diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 3e7e9e9cf091..ffc0150ebac5 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/devcontainers/typescript-node:18-bookworm
+FROM mcr.microsoft.com/devcontainers/typescript-node:22-bookworm
RUN apt-get install -y wget bzip2
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index fe15f35764e6..67a8833d30cf 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -9,13 +9,13 @@
"customizations": {
"vscode": {
"extensions": [
+ "charliermarsh.ruff",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-python.python",
- "ms-python.black-formatter",
"ms-python.vscode-pylance",
- "charliermarsh.ruff"
+ "ms-python.debugpy"
]
}
},
diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 7f6bb48d6c8e..000000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,273 +0,0 @@
-pythonExtensionApi/out/
-
-# The following files were grandfathered out of eslint. They can be removed as time permits.
-
-src/test/analysisEngineTest.ts
-src/test/ciConstants.ts
-src/test/common.ts
-src/test/constants.ts
-src/test/core.ts
-src/test/extension-version.functional.test.ts
-src/test/fixtures.ts
-src/test/index.ts
-src/test/initialize.ts
-src/test/mockClasses.ts
-src/test/performanceTest.ts
-src/test/proc.ts
-src/test/smokeTest.ts
-src/test/standardTest.ts
-src/test/startupTelemetry.unit.test.ts
-src/test/sourceMapSupport.test.ts
-src/test/sourceMapSupport.unit.test.ts
-src/test/testBootstrap.ts
-src/test/testLogger.ts
-src/test/testRunner.ts
-src/test/textUtils.ts
-src/test/unittests.ts
-src/test/vscode-mock.ts
-
-src/test/interpreters/mocks.ts
-src/test/interpreters/virtualEnvs/condaInheritEnvPrompt.unit.test.ts
-src/test/interpreters/pythonPathUpdaterFactory.unit.test.ts
-src/test/interpreters/activation/service.unit.test.ts
-src/test/interpreters/helpers.unit.test.ts
-src/test/interpreters/display.unit.test.ts
-
-src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts
-src/test/terminals/codeExecution/codeExecutionManager.unit.test.ts
-src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts
-
-src/test/activation/activeResource.unit.test.ts
-src/test/activation/extensionSurvey.unit.test.ts
-
-src/test/utils/fs.ts
-
-src/test/api.functional.test.ts
-
-src/test/testing/mocks.ts
-src/test/testing/common/debugLauncher.unit.test.ts
-src/test/testing/common/services/configSettingService.unit.test.ts
-
-src/test/common/exitCIAfterTestReporter.ts
-
-
-src/test/common/terminals/activator/index.unit.test.ts
-src/test/common/terminals/activator/base.unit.test.ts
-src/test/common/terminals/shellDetector.unit.test.ts
-src/test/common/terminals/service.unit.test.ts
-src/test/common/terminals/helper.unit.test.ts
-src/test/common/terminals/activation.unit.test.ts
-src/test/common/terminals/shellDetectors/shellDetectors.unit.test.ts
-src/test/common/terminals/environmentActivationProviders/terminalActivation.testvirtualenvs.ts
-
-src/test/common/socketStream.test.ts
-
-src/test/common/configSettings.test.ts
-
-src/test/common/experiments/telemetry.unit.test.ts
-
-src/test/common/platform/filesystem.unit.test.ts
-src/test/common/platform/errors.unit.test.ts
-src/test/common/platform/utils.ts
-src/test/common/platform/fs-temp.unit.test.ts
-src/test/common/platform/fs-temp.functional.test.ts
-src/test/common/platform/filesystem.functional.test.ts
-src/test/common/platform/filesystem.test.ts
-
-src/test/common/utils/cacheUtils.unit.test.ts
-src/test/common/utils/decorators.unit.test.ts
-src/test/common/utils/version.unit.test.ts
-
-src/test/common/configSettings/configSettings.unit.test.ts
-src/test/common/serviceRegistry.unit.test.ts
-src/test/common/extensions.unit.test.ts
-src/test/common/variables/envVarsService.unit.test.ts
-src/test/common/helpers.test.ts
-src/test/common/application/commands/reloadCommand.unit.test.ts
-
-src/test/common/installer/channelManager.unit.test.ts
-src/test/common/installer/pipInstaller.unit.test.ts
-src/test/common/installer/installer.invalidPath.unit.test.ts
-src/test/common/installer/pipEnvInstaller.unit.test.ts
-src/test/common/installer/productPath.unit.test.ts
-
-src/test/common/socketCallbackHandler.test.ts
-
-src/test/common/process/decoder.test.ts
-src/test/common/process/processFactory.unit.test.ts
-src/test/common/process/pythonToolService.unit.test.ts
-src/test/common/process/proc.observable.test.ts
-src/test/common/process/logger.unit.test.ts
-src/test/common/process/proc.exec.test.ts
-src/test/common/process/pythonProcess.unit.test.ts
-src/test/common/process/proc.unit.test.ts
-
-src/test/common/interpreterPathService.unit.test.ts
-
-
-src/test/pythonFiles/formatting/dummy.ts
-
-src/test/debugger/extension/adapter/adapter.test.ts
-src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts
-src/test/debugger/extension/adapter/factory.unit.test.ts
-src/test/debugger/extension/adapter/activator.unit.test.ts
-src/test/debugger/extension/adapter/logging.unit.test.ts
-src/test/debugger/extension/hooks/childProcessAttachHandler.unit.test.ts
-src/test/debugger/extension/hooks/childProcessAttachService.unit.test.ts
-src/test/debugger/utils.ts
-src/test/debugger/common/protocolparser.test.ts
-src/test/debugger/envVars.test.ts
-
-src/test/telemetry/index.unit.test.ts
-src/test/telemetry/envFileTelemetry.unit.test.ts
-
-src/test/application/diagnostics/checks/macPythonInterpreter.unit.test.ts
-src/test/application/diagnostics/checks/pythonInterpreter.unit.test.ts
-src/test/application/diagnostics/checks/invalidLaunchJsonDebugger.unit.test.ts
-src/test/application/diagnostics/checks/powerShellActivation.unit.test.ts
-src/test/application/diagnostics/checks/invalidPythonPathInDebugger.unit.test.ts
-src/test/application/diagnostics/checks/envPathVariable.unit.test.ts
-src/test/application/diagnostics/applicationDiagnostics.unit.test.ts
-src/test/application/diagnostics/promptHandler.unit.test.ts
-src/test/application/diagnostics/sourceMapSupportService.unit.test.ts
-src/test/application/diagnostics/commands/ignore.unit.test.ts
-
-src/test/performance/load.perf.test.ts
-
-src/client/interpreter/configuration/interpreterSelector/commands/base.ts
-src/client/interpreter/configuration/interpreterSelector/commands/resetInterpreter.ts
-src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts
-src/client/interpreter/configuration/services/globalUpdaterService.ts
-src/client/interpreter/configuration/services/workspaceUpdaterService.ts
-src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts
-src/client/interpreter/helpers.ts
-src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts
-src/client/interpreter/display/index.ts
-
-src/client/extension.ts
-src/client/sourceMapSupport.ts
-src/client/startupTelemetry.ts
-
-src/client/terminals/codeExecution/terminalCodeExecution.ts
-src/client/terminals/codeExecution/codeExecutionManager.ts
-src/client/terminals/codeExecution/djangoContext.ts
-
-src/client/activation/commands.ts
-src/client/activation/progress.ts
-src/client/activation/extensionSurvey.ts
-src/client/activation/common/analysisOptions.ts
-src/client/activation/languageClientMiddleware.ts
-
-src/client/formatters/serviceRegistry.ts
-src/client/formatters/helper.ts
-src/client/formatters/dummyFormatter.ts
-src/client/formatters/baseFormatter.ts
-
-src/client/testing/serviceRegistry.ts
-src/client/testing/main.ts
-src/client/testing/configurationFactory.ts
-src/client/testing/common/constants.ts
-src/client/testing/common/testUtils.ts
-src/client/testing/common/socketServer.ts
-src/client/testing/common/runner.ts
-
-src/client/common/helpers.ts
-src/client/common/net/browser.ts
-src/client/common/net/socket/socketCallbackHandler.ts
-src/client/common/net/socket/socketServer.ts
-src/client/common/net/socket/SocketStream.ts
-src/client/common/editor.ts
-src/client/common/contextKey.ts
-src/client/common/experiments/telemetry.ts
-src/client/common/platform/serviceRegistry.ts
-src/client/common/platform/errors.ts
-src/client/common/platform/fs-temp.ts
-src/client/common/platform/fs-paths.ts
-src/client/common/platform/registry.ts
-src/client/common/platform/pathUtils.ts
-src/client/common/persistentState.ts
-src/client/common/terminal/activator/base.ts
-src/client/common/terminal/activator/powershellFailedHandler.ts
-src/client/common/terminal/activator/index.ts
-src/client/common/terminal/helper.ts
-src/client/common/terminal/syncTerminalService.ts
-src/client/common/terminal/factory.ts
-src/client/common/terminal/commandPrompt.ts
-src/client/common/terminal/service.ts
-src/client/common/terminal/shellDetector.ts
-src/client/common/terminal/shellDetectors/userEnvironmentShellDetector.ts
-src/client/common/terminal/shellDetectors/vscEnvironmentShellDetector.ts
-src/client/common/terminal/shellDetectors/terminalNameShellDetector.ts
-src/client/common/terminal/shellDetectors/settingsShellDetector.ts
-src/client/common/terminal/shellDetectors/baseShellDetector.ts
-src/client/common/utils/decorators.ts
-src/client/common/utils/enum.ts
-src/client/common/utils/platform.ts
-src/client/common/utils/stopWatch.ts
-src/client/common/utils/random.ts
-src/client/common/utils/sysTypes.ts
-src/client/common/utils/misc.ts
-src/client/common/utils/cacheUtils.ts
-src/client/common/utils/workerPool.ts
-src/client/common/extensions.ts
-src/client/common/variables/serviceRegistry.ts
-src/client/common/variables/environment.ts
-src/client/common/variables/types.ts
-src/client/common/variables/systemVariables.ts
-src/client/common/cancellation.ts
-src/client/common/interpreterPathService.ts
-src/client/common/application/applicationShell.ts
-src/client/common/application/languageService.ts
-src/client/common/application/clipboard.ts
-src/client/common/application/workspace.ts
-src/client/common/application/debugSessionTelemetry.ts
-src/client/common/application/documentManager.ts
-src/client/common/application/debugService.ts
-src/client/common/application/commands/reloadCommand.ts
-src/client/common/application/terminalManager.ts
-src/client/common/application/applicationEnvironment.ts
-src/client/common/errors/errorUtils.ts
-src/client/common/installer/serviceRegistry.ts
-src/client/common/installer/channelManager.ts
-src/client/common/installer/moduleInstaller.ts
-src/client/common/installer/types.ts
-src/client/common/installer/pipEnvInstaller.ts
-src/client/common/installer/productService.ts
-src/client/common/installer/pipInstaller.ts
-src/client/common/installer/productPath.ts
-src/client/common/process/currentProcess.ts
-src/client/common/process/processFactory.ts
-src/client/common/process/serviceRegistry.ts
-src/client/common/process/pythonToolService.ts
-src/client/common/process/internal/python.ts
-src/client/common/process/internal/scripts/testing_tools.ts
-src/client/common/process/types.ts
-src/client/common/process/logger.ts
-src/client/common/process/pythonProcess.ts
-src/client/common/process/pythonEnvironment.ts
-src/client/common/process/decoder.ts
-
-
-src/client/debugger/extension/adapter/remoteLaunchers.ts
-src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts
-src/client/debugger/extension/adapter/factory.ts
-src/client/debugger/extension/adapter/activator.ts
-src/client/debugger/extension/adapter/logging.ts
-src/client/debugger/extension/hooks/eventHandlerDispatcher.ts
-src/client/debugger/extension/hooks/childProcessAttachService.ts
-src/client/debugger/extension/attachQuickPick/wmicProcessParser.ts
-src/client/debugger/extension/attachQuickPick/factory.ts
-src/client/debugger/extension/attachQuickPick/psProcessParser.ts
-src/client/debugger/extension/attachQuickPick/picker.ts
-
-src/client/application/serviceRegistry.ts
-src/client/application/diagnostics/surceMapSupportService.ts
-src/client/application/diagnostics/base.ts
-src/client/application/diagnostics/applicationDiagnostics.ts
-src/client/application/diagnostics/filter.ts
-src/client/application/diagnostics/promptHandler.ts
-src/client/application/diagnostics/commands/base.ts
-src/client/application/diagnostics/commands/ignore.ts
-src/client/application/diagnostics/commands/factory.ts
-src/client/application/diagnostics/commands/execVSCCommand.ts
-src/client/application/diagnostics/commands/launchBrowser.ts
diff --git a/.eslintplugin/no-bad-gdpr-comment.js b/.eslintplugin/no-bad-gdpr-comment.js
new file mode 100644
index 000000000000..786259683ff6
--- /dev/null
+++ b/.eslintplugin/no-bad-gdpr-comment.js
@@ -0,0 +1,51 @@
+"use strict";
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+Object.defineProperty(exports, "__esModule", { value: true });
+var noBadGDPRComment = {
+ create: function (context) {
+ var _a;
+ return _a = {},
+ _a['Program'] = function (node) {
+ for (var _i = 0, _a = node.comments; _i < _a.length; _i++) {
+ var comment = _a[_i];
+ if (comment.type !== 'Block' || !comment.loc) {
+ continue;
+ }
+ if (!comment.value.includes('__GDPR__')) {
+ continue;
+ }
+ var dataStart = comment.value.indexOf('\n');
+ var data = comment.value.substring(dataStart);
+ var gdprData = void 0;
+ try {
+ var jsonRaw = "{ ".concat(data, " }");
+ gdprData = JSON.parse(jsonRaw);
+ }
+ catch (e) {
+ context.report({
+ loc: { start: comment.loc.start, end: comment.loc.end },
+ message: 'GDPR comment is not valid JSON',
+ });
+ }
+ if (gdprData) {
+ var len = Object.keys(gdprData).length;
+ if (len !== 1) {
+ context.report({
+ loc: { start: comment.loc.start, end: comment.loc.end },
+ message: "GDPR comment must contain exactly one key, not ".concat(Object.keys(gdprData).join(', ')),
+ });
+ }
+ }
+ }
+ },
+ _a;
+ },
+};
+module.exports = {
+ rules: {
+ 'no-bad-gdpr-comment': noBadGDPRComment, // Ensure correct structure
+ },
+};
diff --git a/.eslintplugin/no-bad-gdpr-comment.ts b/.eslintplugin/no-bad-gdpr-comment.ts
new file mode 100644
index 000000000000..1eba899a7de3
--- /dev/null
+++ b/.eslintplugin/no-bad-gdpr-comment.ts
@@ -0,0 +1,55 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import * as eslint from 'eslint';
+const noBadGDPRComment: eslint.Rule.RuleModule = {
+ create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
+ return {
+ ['Program'](node) {
+ for (const comment of (node as eslint.AST.Program).comments) {
+ if (comment.type !== 'Block' || !comment.loc) {
+ continue;
+ }
+ if (!comment.value.includes('__GDPR__')) {
+ continue;
+ }
+
+ const dataStart = comment.value.indexOf('\n');
+ const data = comment.value.substring(dataStart);
+
+ let gdprData: { [key: string]: object } | undefined;
+
+ try {
+ const jsonRaw = `{ ${data} }`;
+ gdprData = JSON.parse(jsonRaw);
+ } catch (e) {
+ context.report({
+ loc: { start: comment.loc.start, end: comment.loc.end },
+ message: 'GDPR comment is not valid JSON',
+ });
+ }
+
+ if (gdprData) {
+ const len = Object.keys(gdprData).length;
+ if (len !== 1) {
+ context.report({
+ loc: { start: comment.loc.start, end: comment.loc.end },
+ message: `GDPR comment must contain exactly one key, not ${Object.keys(gdprData).join(
+ ', ',
+ )}`,
+ });
+ }
+ }
+ }
+ },
+ };
+ },
+};
+
+module.exports = {
+ rules: {
+ 'no-bad-gdpr-comment': noBadGDPRComment, // Ensure correct structure
+ },
+};
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index 62e2aa6c52ba..000000000000
--- a/.eslintrc
+++ /dev/null
@@ -1,101 +0,0 @@
-{
- "env": {
- "node": true,
- "es6": true,
- "mocha": true
- },
- "parser": "@typescript-eslint/parser",
- "plugins": ["@typescript-eslint"],
- "extends": [
- "airbnb",
- "plugin:@typescript-eslint/recommended",
- "plugin:import/errors",
- "plugin:import/warnings",
- "plugin:import/typescript",
- "prettier"
- ],
- "rules": {
- // Overriding ESLint rules with Typescript-specific ones
- "@typescript-eslint/ban-ts-comment": [
- "error",
- {
- "ts-ignore": "allow-with-description"
- }
- ],
- "@typescript-eslint/explicit-module-boundary-types": "error",
- "no-bitwise": "off",
- "no-dupe-class-members": "off",
- "@typescript-eslint/no-dupe-class-members": "error",
- "no-empty-function": "off",
- "@typescript-eslint/no-empty-function": ["error"],
- "@typescript-eslint/no-empty-interface": "off",
- "@typescript-eslint/no-explicit-any": "error",
- "@typescript-eslint/no-non-null-assertion": "off",
- "no-unused-vars": "off",
- "@typescript-eslint/no-unused-vars": [
- "error",
- {
- "args": "after-used",
- "argsIgnorePattern": "^_"
- }
- ],
- "no-use-before-define": "off",
- "@typescript-eslint/no-use-before-define": [
- "error",
- {
- "functions": false
- }
- ],
- "no-useless-constructor": "off",
- "@typescript-eslint/no-useless-constructor": "error",
- "@typescript-eslint/no-var-requires": "off",
-
- // Other rules
- "class-methods-use-this": ["error", {"exceptMethods": ["dispose"]}],
- "func-names": "off",
- "import/extensions": "off",
- "import/namespace": "off",
- "import/no-extraneous-dependencies": "off",
- "import/no-unresolved": [
- "error",
- {
- "ignore": ["monaco-editor", "vscode"]
- }
- ],
- "import/prefer-default-export": "off",
- "linebreak-style": "off",
- "no-await-in-loop": "off",
- "no-console": "off",
- "no-control-regex": "off",
- "no-extend-native": "off",
- "no-multi-str": "off",
- "no-param-reassign": "off",
- "no-prototype-builtins": "off",
- "no-restricted-syntax": [
- "error",
- {
- "selector": "ForInStatement",
- "message": "for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array."
- },
- {
- "selector": "LabeledStatement",
- "message": "Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand."
- },
- {
- "selector": "WithStatement",
- "message": "`with` is disallowed in strict mode because it makes code impossible to predict and optimize."
- }
- ],
- "no-template-curly-in-string": "off",
- "no-underscore-dangle": "off",
- "no-useless-escape": "off",
- "no-void": [
- "error",
- {
- "allowAsStatement": true
- }
- ],
- "operator-assignment": "off",
- "strict": "off"
- }
-}
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 000000000000..e2c2a50781b9
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,15 @@
+# Prettier
+2b6a8f2d439fe9d5e66665ea46d8b690ac9b2c39
+649156a09ccdc51c0d20f7cd44540f1918f9347b
+4f774d94bf4fbf87bb417b2b2b8e79e334eb3536
+61b179b2092050709e3c373a6738abad8ce581c4
+c33617b0b98daeb4d72040b48c5850b476d6256c
+db8e1e2460e9754ec0672d958789382b6d15c5aa
+08bc9ad3bee5b19f02fa756fbc53ab32f1b39920
+# Black
+a58eeffd1b64498e2afe5f11597888dfd1c8699c
+5cd8f539f4d2086b718c8f11f823c0ac12fc2c49
+9ec9e9eaebb25adc6d942ac19d4d6c128abb987f
+c4af91e090057d20d7a633b3afa45eaa13ece76f
+# Ruff
+e931bed3efbede7b05113316506958ecd7506777
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index eaacc33b8d8d..c966f6bde856 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -9,9 +9,9 @@ contact_links:
- name: 'Jupyter'
url: https://github.com/microsoft/vscode-jupyter/issues
about: 'For issues relating to the Jupyter extension (including the interactive window)'
- - name: 'Debugpy'
- url: https://github.com/microsoft/debugpy/issues
- about: 'For issues relating to the debugpy debugger'
+ - name: 'Python Debugger'
+ url: https://github.com/microsoft/vscode-python-debugger/issues
+ about: 'For issues relating to the Python debugger'
- name: Help/Support
url: https://github.com/microsoft/vscode-python/discussions/categories/q-a
about: 'Having trouble with the extension? Need help getting something to work?'
diff --git a/.github/actions/build-vsix/action.yml b/.github/actions/build-vsix/action.yml
index b632eb0a25cc..912ff2c34a74 100644
--- a/.github/actions/build-vsix/action.yml
+++ b/.github/actions/build-vsix/action.yml
@@ -11,26 +11,34 @@ inputs:
artifact_name:
description: 'Name to give the artifact containing the VSIX'
required: true
+ cargo_target:
+ description: 'Cargo build target for the native build'
+ required: true
+ vsix_target:
+ description: 'vsix build target for the native build'
+ required: true
runs:
using: 'composite'
steps:
- name: Install Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: ${{ inputs.node_version }}
cache: 'npm'
+ - name: Rust Tool Chain setup
+ uses: dtolnay/rust-toolchain@stable
+
# Jedi LS depends on dataclasses which is not in the stdlib in Python 3.7.
- - name: Use Python 3.8 for JediLSP
- uses: actions/setup-python@v4
+ - name: Use Python 3.10 for JediLSP
+ uses: actions/setup-python@v6
with:
- python-version: 3.8
+ python-version: '3.10'
cache: 'pip'
cache-dependency-path: |
requirements.txt
- build/build-install-requirements.txt
- pythonFiles/jedilsp_requirements/requirements.txt
+ python_files/jedilsp_requirements/requirements.txt
- name: Upgrade Pip
run: python -m pip install -U pip
@@ -38,53 +46,54 @@ runs:
# For faster/better builds of sdists.
- name: Install build pre-requisite
- run: python -m pip install wheel
+ run: python -m pip install wheel nox
shell: bash
- - name: Install Python dependencies
- uses: brettcannon/pip-secure-install@v1
- with:
- options: '-t ./pythonFiles/lib/python --implementation py'
+ - name: Install Python Extension dependencies (jedi, etc.)
+ run: nox --session install_python_libs
+ shell: bash
- - name: Install debugpy and get-pip
- run: |
- python -m pip --disable-pip-version-check install packaging
- python ./pythonFiles/install_debugpy.py
- python ./pythonFiles/download_get_pip.py
+ - name: Add Rustup target
+ run: rustup target add "${CARGO_TARGET}"
shell: bash
+ env:
+ CARGO_TARGET: ${{ inputs.cargo_target }}
- - name: Install Jedi LSP
- uses: brettcannon/pip-secure-install@v1
- with:
- requirements-file: './pythonFiles/jedilsp_requirements/requirements.txt'
- options: '-t ./pythonFiles/lib/jedilsp --implementation py --platform any --abi none'
+ - name: Build Native Binaries
+ run: nox --session native_build
+ shell: bash
+ env:
+ CARGO_TARGET: ${{ inputs.cargo_target }}
- name: Run npm ci
run: npm ci --prefer-offline
shell: bash
- # Use the GITHUB_RUN_ID environment variable to update the build number.
- # GITHUB_RUN_ID is a unique number for each run within a repository.
- # This number does not change if you re-run the workflow run.
- - name: Update extension build number
- run: npm run updateBuildNumber -- --buildNumber $GITHUB_RUN_ID
- shell: bash
-
- name: Update optional extension dependencies
run: npm run addExtensionPackDependencies
shell: bash
+ - name: Build Webpack
+ run: |
+ npx gulp clean
+ npx gulp prePublishBundle
+ shell: bash
+
- name: Build VSIX
- run: npm run package
+ run: npx vsce package --target "${VSIX_TARGET}" --out ms-python-insiders.vsix --pre-release
shell: bash
+ env:
+ VSIX_TARGET: ${{ inputs.vsix_target }}
- name: Rename VSIX
# Move to a temp name in case the specified name happens to match the default name.
- run: mv ms-python-insiders.vsix ms-python-temp.vsix && mv ms-python-temp.vsix ${{ inputs.vsix_name }}
+ run: mv ms-python-insiders.vsix ms-python-temp.vsix && mv ms-python-temp.vsix "${VSIX_NAME}"
shell: bash
+ env:
+ VSIX_NAME: ${{ inputs.vsix_name }}
- name: Upload VSIX
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v7
with:
name: ${{ inputs.artifact_name }}
path: ${{ inputs.vsix_name }}
diff --git a/.github/actions/lint/action.yml b/.github/actions/lint/action.yml
index 47924c108151..0bd5a2d8e1e2 100644
--- a/.github/actions/lint/action.yml
+++ b/.github/actions/lint/action.yml
@@ -10,7 +10,7 @@ runs:
using: 'composite'
steps:
- name: Install Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: ${{ inputs.node_version }}
cache: 'npm'
@@ -36,21 +36,15 @@ runs:
shell: bash
- name: Install Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: '3.x'
cache: 'pip'
- - name: Check Python format
- run: |
- python -m pip install -U black
- python -m black . --check
- working-directory: pythonFiles
- shell: bash
-
- name: Run Ruff
run: |
- python -m pip install -U ruff
+ python -m pip install -U "ruff"
python -m ruff check .
- working-directory: pythonFiles
+ python -m ruff format --check
+ working-directory: python_files
shell: bash
diff --git a/.github/actions/smoke-tests/action.yml b/.github/actions/smoke-tests/action.yml
index b2d002050433..0531ef5d42a3 100644
--- a/.github/actions/smoke-tests/action.yml
+++ b/.github/actions/smoke-tests/action.yml
@@ -13,13 +13,13 @@ runs:
using: 'composite'
steps:
- name: Install Node
- uses: actions/setup-node@v2
+ uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node_version }}
cache: 'npm'
- name: Install Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v5
with:
python-version: '3.x'
cache: 'pip'
@@ -32,19 +32,18 @@ runs:
shell: bash
- name: Install Python requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- options: '-t ./pythonFiles/lib/python --implementation py'
+ options: '-t ./python_files/lib/python --implementation py'
- name: pip install system test requirements
run: |
python -m pip install --upgrade -r build/test-requirements.txt
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --implementation py --no-deps --upgrade --pre debugpy
shell: bash
# Bits from the VSIX are reused by smokeTest.ts to speed things up.
- name: Download VSIX
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v4
with:
name: ${{ inputs.artifact_name }}
@@ -62,6 +61,6 @@ runs:
env:
DISPLAY: 10
INSTALL_JUPYTER_EXTENSION: true
- uses: GabrielBB/xvfb-action@v1.5
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: node --no-force-async-hooks-checks ./out/test/smokeTest.js
diff --git a/.github/commands.json b/.github/commands.json
new file mode 100644
index 000000000000..171f33f380c3
--- /dev/null
+++ b/.github/commands.json
@@ -0,0 +1,166 @@
+[
+ {
+ "type": "label",
+ "name": "*question",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "We closed this issue because it is a question about using the Python extension for VS Code rather than an issue or feature request. We recommend browsing resources such as our [Python documentation](https://code.visualstudio.com/docs/languages/python) and our [Discussions page](https://github.com/microsoft/vscode-python/discussions). You may also find help on [StackOverflow](https://stackoverflow.com/questions/tagged/vscode-python), where the community has already answered thousands of similar questions. \n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "*dev-question",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "We have a great extension developer community over on [GitHub discussions](https://github.com/microsoft/vscode-discussions/discussions) and [Slack](https://vscode-dev-community.slack.com/) where extension authors help each other. This is a great place for you to ask questions and find support.\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "*extension-candidate",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "We try to keep the Python extension lean and we think the functionality you're asking for is great for a VS Code extension. You might be able to find one that suits you in the [VS Code Marketplace](https://aka.ms/vscodemarketplace) already. If not, in a few simple steps you can get started [writing your own extension](https://aka.ms/vscodewritingextensions) or leverage our [tool extension template](https://github.com/microsoft/vscode-python-tools-extension-template) to get started. In addition, check out the [vscode-python-environments](https://github.com/microsoft/vscode-python-environments) as this may be the right spot for your request. \n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "*not-reproducible",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "We closed this issue because we are unable to reproduce the problem with the steps you describe. Chances are we've already fixed your problem in a recent version of the Python extension, so we recommend updating to the latest version and trying again. If you continue to experience this issue, please ask us to reopen the issue and provide us with more detail.\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "*out-of-scope",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "We closed this issue because we [don't plan to address it](https://github.com/microsoft/vscode-python/wiki/Issue-Management#criteria-for-closing-out-of-scope-feature-requests) in the foreseeable future. If you disagree and feel that this issue is crucial: we are happy to listen and to reconsider.\n\nIf you wonder what we are up to, please see our [roadmap](https://aka.ms/pythonvscoderoadmap) and [issue reporting guidelines]( https://github.com/microsoft/vscode-python/wiki/Issue-Management).\n\nThanks for your understanding, and happy coding!"
+ },
+ {
+ "type": "label",
+ "name": "wont-fix",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "We closed this issue because we [don't plan to address it](https://github.com/microsoft/vscode/wiki/Issue-Grooming#wont-fix-bugs).\n\nThanks for your understanding, and happy coding!"
+ },
+ {
+ "type": "label",
+ "name": "*caused-by-extension",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "This issue is caused by an extension, please file it with the repository (or contact) the extension has linked in its overview in VS Code or the [marketplace](https://aka.ms/vscodemarketplace) for VS Code. See also our [issue reporting guidelines](https://aka.ms/vscodeissuereporting). If you don't know which extension is causing the problem, you can run `Help: Start extension bisect` from the command palette (F1) to help identify the problem extension.\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "*as-designed",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "The described behavior is how it is expected to work. If you disagree, please explain what is expected and what is not in more detail. See also our [issue reporting guidelines](https://aka.ms/vscodeissuereporting).\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "L10N",
+ "assign": [
+ "csigs",
+ "TylerLeonhardt"
+ ]
+ },
+ {
+ "type": "label",
+ "name": "*duplicate",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "Thanks for creating this issue! We figured it's covering the same as another one we already have. Thus, we closed this one as a duplicate. You can search for [similar existing issues](${duplicateQuery}). See also our [issue reporting guidelines](https://aka.ms/vscodeissuereporting).\n\nHappy Coding!"
+ },
+ {
+ "type": "comment",
+ "name": "verified",
+ "allowUsers": [
+ "@author"
+ ],
+ "action": "updateLabels",
+ "addLabel": "verified",
+ "removeLabel": "author-verification-requested",
+ "requireLabel": "author-verification-requested",
+ "disallowLabel": "unreleased"
+ },
+ {
+ "type": "comment",
+ "name": "confirm",
+ "allowUsers": [
+ "cleidigh",
+ "usernamehw",
+ "gjsjohnmurray",
+ "IllusionMH"
+ ],
+ "action": "updateLabels",
+ "addLabel": "confirmed",
+ "removeLabel": "confirmation-pending"
+ },
+ {
+ "type": "label",
+ "name": "*off-topic",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "Thanks for creating this issue. We think this issue is unactionable or unrelated to the goals of this project. Please follow our [issue reporting guidelines](https://aka.ms/vscodeissuereporting).\n\nHappy Coding!"
+ },
+ {
+ "type": "comment",
+ "name": "gifPlease",
+ "allowUsers": [
+ "cleidigh",
+ "usernamehw",
+ "gjsjohnmurray",
+ "IllusionMH"
+ ],
+ "action": "comment",
+ "addLabel": "info-needed",
+ "comment": "Thanks for reporting this issue! Unfortunately, it's hard for us to understand what issue you're seeing. Please help us out by providing a screen recording showing exactly what isn't working as expected. While we can work with most standard formats, `.gif` files are preferred as they are displayed inline on GitHub. You may find https://gifcap.dev helpful as a browser-based gif recording tool.\n\nIf the issue depends on keyboard input, you can help us by enabling screencast mode for the recording (`Developer: Toggle Screencast Mode` in the command palette). Lastly, please attach this file via the GitHub web interface as emailed responses will strip files out from the issue.\n\nHappy coding!"
+ },
+ {
+ "type": "label",
+ "name": "*workspace-trust-docs",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "This issue appears to be the result of the new workspace trust feature shipped in June 2021. This security-focused feature has major impact on the functionality of VS Code. Due to the volume of issues, we ask that you take some time to review our [comprehensive documentation](https://aka.ms/vscode-workspace-trust) on the feature. If your issue is still not resolved, please let us know."
+ },
+ {
+ "type": "label",
+ "name": "~verification-steps-needed",
+ "action": "updateLabels",
+ "addLabel": "verification-steps-needed",
+ "removeLabel": "~verification-steps-needed",
+ "comment": "Friendly ping! Looks like this issue requires some further steps to be verified. Please provide us with the steps necessary to verify this issue."
+ },
+ {
+ "type": "label",
+ "name": "~info-needed",
+ "action": "updateLabels",
+ "addLabel": "info-needed",
+ "removeLabel": "~info-needed",
+ "comment": "Thanks for creating this issue! We figured it's missing some basic information or in some other way doesn't follow our [issue reporting guidelines](https://aka.ms/pvsc-bug). Please take the time to review these and update the issue or even open a new one with the Report Issue command in VS Code (**Help > Report Issue**) to have all the right information collected for you.\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "~version-info-needed",
+ "action": "updateLabels",
+ "addLabel": "info-needed",
+ "removeLabel": "~version-info-needed",
+ "comment": "Thanks for creating this issue! We figured it's missing some basic information, such as a version number, or in some other way doesn't follow our issue reporting guidelines. Please take the time to review these and update the issue or even open a new one with the Report Issue command in VS Code (**Help > Report Issue**) to have all the right information collected for you.\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "~confirmation-needed",
+ "action": "updateLabels",
+ "addLabel": "info-needed",
+ "removeLabel": "~confirmation-needed",
+ "comment": "Please diagnose the root cause of the issue by running the command `F1 > Help: Troubleshoot Issue` and following the instructions. Once you have done that, please update the issue with the results.\n\nHappy Coding!"
+ },
+ {
+ "type": "label",
+ "name": "~spam",
+ "removeLabel": "~spam",
+ "addLabel": "spam",
+ "action": "close",
+ "reason": "not_planned",
+ "comment": "Thank you for your submission. This issue has been closed as it doesn't meet our community guidelines or appears to be spam.\n\n**If you believe this was closed in error:**\n- Please review our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/)\n- Ensure your issue contains a clear description of the problem or feature request\n- Feel free to open a new issue with appropriate detail if this was a legitimate concern\n\n**For legitimate issues, please include:**\n- Clear description of the problem\n- Steps to reproduce (for bugs)\n- Expected vs actual behavior\n- VS Code version and environment details\n\nThank you for helping us maintain a welcoming and productive community."
+ }
+]
diff --git a/.github/instructions/learning.instructions.md b/.github/instructions/learning.instructions.md
new file mode 100644
index 000000000000..28b085f486ce
--- /dev/null
+++ b/.github/instructions/learning.instructions.md
@@ -0,0 +1,34 @@
+---
+applyTo: '**'
+description: This document describes how to deal with learnings that you make. (meta instruction)
+---
+
+This document describes how to deal with learnings that you make.
+It is a meta-instruction file.
+
+Structure of learnings:
+
+- Each instruction file has a "Learnings" section.
+- Each learning has a counter that indicates how often that learning was useful (initially 1).
+- Each learning has a 1 sentence description of the learning that is clear and concise.
+
+Example:
+
+```markdown
+## Learnings
+
+- Prefer `const` over `let` whenever possible (1)
+- Avoid `any` type (3)
+```
+
+When the user tells you "learn!", you should:
+
+- extract a learning from the recent conversation
+ _ identify the problem that you created
+ _ identify why it was a problem
+ _ identify how you were told to fix it/how the user fixed it
+ _ generate only one learning (1 sentence) that helps to summarize the insight gained
+- then, add the reflected learning to the "Learnings" section of the most appropriate instruction file
+
+Important: Whenever a learning was really useful, increase the counter!!
+When a learning was not useful and just caused more problems, decrease the counter.
diff --git a/.github/instructions/pytest-json-test-builder.instructions.md b/.github/instructions/pytest-json-test-builder.instructions.md
new file mode 100644
index 000000000000..436bce0c9cd8
--- /dev/null
+++ b/.github/instructions/pytest-json-test-builder.instructions.md
@@ -0,0 +1,126 @@
+---
+applyTo: 'python_files/tests/pytestadapter/test_discovery.py'
+description: 'A guide for adding new tests for pytest discovery and JSON formatting in the test_pytest_collect suite.'
+---
+
+# How to Add New Pytest Discovery Tests
+
+This guide explains how to add new tests for pytest discovery and JSON formatting in the `test_pytest_collect` suite. Follow these steps to ensure your tests are consistent and correct.
+
+---
+
+## 1. Add Your Test File
+
+- Place your new test file/files in the appropriate subfolder under:
+ ```
+ python_files/tests/pytestadapter/.data/
+ ```
+- Organize folders and files to match the structure you want to test. For example, to test nested folders, create the corresponding directory structure.
+- In your test file, mark each test function with a comment:
+ ```python
+ def test_function(): # test_marker--test_function
+ ...
+ ```
+
+**Root Node Matching:**
+
+- The root node in your expected output must match the folder or file you pass to pytest discovery. For example, if you run discovery on a subfolder, the root `"name"`, `"path"`, and `"id_"` in your expected output should be that subfolder, not the parent `.data` folder.
+- Only use `.data` as the root if you are running discovery on the entire `.data` folder.
+
+**Example:**
+If you run:
+
+```python
+helpers.runner([os.fspath(TEST_DATA_PATH / "myfolder"), "--collect-only"])
+```
+
+then your expected output root should be:
+
+```python
+{
+ "name": "myfolder",
+ "path": os.fspath(TEST_DATA_PATH / "myfolder"),
+ "type_": "folder",
+ ...
+}
+```
+
+---
+
+## 2. Update `expected_discovery_test_output.py`
+
+- Open `expected_discovery_test_output.py` in the same test suite.
+- Add a new expected output dictionary for your test file, following the format of existing entries.
+- Use the helper functions and path conventions:
+ - Use `os.fspath()` for all paths.
+ - Use `find_test_line_number("function_name", file_path)` for the `lineno` field.
+ - Use `get_absolute_test_id("relative_path::function_name", file_path)` for `id_` and `runID`.
+ - Always use current path concatenation (e.g., `TEST_DATA_PATH / "your_folder" / "your_file.py"`).
+ - Create new constants as needed to keep the code clean and maintainable.
+
+**Important:**
+
+- Do **not** read the entire `expected_discovery_test_output.py` file if you only need to add or reference a single constant. This file is very large; prefer searching for the relevant section or appending to the end.
+
+**Example:**
+If you run discovery on a subfolder:
+
+```python
+helpers.runner([os.fspath(TEST_DATA_PATH / "myfolder"), "--collect-only"])
+```
+
+then your expected output root should be:
+
+```python
+myfolder_path = TEST_DATA_PATH / "myfolder"
+my_expected_output = {
+ "name": "myfolder",
+ "path": os.fspath(myfolder_path),
+ "type_": "folder",
+ ...
+}
+```
+
+- Add a comment above your dictionary describing the structure, as in the existing examples.
+
+---
+
+## 3. Add Your Test to `test_discovery.py`
+
+- In `test_discovery.py`, add your new test as a parameterized case to the main `test_pytest_collect` function. Do **not** create a standalone test function for new discovery cases.
+- Reference your new expected output constant from `expected_discovery_test_output.py`.
+
+**Example:**
+
+```python
+@pytest.mark.parametrize(
+ ("file", "expected_const"),
+ [
+ ("myfolder", my_expected_output),
+ # ... other cases ...
+ ],
+)
+def test_pytest_collect(file, expected_const):
+ ...
+```
+
+---
+
+## 4. Run and Verify
+
+- Run the test suite to ensure your new test is discovered and passes.
+- If the test fails, check your expected output dictionary for path or structure mismatches.
+
+---
+
+## 5. Tips
+
+- Always use the helper functions for line numbers and IDs.
+- Match the folder/file structure in `.data` to the expected JSON structure.
+- Use comments to document the expected output structure for clarity.
+- Ensure all `"path"` and `"id_"` fields in your expected output match exactly what pytest returns, including absolute paths and root node structure.
+
+---
+
+**Reference:**
+See `expected_discovery_test_output.py` for more examples and formatting. Use search or jump to the end of the file to avoid reading the entire file when possible.
diff --git a/.github/instructions/python-quality-checks.instructions.md b/.github/instructions/python-quality-checks.instructions.md
new file mode 100644
index 000000000000..48f37529dfbc
--- /dev/null
+++ b/.github/instructions/python-quality-checks.instructions.md
@@ -0,0 +1,97 @@
+---
+applyTo: 'python_files/**'
+description: Guide for running and fixing Python quality checks (Ruff and Pyright) that run in CI
+---
+
+# Python Quality Checks β Ruff and Pyright
+
+Run the same Python quality checks that run in CI. All checks target `python_files/` and use config from `python_files/pyproject.toml`.
+
+## Commands
+
+```bash
+npm run check-python # Run both Ruff and Pyright
+npm run check-python:ruff # Linting and formatting only
+npm run check-python:pyright # Type checking only
+```
+
+## Fixing Ruff Errors
+
+**Auto-fix most issues:**
+
+```bash
+cd python_files
+python -m ruff check . --fix
+python -m ruff format
+npm run check-python:ruff # Verify
+```
+
+**Manual fixes:**
+
+- Ruff shows file, line number, rule code (e.g., `F841`), and description
+- Open the file, read the error, fix the code
+- Common: line length (100 char max), import sorting, unused variables
+
+## Fixing Pyright Errors
+
+**Common patterns and fixes:**
+
+- **Undefined variable/import**: Add the missing import
+- **Type mismatch**: Correct the type or add type annotations
+- **Missing return type**: Add `-> ReturnType` to function signatures
+ ```python
+ def my_function() -> str: # Add return type
+ return "result"
+ ```
+
+**Verify:**
+
+```bash
+npm run check-python:pyright
+```
+
+## Configuration
+
+- **Ruff**: Line length 100, Python 3.9+, 40+ rule families (flake8, isort, pyupgrade, etc.)
+- **Pyright**: Version 1.1.308 (or whatever is found in the environment), ignores `lib/` and 15+ legacy files
+- Config: `python_files/pyproject.toml` sections `[tool.ruff]` and `[tool.pyright]`
+
+## Troubleshooting
+
+**"Module not found" in Pyright**: Install dependencies
+
+```bash
+python -m pip install --upgrade -r build/test-requirements.txt
+nox --session install_python_libs
+```
+
+**Import order errors**: Auto-fix with `ruff check . --fix`
+
+**Type errors in ignored files**: Legacy files in `pyproject.toml` ignore listβfix if working on them
+
+## When Writing Tests
+
+**Always format your test files before committing:**
+
+```bash
+cd python_files
+ruff format tests/ # Format all test files
+# or format specific files:
+ruff format tests/unittestadapter/test_utils.py
+```
+
+**Best practice workflow:**
+
+1. Write your test code
+2. Run `ruff format` on the test files
+3. Run the tests to verify they pass
+4. Run `npm run check-python` to catch any remaining issues
+
+This ensures your tests pass both functional checks and quality checks in CI.
+
+## Learnings
+
+- Always run `npm run check-python` before pushing to catch CI failures early (1)
+- Use `ruff check . --fix` to auto-fix most linting issues before manual review (1)
+- Pyright version must match CI (1.1.308) to avoid inconsistent results between local and CI runs (1)
+- Always run `ruff format` on test files after writing them to avoid formatting CI failures (1)
diff --git a/.github/instructions/testing-workflow.instructions.md b/.github/instructions/testing-workflow.instructions.md
new file mode 100644
index 000000000000..844946404328
--- /dev/null
+++ b/.github/instructions/testing-workflow.instructions.md
@@ -0,0 +1,581 @@
+---
+applyTo: '**/test/**'
+---
+
+# AI Testing Workflow Guide: Write, Run, and Fix Tests
+
+This guide provides comprehensive instructions for AI agents on the complete testing workflow: writing tests, running them, diagnosing failures, and fixing issues. Use this guide whenever working with test files or when users request testing tasks.
+
+## Complete Testing Workflow
+
+This guide covers the full testing lifecycle:
+
+1. **π Writing Tests** - Create comprehensive test suites
+2. **βΆοΈ Running Tests** - Execute tests using VS Code tools
+3. **π Diagnosing Issues** - Analyze failures and errors
+4. **π οΈ Fixing Problems** - Resolve compilation and runtime issues
+5. **β
Validation** - Ensure coverage and resilience
+
+### When to Use This Guide
+
+**User Requests Testing:**
+
+- "Write tests for this function"
+- "Run the tests"
+- "Fix the failing tests"
+- "Test this code"
+- "Add test coverage"
+
+**File Context Triggers:**
+
+- Working in `**/test/**` directories
+- Files ending in `.test.ts` or `.unit.test.ts`
+- Test failures or compilation errors
+- Coverage reports or test output analysis
+
+## Test Types
+
+When implementing tests as an AI agent, choose between two main types:
+
+### Unit Tests (`*.unit.test.ts`)
+
+- **Fast isolated testing** - Mock all external dependencies
+- **Use for**: Pure functions, business logic, data transformations
+- **Execute with**: `runTests` tool with specific file patterns
+- **Mock everything** - VS Code APIs automatically mocked via `/src/test/unittests.ts`
+
+### Extension Tests (`*.test.ts`)
+
+- **Full VS Code integration** - Real environment with actual APIs
+- **Use for**: Command registration, UI interactions, extension lifecycle
+- **Execute with**: VS Code launch configurations or `runTests` tool
+- **Slower but comprehensive** - Tests complete user workflows
+
+## π€ Agent Tool Usage for Test Execution
+
+### Primary Tool: `runTests`
+
+Use the `runTests` tool to execute tests programmatically rather than terminal commands for better integration and result parsing:
+
+```typescript
+// Run specific test files
+await runTests({
+ files: ['/absolute/path/to/test.unit.test.ts'],
+ mode: 'run',
+});
+
+// Run tests with coverage
+await runTests({
+ files: ['/absolute/path/to/test.unit.test.ts'],
+ mode: 'coverage',
+ coverageFiles: ['/absolute/path/to/source.ts'],
+});
+
+// Run specific test names
+await runTests({
+ files: ['/absolute/path/to/test.unit.test.ts'],
+ testNames: ['should handle edge case', 'should validate input'],
+});
+```
+
+### Compilation Requirements
+
+Before running tests, ensure compilation. Always start compilation with `npm run watch-tests` before test execution to ensure TypeScript files are built. Recompile after making import/export changes before running tests, as stubs won't work if they're applied to old compiled JavaScript that doesn't have the updated imports:
+
+```typescript
+// Start watch mode for auto-compilation
+await run_in_terminal({
+ command: 'npm run watch-tests',
+ isBackground: true,
+ explanation: 'Start test compilation in watch mode',
+});
+
+// Or compile manually
+await run_in_terminal({
+ command: 'npm run compile-tests',
+ isBackground: false,
+ explanation: 'Compile TypeScript test files',
+});
+```
+
+### Alternative: Terminal Execution
+
+For targeted test runs when `runTests` tool is unavailable. Note: When a targeted test run yields 0 tests, first verify the compiled JS exists under `out/test` (rootDir is `src`); absence almost always means the test file sits outside `src` or compilation hasn't run yet:
+
+```typescript
+// Run specific test suite
+await run_in_terminal({
+ command: 'npm run unittest -- --grep "Suite Name"',
+ isBackground: false,
+ explanation: 'Run targeted unit tests',
+});
+```
+
+## π Diagnosing Test Failures
+
+### Common Failure Patterns
+
+**Compilation Errors:**
+
+```typescript
+// Missing imports
+if (error.includes('Cannot find module')) {
+ await addMissingImports(testFile);
+}
+
+// Type mismatches
+if (error.includes("Type '" && error.includes("' is not assignable"))) {
+ await fixTypeIssues(testFile);
+}
+```
+
+**Runtime Errors:**
+
+```typescript
+// Mock setup issues
+if (error.includes('stub') || error.includes('mock')) {
+ await fixMockConfiguration(testFile);
+}
+
+// Assertion failures
+if (error.includes('AssertionError')) {
+ await analyzeAssertionFailure(error);
+}
+```
+
+### Systematic Failure Analysis
+
+Fix test issues iteratively - run tests, analyze failures, apply fixes, repeat until passing. When unit tests fail with VS Code API errors like `TypeError: X is not a constructor` or `Cannot read properties of undefined (reading 'Y')`, check if VS Code APIs are properly mocked in `/src/test/unittests.ts` - add missing APIs following the existing pattern.
+
+```typescript
+interface TestFailureAnalysis {
+ type: 'compilation' | 'runtime' | 'assertion' | 'timeout';
+ message: string;
+ location: { file: string; line: number; col: number };
+ suggestedFix: string;
+}
+
+function analyzeFailure(failure: TestFailure): TestFailureAnalysis {
+ if (failure.message.includes('Cannot find module')) {
+ return {
+ type: 'compilation',
+ message: failure.message,
+ location: failure.location,
+ suggestedFix: 'Add missing import statement',
+ };
+ }
+ // ... other failure patterns
+}
+```
+
+### Agent Decision Logic for Test Type Selection
+
+**Choose Unit Tests (`*.unit.test.ts`) when analyzing:**
+
+- Functions with clear inputs/outputs and no VS Code API dependencies
+- Data transformation, parsing, or utility functions
+- Business logic that can be isolated with mocks
+- Error handling scenarios with predictable inputs
+
+**Choose Extension Tests (`*.test.ts`) when analyzing:**
+
+- Functions that register VS Code commands or use `vscode.*` APIs
+- UI components, tree views, or command palette interactions
+- File system operations requiring workspace context
+- Extension lifecycle events (activation, deactivation)
+
+**Agent Implementation Pattern:**
+
+```typescript
+function determineTestType(functionCode: string): 'unit' | 'extension' {
+ if (
+ functionCode.includes('vscode.') ||
+ functionCode.includes('commands.register') ||
+ functionCode.includes('window.') ||
+ functionCode.includes('workspace.')
+ ) {
+ return 'extension';
+ }
+ return 'unit';
+}
+```
+
+## π― Step 1: Automated Function Analysis
+
+As an AI agent, analyze the target function systematically:
+
+### Code Analysis Checklist
+
+```typescript
+interface FunctionAnalysis {
+ name: string;
+ inputs: string[]; // Parameter types and names
+ outputs: string; // Return type
+ dependencies: string[]; // External modules/APIs used
+ sideEffects: string[]; // Logging, file system, network calls
+ errorPaths: string[]; // Exception scenarios
+ testType: 'unit' | 'extension';
+}
+```
+
+### Analysis Implementation
+
+1. **Read function source** using `read_file` tool
+2. **Identify imports** - look for `vscode.*`, `child_process`, `fs`, etc.
+3. **Map data flow** - trace inputs through transformations to outputs
+4. **Catalog dependencies** - external calls that need mocking
+5. **Document side effects** - logging, file operations, state changes
+
+### Test Setup Differences
+
+#### Unit Test Setup (\*.unit.test.ts)
+
+```typescript
+// Mock VS Code APIs - handled automatically by unittests.ts
+import * as sinon from 'sinon';
+import * as workspaceApis from '../../common/workspace.apis'; // Wrapper functions
+
+// Stub wrapper functions, not VS Code APIs directly
+// Always mock wrapper functions (e.g., workspaceApis.getConfiguration()) instead of
+// VS Code APIs directly to avoid stubbing issues
+const mockGetConfiguration = sinon.stub(workspaceApis, 'getConfiguration');
+```
+
+#### Extension Test Setup (\*.test.ts)
+
+```typescript
+// Use real VS Code APIs
+import * as vscode from 'vscode';
+
+// Real VS Code APIs available - no mocking needed
+const config = vscode.workspace.getConfiguration('python');
+```
+
+## π― Step 2: Generate Test Coverage Matrix
+
+Based on function analysis, automatically generate comprehensive test scenarios:
+
+### Coverage Matrix Generation
+
+```typescript
+interface TestScenario {
+ category: 'happy-path' | 'edge-case' | 'error-handling' | 'side-effects';
+ description: string;
+ inputs: Record;
+ expectedOutput?: any;
+ expectedSideEffects?: string[];
+ shouldThrow?: boolean;
+}
+```
+
+### Automated Scenario Creation
+
+1. **Happy Path**: Normal execution with typical inputs
+2. **Edge Cases**: Boundary conditions, empty/null inputs, unusual but valid data
+3. **Error Scenarios**: Invalid inputs, dependency failures, exception paths
+4. **Side Effects**: Verify logging calls, file operations, state changes
+
+### Agent Pattern for Scenario Generation
+
+```typescript
+function generateTestScenarios(analysis: FunctionAnalysis): TestScenario[] {
+ const scenarios: TestScenario[] = [];
+
+ // Generate happy path for each input combination
+ scenarios.push(...generateHappyPathScenarios(analysis));
+
+ // Generate edge cases for boundary conditions
+ scenarios.push(...generateEdgeCaseScenarios(analysis));
+
+ // Generate error scenarios for each dependency
+ scenarios.push(...generateErrorScenarios(analysis));
+
+ return scenarios;
+}
+```
+
+## πΊοΈ Step 3: Plan Your Test Coverage
+
+### Create a Test Coverage Matrix
+
+#### Main Flows
+
+- β
**Happy path scenarios** - normal expected usage
+- β
**Alternative paths** - different configuration combinations
+- β
**Integration scenarios** - multiple features working together
+
+#### Edge Cases
+
+- πΈ **Boundary conditions** - empty inputs, missing data
+- πΈ **Error scenarios** - network failures, permission errors
+- πΈ **Data validation** - invalid inputs, type mismatches
+
+#### Real-World Scenarios
+
+- β
**Fresh install** - clean slate
+- β
**Existing user** - migration scenarios
+- β
**Power user** - complex configurations
+- πΈ **Error recovery** - graceful degradation
+
+### Example Test Plan Structure
+
+```markdown
+## Test Categories
+
+### 1. Configuration Migration Tests
+
+- No legacy settings exist
+- Legacy settings already migrated
+- Fresh migration needed
+- Partial migration required
+- Migration failures
+
+### 2. Configuration Source Tests
+
+- Global search paths
+- Workspace search paths
+- Settings precedence
+- Configuration errors
+
+### 3. Path Resolution Tests
+
+- Absolute vs relative paths
+- Workspace folder resolution
+- Path validation and filtering
+
+### 4. Integration Scenarios
+
+- Combined configurations
+- Deduplication logic
+- Error handling flows
+```
+
+## π§ Step 4: Set Up Your Test Infrastructure
+
+### Test File Structure
+
+```typescript
+// 1. Imports - group logically
+import assert from 'node:assert';
+import * as sinon from 'sinon';
+import { Uri } from 'vscode';
+import * as logging from '../../../common/logging';
+import * as pathUtils from '../../../common/utils/pathUtils';
+import * as workspaceApis from '../../../common/workspace.apis';
+
+// 2. Function under test
+import { getAllExtraSearchPaths } from '../../../managers/common/nativePythonFinder';
+
+// 3. Mock interfaces
+interface MockWorkspaceConfig {
+ get: sinon.SinonStub;
+ inspect: sinon.SinonStub;
+ update: sinon.SinonStub;
+}
+```
+
+### Mock Setup Strategy
+
+Create minimal mock objects with only required methods and use TypeScript type assertions (e.g., `mockApi as PythonEnvironmentApi`) to satisfy interface requirements instead of implementing all interface methods when only specific methods are needed for the test. Simplify mock setup by only mocking methods actually used in tests and use `as unknown as Type` for TypeScript compatibility.
+
+```typescript
+suite('Function Integration Tests', () => {
+ // 1. Declare all mocks
+ let mockGetConfiguration: sinon.SinonStub;
+ let mockGetWorkspaceFolders: sinon.SinonStub;
+ let mockTraceLog: sinon.SinonStub;
+ let mockTraceError: sinon.SinonStub;
+ let mockTraceWarn: sinon.SinonStub;
+
+ // 2. Mock complex objects
+ let pythonConfig: MockWorkspaceConfig;
+ let envConfig: MockWorkspaceConfig;
+
+ setup(() => {
+ // 3. Initialize all mocks
+ mockGetConfiguration = sinon.stub(workspaceApis, 'getConfiguration');
+ mockGetWorkspaceFolders = sinon.stub(workspaceApis, 'getWorkspaceFolders');
+ mockTraceLog = sinon.stub(logging, 'traceLog');
+ mockTraceError = sinon.stub(logging, 'traceError');
+ mockTraceWarn = sinon.stub(logging, 'traceWarn');
+
+ // 4. Set up default behaviors
+ mockGetWorkspaceFolders.returns(undefined);
+
+ // 5. Create mock configuration objects
+ // When fixing mock environment creation, use null to truly omit
+ // properties rather than undefined
+ pythonConfig = {
+ get: sinon.stub(),
+ inspect: sinon.stub(),
+ update: sinon.stub(),
+ };
+
+ envConfig = {
+ get: sinon.stub(),
+ inspect: sinon.stub(),
+ update: sinon.stub(),
+ };
+ });
+
+ teardown(() => {
+ sinon.restore(); // Always clean up!
+ });
+});
+```
+
+## Step 4: Write Tests Using Mock β Run β Assert Pattern
+
+### The Three-Phase Pattern
+
+#### Phase 1: Mock (Set up the scenario)
+
+```typescript
+test('Description of what this tests', async () => {
+ // Mock β Clear description of the scenario
+ pythonConfig.inspect.withArgs('venvPath').returns({ globalValue: '/path' });
+ envConfig.inspect.withArgs('globalSearchPaths').returns({ globalValue: [] });
+ mockGetWorkspaceFolders.returns([{ uri: Uri.file('/workspace') }]);
+```
+
+#### Phase 2: Run (Execute the function)
+
+```typescript
+// Run
+const result = await getAllExtraSearchPaths();
+```
+
+#### Phase 3: Assert (Verify the behavior)
+
+```typescript
+ // Assert - Use set-based comparison for order-agnostic testing
+ const expected = new Set(['/expected', '/paths']);
+ const actual = new Set(result);
+ assert.strictEqual(actual.size, expected.size, 'Should have correct number of paths');
+ assert.deepStrictEqual(actual, expected, 'Should contain exactly the expected paths');
+
+ // Verify side effects
+ // Use sinon.match() patterns for resilient assertions that don't break on minor output changes
+ assert(mockTraceLog.calledWith(sinon.match(/completion/i)), 'Should log completion');
+});
+```
+
+## Step 6: Make Tests Resilient
+
+### Use Order-Agnostic Comparisons
+
+```typescript
+// β Brittle - depends on order
+assert.deepStrictEqual(result, ['/path1', '/path2', '/path3']);
+
+// β
Resilient - order doesn't matter
+const expected = new Set(['/path1', '/path2', '/path3']);
+const actual = new Set(result);
+assert.strictEqual(actual.size, expected.size, 'Should have correct number of paths');
+assert.deepStrictEqual(actual, expected, 'Should contain exactly the expected paths');
+```
+
+### Use Flexible Error Message Testing
+
+```typescript
+// β Brittle - exact text matching
+assert(mockTraceError.calledWith('Error during legacy python settings migration:'));
+
+// β
Resilient - pattern matching
+assert(mockTraceError.calledWith(sinon.match.string, sinon.match.instanceOf(Error)), 'Should log migration error');
+
+// β
Resilient - key terms with regex
+assert(mockTraceError.calledWith(sinon.match(/migration.*error/i)), 'Should log migration error');
+```
+
+### Handle Complex Mock Scenarios
+
+```typescript
+// For functions that call the same mock multiple times
+envConfig.inspect.withArgs('globalSearchPaths').returns({ globalValue: [] });
+envConfig.inspect
+ .withArgs('globalSearchPaths')
+ .onSecondCall()
+ .returns({
+ globalValue: ['/migrated/paths'],
+ });
+
+// Testing async functions with child processes:
+// Call the function first to get a promise, then use setTimeout to emit mock events,
+// then await the promise - this ensures proper timing of mock setup versus function execution
+
+// Cannot stub internal function calls within the same module after import - stub external
+// dependencies instead (e.g., stub childProcessApis.spawnProcess rather than trying to stub
+// helpers.isUvInstalled when testing helpers.shouldUseUv) because intra-module calls use
+// direct references, not module exports
+```
+
+## π§ͺ Step 7: Test Categories and Patterns
+
+### Configuration Tests
+
+- Test different setting combinations
+- Test setting precedence (workspace > user > default)
+- Test configuration errors and recovery
+- Always use dynamic path construction with Node.js `path` module when testing functions that resolve paths against workspace folders to ensure cross-platform compatibility
+
+### Data Flow Tests
+
+- Test how data moves through the system
+- Test transformations (path resolution, filtering)
+- Test state changes (migrations, updates)
+
+### Error Handling Tests
+
+- Test graceful degradation
+- Test error logging
+- Test fallback behaviors
+
+### Integration Tests
+
+- Test multiple features together
+- Test real-world scenarios
+- Test edge case combinations
+
+## π Step 8: Review and Refine
+
+### Test Quality Checklist
+
+- [ ] **Clear naming** - test names describe the scenario and expected outcome
+- [ ] **Good coverage** - main flows, edge cases, error scenarios
+- [ ] **Resilient assertions** - won't break due to minor changes
+- [ ] **Readable structure** - follows Mock β Run β Assert pattern
+- [ ] **Isolated tests** - each test is independent
+- [ ] **Fast execution** - tests run quickly with proper mocking
+
+### Common Anti-Patterns to Avoid
+
+- β Testing implementation details instead of behavior
+- β Brittle assertions that break on cosmetic changes
+- β Order-dependent tests that fail due to processing changes
+- β Tests that don't clean up mocks properly
+- β Overly complex test setup that's hard to understand
+
+## π Reviewing and Improving Existing Tests
+
+### Quick Review Process
+
+1. **Read test files** - Check structure and mock setup
+2. **Run tests** - Establish baseline functionality
+3. **Apply improvements** - Use patterns below. When reviewing existing tests, focus on behavior rather than implementation details in test names and assertions
+4. **Verify** - Ensure tests still pass
+
+### Common Fixes
+
+- Over-complex mocks β Minimal mocks with only needed methods
+- Brittle assertions β Behavior-focused with error messages
+- Vague test names β Clear scenario descriptions (transform "should return X when Y" into "should [expected behavior] when [scenario context]")
+- Missing structure β Mock β Run β Assert pattern
+- Untestable Node.js APIs β Create proxy abstraction functions (use function overloads to preserve intelligent typing while making functions mockable)
+
+## π§ Agent Learnings
+
+- When mocking `testController.createTestItem()` in unit tests, use `typemoq.It.isAny()` for parameters when testing handler behavior (not ID/label generation logic), but consider using specific matchers (e.g., `It.is((id: string) => id.startsWith('_error_'))`) when the actual values being passed are important for correctness - this balances test precision with maintainability (2)
+- Remove unused variables from test code immediately - leftover tracking variables like `validationCallCount` that aren't referenced indicate dead code that should be simplified (1)
+- Use `Uri.file(path).fsPath` for both sides of path comparisons in tests to ensure cross-platform compatibility - Windows converts forward slashes to backslashes automatically (1)
+- When tests fail with "Cannot stub non-existent property", the method likely moved to a different class during refactoring - find the class that owns the method and test that class directly instead of stubbing on the original class (1)
diff --git a/.github/instructions/testing_feature_area.instructions.md b/.github/instructions/testing_feature_area.instructions.md
new file mode 100644
index 000000000000..a4e11523d7c8
--- /dev/null
+++ b/.github/instructions/testing_feature_area.instructions.md
@@ -0,0 +1,263 @@
+---
+applyTo: 'src/client/testing/**'
+---
+
+# Testing feature area β Discovery, Run, Debug, and Results
+
+This document maps the testing support in the extension: discovery, execution (run), debugging, result reporting and how those pieces connect to the codebase. It's written for contributors and agents who need to navigate, modify, or extend test support (both `unittest` and `pytest`).
+
+## Overview
+
+- Purpose: expose Python tests in the VS Code Test Explorer (TestController), support discovery, run, debug, and surface rich results and outputs.
+- Scope: provider-agnostic orchestration + provider-specific adapters, TestController mapping, IPC with Python-side scripts, debug launch integration, and configuration management.
+
+## High-level architecture
+
+- Controller / UI bridge: orchestrates TestController requests and routes them to workspace adapters.
+- Workspace adapter: provider-agnostic coordinator that translates TestController requests to provider adapters and maps payloads back into TestItems/TestRuns.
+- Provider adapters: implement discovery/run/debug for `unittest` and `pytest` by launching Python scripts and wiring named-pipe IPC.
+- Result resolver: translates Python-side JSON/IPCPayloads into TestController updates (start/pass/fail/output/attachments).
+- Debug launcher: prepares debug sessions and coordinates the debugger attach flow with the Python runner.
+
+## Key components (files and responsibilities)
+
+- Entrypoints
+ - `src/client/testing/testController/controller.ts` β `PythonTestController` (main orchestrator).
+ - `src/client/testing/serviceRegistry.ts` β DI/wiring for testing services.
+- Workspace orchestration
+ - `src/client/testing/testController/workspaceTestAdapter.ts` β `WorkspaceTestAdapter` (provider-agnostic entry used by controller).
+- **Project-based testing (multi-project workspaces)**
+ - `src/client/testing/testController/common/testProjectRegistry.ts` β `TestProjectRegistry` (manages project lifecycle, discovery, and nested project handling).
+ - `src/client/testing/testController/common/projectAdapter.ts` β `ProjectAdapter` interface (represents a single Python project with its own test infrastructure).
+ - `src/client/testing/testController/common/projectUtils.ts` β utilities for project ID generation, display names, and shared adapter creation.
+- Provider adapters
+ - Unittest
+ - `src/client/testing/testController/unittest/testDiscoveryAdapter.ts`
+ - `src/client/testing/testController/unittest/testExecutionAdapter.ts`
+ - Pytest
+ - `src/client/testing/testController/pytest/pytestDiscoveryAdapter.ts`
+ - `src/client/testing/testController/pytest/pytestExecutionAdapter.ts`
+- Result resolution and helpers
+ - `src/client/testing/testController/common/resultResolver.ts` β `PythonResultResolver` (maps payload -> TestController updates).
+ - `src/client/testing/testController/common/testItemUtilities.ts` β helpers for TestItem lifecycle.
+ - `src/client/testing/testController/common/types.ts` β `ITestDiscoveryAdapter`, `ITestExecutionAdapter`, `ITestResultResolver`, `ITestDebugLauncher`.
+ - `src/client/testing/testController/common/debugLauncher.ts` β debug session creation helper.
+ - `src/client/testing/testController/common/utils.ts` β named-pipe helpers and command builders (`startDiscoveryNamedPipe`, etc.).
+- Configuration
+ - `src/client/testing/common/testConfigurationManager.ts` β per-workspace test settings.
+ - `src/client/testing/configurationFactory.ts` β configuration service factory.
+- Utilities & glue
+ - `src/client/testing/utils.ts` β assorted helpers used by adapters.
+ - Python-side scripts: `python_files/unittestadapter/*`, `python_files/pytestadapter/*` β discovery/run code executed by adapters.
+
+## Python subprocess runners (what runs inside Python)
+
+The adapters in the extension don't implement test discovery/run logic themselves β they spawn a Python subprocess that runs small helper scripts located under `python_files/` and stream structured events back to the extension over the named-pipe IPC. This is a central part of the feature area; changes here usually require coordinated edits in both the TypeScript adapters and the Python scripts.
+
+- Unittest helpers (folder: `python_files/unittestadapter`)
+
+ - `discovery.py` β performs `unittest` discovery and emits discovery payloads (test suites, cases, locations) on the IPC channel.
+ - `execution.py` / `django_test_runner.py` β run tests for `unittest` and, where applicable, Django test runners; emit run events (start, stdout/stderr, pass, fail, skip, teardown) and attachment info.
+ - `pvsc_utils.py`, `django_handler.py` β utility helpers used by the runners for environment handling and Django-specific wiring.
+ - The adapter TypeScript files (`testDiscoveryAdapter.ts`, `testExecutionAdapter.ts`) construct the command line, start a named-pipe listener, and spawn these Python scripts using the extension's ExecutionFactory (activated interpreter) so the scripts execute inside the user's selected environment.
+
+- Pytest helpers (folder: `python_files/vscode_pytest`)
+
+ - `_common.py` β shared helpers for pytest runner scripts.
+ - `run_pytest_script.py` β the primary pytest runner used for discovery and execution; emits the same structured IPC payloads the extension expects (discovery events and run events).
+ - The `pytest` execution adapter (`pytestExecutionAdapter.ts`) and discovery adapter build the CLI to run `run_pytest_script.py`, start the pipe, and translate incoming payloads via `PythonResultResolver`.
+
+- IPC contract and expectations
+
+ - Adapters rely on a stable JSON payload contract emitted by the Python scripts: identifiers for tests, event types (discovered, collected, started, passed, failed, skipped), timings, error traces, and optional attachments (logs, captured stdout/stderr, file links).
+ - The extension maps these payloads to `TestItem`/`TestRun` updates via `PythonResultResolver` (`src/client/testing/testController/common/resultResolver.ts`). If you change payload shape, update the resolver and tests concurrently.
+
+- How the subprocess is started
+ - Execution adapters use the extension's `ExecutionFactory` (preferred) to get an activated interpreter and then spawn a child process that runs the helper script. The adapter will set up environment variables and command-line args (including the pipe name / run-id) so the Python runner knows where to send events and how to behave (discovery vs run vs debug).
+ - For debug sessions a debug-specific entry argument/port is passed and `common/debugLauncher.ts` coordinates starting a VS Code debug session that will attach to the Python process.
+
+## Core functionality (what to change where)
+
+- Discovery
+ - Entry: `WorkspaceTestAdapter.discoverTests` β provider discovery adapter. Adapter starts a named-pipe listener, spawns the discovery script in an activated interpreter, forwards discovery events to `PythonResultResolver` which creates/updates TestItems.
+ - Files: `workspaceTestAdapter.ts`, `*DiscoveryAdapter.ts`, `resultResolver.ts`, `testItemUtilities.ts`.
+- Run / Execution
+ - Entry: `WorkspaceTestAdapter.executeTests` β provider execution adapter. Adapter spawns runner in an activated env, runner streams run events to the pipe, `PythonResultResolver` updates a `TestRun` with start/pass/fail and attachments.
+ - Files: `workspaceTestAdapter.ts`, `*ExecutionAdapter.ts`, `resultResolver.ts`.
+- Debugging
+ - Flow: debug request flows like a run but goes through `debugLauncher.ts` to create a VS Code debug session with prepared ports/pipes. The Python runner coordinates attach/continue with the debugger.
+ - Files: `*ExecutionAdapter.ts`, `common/debugLauncher.ts`, `common/types.ts`.
+- Result reporting
+ - `resultResolver.ts` is the canonical place to change how JSON payloads map to TestController constructs (messages, durations, error traces, attachments).
+
+## Typical workflows (short)
+
+- Full discovery
+
+ 1. `PythonTestController` triggers discovery -> `WorkspaceTestAdapter.discoverTests`.
+ 2. Provider discovery adapter starts pipe and launches Python discovery script.
+ 3. Discovery events -> `PythonResultResolver` -> TestController tree updated.
+
+- Run tests
+
+ 1. Controller collects TestItems -> creates `TestRun`.
+ 2. `WorkspaceTestAdapter.executeTests` delegates to execution adapter which launches the runner.
+ 3. Runner events arrive via pipe -> `PythonResultResolver` updates `TestRun`.
+ 4. On process exit the run is finalized.
+
+- Debug a test
+ 1. Debug request flows to execution adapter.
+ 2. Adapter prepares ports and calls `debugLauncher` to start a VS Code debug session with the run ID.
+ 3. Runner coordinates with the debugger; `PythonResultResolver` still receives and applies run events.
+
+## Tests and examples to inspect
+
+- Unit/integration tests for adapters and orchestration under `src/test/` (examples):
+ - `src/test/testing/common/testingAdapter.test.ts`
+ - `src/test/testing/testController/workspaceTestAdapter.unit.test.ts`
+ - `src/test/testing/testController/unittest/testExecutionAdapter.unit.test.ts`
+ - Adapter tests demonstrate expected telemetry, debug-launch payloads and result resolution.
+
+## History & evolution (brief)
+
+- Migration to TestController API: the code organizes around VS Code TestController, mapping legacy adapter behaviour into TestItems/TestRuns.
+- Named-pipe IPC: discovery/run use named-pipe IPC to stream events from Python runner scripts (`python_files/*`) which enables richer, incremental updates and debug coordination.
+- Environment activation: adapters prefer the extension ExecutionFactory (activated interpreter) to run discovery and test scripts.
+
+## Pointers for contributors (practical)
+
+- To extend discovery output: update the Python discovery script in `python_files/*` and `resultResolver.ts` to parse new payload fields.
+- To change run behaviour (args/env/timouts): update the provider execution adapter (`*ExecutionAdapter.ts`) and add/update tests under `src/test/`.
+- To change debug flow: edit `common/debugLauncher.ts` and adapters' debug paths; update tests that assert launch argument shapes.
+
+## Django support (how it works)
+
+- The extension supports Django projects by delegating discovery and execution to Django-aware Python helpers under `python_files/unittestadapter`.
+ - `python_files/unittestadapter/django_handler.py` contains helpers that invoke `manage.py` for discovery or execute Django test runners inside the project context.
+ - `python_files/unittestadapter/django_test_runner.py` provides `CustomDiscoveryTestRunner` and `CustomExecutionTestRunner` which integrate with the extension by using the same IPC contract (they use `UnittestTestResult` and `send_post_request` to emit discovery/run payloads).
+- How adapters pass Django configuration:
+ - Execution adapters set environment variables (e.g. `MANAGE_PY_PATH`) and modify `PYTHONPATH` so Django code and the custom test runner are importable inside the spawned subprocess.
+ - For discovery the adapter may run the discovery helper which calls `manage.py test` with a custom test runner that emits discovery payloads instead of executing tests.
+- Practical notes for contributors:
+ - Changes to Django discovery/execution often require edits in both `django_test_runner.py`/`django_handler.py` and the TypeScript adapters (`testDiscoveryAdapter.ts` / `testExecutionAdapter.ts`).
+ - The Django test runner expects `TEST_RUN_PIPE` environment variable to be present to send IPC events (see `django_test_runner.py`).
+
+## Settings referenced by this feature area
+
+- The extension exposes several `python.testing.*` settings used by adapters and configuration code (declared in `package.json`):
+ - `python.testing.pytestEnabled`, `python.testing.unittestEnabled` β enable/disable frameworks.
+ - `python.testing.pytestPath`, `python.testing.pytestArgs`, `python.testing.unittestArgs` β command path and CLI arguments used when spawning helper scripts.
+ - `python.testing.cwd` β optional working directory used when running discovery/runs.
+ - `python.testing.autoTestDiscoverOnSaveEnabled`, `python.testing.autoTestDiscoverOnSavePattern` β control automatic discovery on save.
+ - `python.testing.debugPort` β default port used for debug runs.
+ - `python.testing.promptToConfigure` β whether to prompt users to configure tests when potential test folders are found.
+- Where to look in the code:
+ - Settings are consumed by `src/client/testing/common/testConfigurationManager.ts`, `src/client/testing/configurationFactory.ts`, and adapters under `src/client/testing/testController/*` which read settings to build CLI args and env for subprocesses.
+ - The setting definitions and descriptions are in `package.json` and localized strings in `package.nls.json`.
+
+## Project-based testing (multi-project workspaces)
+
+Project-based testing enables multi-project workspace support where each Python project gets its own test tree root with its own Python environment.
+
+### Architecture
+
+- **TestProjectRegistry** (`testProjectRegistry.ts`): Central registry that:
+
+ - Discovers Python projects via the Python Environments API
+ - Creates and manages `ProjectAdapter` instances per workspace
+ - Computes nested project relationships and configures ignore lists
+ - Falls back to "legacy" single-adapter mode when API unavailable
+
+- **ProjectAdapter** (`projectAdapter.ts`): Interface representing a single project with:
+ - Project identity (ID, name, URI from Python Environments API)
+ - Python environment with execution details
+ - Test framework adapters (discovery/execution)
+ - Nested project ignore paths (for parent projects)
+
+### How it works
+
+1. **Activation**: When the extension activates, `PythonTestController` checks if the Python Environments API is available.
+2. **Project discovery**: `TestProjectRegistry.discoverAndRegisterProjects()` queries the API for all Python projects in each workspace.
+3. **Nested handling**: `configureNestedProjectIgnores()` identifies child projects and adds their paths to parent projects' ignore lists.
+4. **Test discovery**: For each project, the controller calls `project.discoveryAdapter.discoverTests()` with the project's URI. The adapter sets `PROJECT_ROOT_PATH` environment variable for the Python runner.
+5. **Python side**:
+ - For pytest: `get_test_root_path()` in `vscode_pytest/__init__.py` returns `PROJECT_ROOT_PATH` (if set) or falls back to `cwd`.
+ - For unittest: `discovery.py` uses `PROJECT_ROOT_PATH` as `top_level_dir` and `project_root_path` to root the test tree at the project directory.
+6. **Test tree**: Each project gets its own root node in the Test Explorer, with test IDs scoped by project ID using the `@@vsc@@` separator (defined in `projectUtils.ts`).
+
+### Nested project handling: pytest vs unittest
+
+**pytest** supports the `--ignore` flag to exclude paths during test collection. When nested projects are detected, parent projects automatically receive `--ignore` flags for child project paths. This ensures each test appears under exactly one project in the test tree.
+
+**unittest** does not support path exclusion during `discover()`. Therefore, tests in nested project directories may appear under multiple project roots (both the parent and the child project). This is **expected behavior** for unittest:
+
+- Each project discovers and displays all tests it finds within its directory structure
+- There is no deduplication or collision detection
+- Users may see the same test file under multiple project roots if their project structure has nesting
+
+This approach was chosen because:
+
+1. unittest's `TestLoader.discover()` has no built-in path exclusion mechanism
+2. Implementing custom exclusion would add significant complexity with minimal benefit
+3. The existing approach is transparent and predictable - each project shows what it finds
+
+### Empty projects and root nodes
+
+If a project discovers zero tests, its root node will still appear in the Test Explorer as an empty folder. This ensures consistent behavior and makes it clear which projects were discovered, even if they have no tests yet.
+
+### Logging prefix
+
+All project-based testing logs use the `[test-by-project]` prefix for easy filtering in the output channel.
+
+### Key files
+
+- Python side:
+ - `python_files/vscode_pytest/__init__.py` β `get_test_root_path()` function and `PROJECT_ROOT_PATH` environment variable for pytest.
+ - `python_files/unittestadapter/discovery.py` β `discover_tests()` with `project_root_path` parameter and `PROJECT_ROOT_PATH` handling for unittest discovery.
+ - `python_files/unittestadapter/execution.py` β `run_tests()` with `project_root_path` parameter and `PROJECT_ROOT_PATH` handling for unittest execution.
+- TypeScript: `testProjectRegistry.ts`, `projectAdapter.ts`, `projectUtils.ts`, and the discovery/execution adapters.
+
+### Tests
+
+- `src/test/testing/testController/common/testProjectRegistry.unit.test.ts` β TestProjectRegistry tests
+- `src/test/testing/testController/common/projectUtils.unit.test.ts` β Project utility function tests
+- `python_files/tests/pytestadapter/test_discovery.py` β pytest PROJECT_ROOT_PATH tests (see `test_project_root_path_env_var()` and `test_symlink_with_project_root_path()`)
+- `python_files/tests/unittestadapter/test_discovery.py` β unittest `project_root_path` / PROJECT_ROOT_PATH discovery tests
+- `python_files/tests/unittestadapter/test_execution.py` β unittest `project_root_path` / PROJECT_ROOT_PATH execution tests
+- `src/test/testing/testController/unittest/testDiscoveryAdapter.unit.test.ts` β unittest discovery adapter PROJECT_ROOT_PATH tests
+- `src/test/testing/testController/unittest/testExecutionAdapter.unit.test.ts` β unittest execution adapter PROJECT_ROOT_PATH tests
+
+## Coverage support (how it works)
+
+- Coverage is supported by running the Python helper scripts with coverage enabled and then collecting a coverage payload from the runner.
+ - Pytest-side coverage logic lives in `python_files/vscode_pytest/__init__.py` (checks `COVERAGE_ENABLED`, imports `coverage`, computes per-file metrics and emits a `CoveragePayloadDict`).
+ - Unittest adapters enable coverage by setting environment variable(s) (e.g. `COVERAGE_ENABLED`) when launching the subprocess; adapters and `resultResolver.ts` handle the coverage profile kind (`TestRunProfileKind.Coverage`).
+- Flow summary:
+ 1. User starts a Coverage run via Test Explorer (profile kind `Coverage`).
+ 2. Controller/adapters set `COVERAGE_ENABLED` (or equivalent) in the subprocess env and invoke the runner script.
+ 3. The Python runner collects coverage (using `coverage` or `pytest-cov`), builds a file-level coverage map, and sends a coverage payload back over the IPC.
+ 4. `PythonResultResolver` (`src/client/testing/testController/common/resultResolver.ts`) receives the coverage payload and stores `detailedCoverageMap` used by the TestController profile to show file-level coverage details.
+- Tests that exercise coverage flows are under `src/test/testing/*` and `python_files/tests/*` (see `testingAdapter.test.ts` and adapter unit tests that assert `COVERAGE_ENABLED` is set appropriately).
+
+## Interaction with the VS Code API
+
+- TestController API
+ - The feature area is built on VS Code's TestController/TestItem/TestRun APIs (`vscode.tests.createTestController` / `tests.createTestController` in the code). The controller creates a `TestController` in `src/client/testing/testController/controller.ts` and synchronizes `TestItem` trees with discovery payloads.
+ - `PythonResultResolver` maps incoming JSON events to VS Code API calls: `testRun.appendOutput`, `testRun.passed/failed/skipped`, `testRun.end`, and `TestItem` updates (labels, locations, children).
+- Debug API
+ - Debug runs use the Debug API to start an attach/launch session. The debug launcher implementation is in `src/client/testing/testController/common/debugLauncher.ts` which constructs a debug configuration and calls the VS Code debug API to start a session (e.g. `vscode.debug.startDebugging`).
+ - Debug adapter/resolver code in the extension's debugger modules may also be used when attaching to Django or test subprocesses.
+- Commands and configuration
+ - The Test Controller wires commands that appear in the Test Explorer and editor context menus (see `package.json` contributes `commands`) and listens to configuration changes filtered by `python.testing` in `src/client/testing/main.ts`.
+- The "Copy Test ID" command (`python.copyTestId`) can be accessed from both the Test Explorer context menu (`testing/item/context`) and the editor gutter icon context menu (`testing/item/gutter`). This command copies test identifiers to the clipboard in the appropriate format for the active test framework (pytest path format or unittest module.class.method format).
+- Execution factory & activated environments
+ - Adapters use the extension `ExecutionFactory` to spawn subprocesses in an activated interpreter (so the user's venv/conda is used). This involves the extension's internal environment execution APIs and sometimes `envExt` helpers when the external environment extension is present.
+
+## Learnings
+
+- Never await `showErrorMessage()` calls in test execution adapters as it blocks the test UI thread and freezes the Test Explorer (1)
+- VS Code test-related context menus are contributed to using both `testing/item/context` and `testing/item/gutter` menu locations in package.json for full coverage (1)
+
+```
+
+```
diff --git a/.github/prompts/extract-impl-instructions.prompt.md b/.github/prompts/extract-impl-instructions.prompt.md
new file mode 100644
index 000000000000..c2fb08b443c7
--- /dev/null
+++ b/.github/prompts/extract-impl-instructions.prompt.md
@@ -0,0 +1,79 @@
+---
+mode: edit
+---
+
+Analyze the specified part of the VS Code Python Extension codebase to generate or update implementation instructions in `.github/instructions/.instructions.md`.
+
+## Task
+
+Create concise developer guidance focused on:
+
+### Implementation Essentials
+
+- **Core patterns**: How this component is typically implemented and extended
+- **Key interfaces**: Essential classes, services, and APIs with usage examples
+- **Integration points**: How this component interacts with other extension parts
+- **Common tasks**: Typical development scenarios with step-by-step guidance
+
+### Content Structure
+
+````markdown
+---
+description: 'Implementation guide for the part of the Python Extension'
+---
+
+# Implementation Guide
+
+## Overview
+
+Brief description of the component's purpose and role in VS Code Python Extension.
+
+## Key Concepts
+
+- Main abstractions and their responsibilities
+- Important interfaces and base classes
+
+## Common Implementation Patterns
+
+### Pattern 1: [Specific Use Case]
+
+```typescript
+// Code example showing typical implementation
+```
+````
+
+### Pattern 2: [Another Use Case]
+
+```typescript
+// Another practical example
+```
+
+## Integration Points
+
+- How this component connects to other VS Code Python Extension systems
+- Required services and dependencies
+- Extension points and contribution models
+
+## Essential APIs
+
+- Key methods and interfaces developers need
+- Common parameters and return types
+
+## Gotchas and Best Practices
+
+- Non-obvious behaviors to watch for
+- Performance considerations
+- Common mistakes to avoid
+
+```
+
+## Guidelines
+- **Be specific**: Use actual class names, method signatures, and file paths
+- **Show examples**: Include working code snippets from the codebase
+- **Target implementation**: Focus on how to build with/extend this component
+- **Keep it actionable**: Every section should help developers accomplish tasks
+
+Source conventions from existing `.github/instructions/*.instructions.md`, `CONTRIBUTING.md`, and codebase patterns.
+
+If `.github/instructions/.instructions.md` exists, intelligently merge new insights with existing content.
+```
diff --git a/.github/prompts/extract-usage-instructions.prompt.md b/.github/prompts/extract-usage-instructions.prompt.md
new file mode 100644
index 000000000000..ea48f162a220
--- /dev/null
+++ b/.github/prompts/extract-usage-instructions.prompt.md
@@ -0,0 +1,30 @@
+---
+mode: edit
+---
+
+Analyze the user requested part of the codebase (use a suitable ) to generate or update `.github/instructions/.instructions.md` for guiding developers and AI coding agents.
+
+Focus on practical usage patterns and essential knowledge:
+
+- How to use, extend, or integrate with this code area
+- Key architectural patterns and conventions specific to this area
+- Common implementation patterns with code examples
+- Integration points and typical interaction patterns with other components
+- Essential gotchas and non-obvious behaviors
+
+Source existing conventions from `.github/instructions/*.instructions.md`, `CONTRIBUTING.md`, and `README.md`.
+
+Guidelines:
+
+- Write concise, actionable instructions using markdown structure
+- Document discoverable patterns with concrete examples
+- If `.github/instructions/.instructions.md` exists, merge intelligently
+- Target developers who need to work with or extend this code area
+
+Update `.github/instructions/.instructions.md` with header:
+
+```
+---
+description: "How to work with the part of the codebase"
+---
+```
diff --git a/.github/release_plan.md b/.github/release_plan.md
index 71f8d8aa0955..091ed559825b 100644
--- a/.github/release_plan.md
+++ b/.github/release_plan.md
@@ -1,23 +1,47 @@
+### General Notes
All dates should align with VS Code's [iteration](https://github.com/microsoft/vscode/labels/iteration-plan) and [endgame](https://github.com/microsoft/vscode/labels/endgame-plan) plans.
Feature freeze is Monday @ 17:00 America/Vancouver, XXX XX. At that point, commits to `main` should only be in response to bugs found during endgame testing until the release candidate is ready.
+
+ Release Primary and Secondary Assignments for the 2025 Calendar Year
-NOTE: the number of this release is in the issue title and can be substituted in wherever you see [YYYY.minor].
+| Month and version number | Primary | Secondary |
+|------------|----------|-----------|
+| January v2025.0.0 | Eleanor | Karthik |
+| February v2025.2.0 | Anthony | Eleanor |
+| March v2025.4.0 | Karthik | Anthony |
+| April v2025.6.0 | Eleanor | Karthik |
+| May v2025.8.0 | Anthony | Eleanor |
+| June v2025.10.0 | Karthik | Anthony |
+| July v2025.12.0 | Eleanor | Karthik |
+| August v2025.14.0 | Anthony | Eleanor |
+| September v2025.16.0 | Karthik | Anthony |
+| October v2025.18.0 | Eleanor | Karthik |
+| November v2025.20.0 | Anthony | Eleanor |
+| December v2025.22.0 | Karthik | Anthony |
+
+
-# Release candidate (Monday, XXX XX)
+# Release candidate (Thursday, XXX XX)
+NOTE: This Thursday occurs during TESTING week. Branching should be done during this week to freeze the release with only the correct changes. Any last minute fixes go in as candidates into the release branch and will require team approval.
+Other:
NOTE: Third Party Notices are automatically added by our build pipelines using https://tools.opensource.microsoft.com/notice.
+NOTE: the number of this release is in the issue title and can be substituted in wherever you see [YYYY.minor].
+
### Step 1:
-##### Bump the version of `main` to be a release candidate (also updating debugpy dependences, third party notices, and package-lock.json).βοΈ (steps with βοΈ will dictate this step happens while main is frozen π₯Ά)
+##### Bump the version of `main` to be a release candidate (also updating third party notices, and package-lock.json).βοΈ (steps with βοΈ will dictate this step happens while main is frozen π₯Ά)
- [ ] checkout to `main` on your local machine and run `git fetch` to ensure your local is up to date with the remote repo.
- [ ] Create a new branch called **`bump-release-[YYYY.minor]`**.
-- [ ] Change the version in `package.json` to the next **even** number and switch the `-dev` to `-rc`. (π€)
+- [ ] Update `pet`:
+ - [ ] Go to the [pet](https://github.com/microsoft/python-environment-tools) repo and check `main` and latest `release/*` branch. If there are new changes in `main` then create a branch called `release/YYYY.minor` (matching python extension release `major.minor`).
+ - [ ] Update `build\azure-pipeline.stable.yml` to point to the latest `release/YYYY.minor` for `python-environment-tools`.
+- [ ] Change the version in `package.json` to the next **even** number. (π€)
- [ ] Run `npm install` to make sure `package-lock.json` is up-to-date _(you should now see changes to the `package.json` and `package-lock.json` at this point which update the version number **only**)_. (π€)
-- [ ] Check [debugpy on PyPI](https://pypi.org/project/debugpy/) for a new release and update the version of debugpy in [`install_debugpy.py`](https://github.com/microsoft/vscode-python/blob/main/pythonFiles/install_debugpy.py) if necessary.
- [ ] Update `ThirdPartyNotices-Repository.txt` as appropriate. You can check by looking at the [commit history](https://github.com/microsoft/vscode-python/commits/main) and scrolling through to see if there's anything listed there which might have pulled in some code directly into the repository from somewhere else. If you are still unsure you can check with the team.
- [ ] Create a PR from your branch **`bump-release-[YYYY.minor]`** to `main`. Add the `"no change-log"` tag to the PR so it does not show up on the release notes before merging it.
@@ -40,7 +64,7 @@ NOTE: If there are release branches that are two versions old you can delete the
### Step 4: Return `main` to dev and unfreeze (βοΈ β‘ π§)
NOTE: The purpose of this step is ensuring that main always is on a dev version number for every night's π pre-release. Therefore it is imperative that you do this directly after the previous steps to reset the version in main to a dev version **before** a pre-release goes out.
- [ ] Create a branch called **`bump-dev-version-YYYY.[minor+1]`**.
-- [ ] Bump the minor version number in the `package.json` to the next `YYYY.[minor+1]` which will be an odd number, and switch the `-rc` to `-dev`.(π€)
+- [ ] Bump the minor version number in the `package.json` to the next `YYYY.[minor+1]` which will be an odd number, and add `-dev`.(π€)
- [ ] Run `npm install` to make sure `package-lock.json` is up-to-date _(you should now see changes to the `package.json` and `package-lock.json` only relating to the new version number)_ . (π€)
- [ ] Create a PR from this branch against `main` and merge it.
@@ -59,12 +83,6 @@ NOTE: this PR should make all CI relating to `main` be passing again (such as th
### Step 6: Take the release branch from a candidate to the finalized release
- [ ] Make sure the [appropriate pull requests](https://github.com/microsoft/vscode-docs/pulls) for the [documentation](https://code.visualstudio.com/docs/python/python-tutorial) -- including the [WOW](https://code.visualstudio.com/docs/languages/python) page -- are ready.
- [ ] Check to make sure any final updates to the **`release/YYYY.minor`** branch have been merged.
-- [ ] Create a branch against **`release/YYYY.minor`** called **`finalized-release-[YYYY.minor]`**.
-- [ ] Update the version in `package.json` to remove the `-rc` (π€) from the version.
-- [ ] Run `npm install` to make sure `package-lock.json` is up-to-date _(the only update should be the version number if `package-lock.json` has been kept up-to-date)_. (π€)
-- [ ] Update `ThirdPartyNotices-Repository.txt` manually if necessary.
-- [ ] Create a PR from **`finalized-release-[YYYY.minor]`** against `release/YYYY.minor` and merge it.
-
### Step 7: Execute the Release
- [ ] Make sure CI is passing for **`release/YYYY.minor`** release branch (π€).
@@ -87,6 +105,7 @@ NOTE: this PR should make all CI relating to `main` be passing again (such as th
- [ ] Create a branch against **`release/YYYY.minor`** called **`release-[YYYY.minor.point]`**.
- [ ] Bump the point version number in the `package.json` to the next `YYYY.minor.point`
- [ ] Run `npm install` to make sure `package-lock.json` is up-to-date _(you should now see changes to the `package.json` and `package-lock.json` only relating to the new version number)_ . (π€)
+- [ ] If Point Release is due to an issue in `pet`. Update `build\azure-pipeline.stable.yml` to point to the branch `release/YYYY.minor` for `python-environment-tools` with the fix or decided by the team.
- [ ] Create a PR from this branch against `release/YYYY.minor`
- [ ] **Rebase** and merge this PR into the release branch
- [ ] Create a draft GitHub release for the release notes (π€) βοΈ
@@ -116,4 +135,4 @@ NOTE: this PR should make all CI relating to `main` be passing again (such as th
## Prep for the _next_ release
- [ ] Create a new [release plan](https://raw.githubusercontent.com/microsoft/vscode-python/main/.github/release_plan.md). (π€)
-- [ ] [(Un-)pin](https://help.github.com/en/articles/pinning-an-issue-to-your-repository) [release plan issues](https://github.com/Microsoft/vscode-python/labels/release%20plan) (π€)
+- [ ] [(Un-)pin](https://help.github.com/en/articles/pinning-an-issue-to-your-repository) [release plan issues](https://github.com/Microsoft/vscode-python/labels/release-plan) (π€)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 3de5bd1ff756..09d019dec4a7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,8 +8,10 @@ on:
- 'release/*'
- 'release-*'
+permissions: {}
+
env:
- NODE_VERSION: 18.17.1
+ NODE_VERSION: 22.21.1
PYTHON_VERSION: '3.10' # YML treats 3.10 the number as 3.1, so quotes around 3.10
# Force a path with spaces and to test extension works in these scenarios
# Unicode characters are causing 2.7 failures so skip that for now.
@@ -28,6 +30,7 @@ jobs:
run:
shell: python
outputs:
+ vsix_basename: ${{ steps.vsix_names.outputs.vsix_basename }}
vsix_name: ${{ steps.vsix_names.outputs.vsix_name }}
vsix_artifact_name: ${{ steps.vsix_names.outputs.vsix_artifact_name }}
steps:
@@ -40,23 +43,71 @@ jobs:
else:
vsix_type = "release"
print(f"::set-output name=vsix_name::ms-python-{vsix_type}.vsix")
+ print(f"::set-output name=vsix_basename::ms-python-{vsix_type}")
print(f"::set-output name=vsix_artifact_name::ms-python-{vsix_type}-vsix")
build-vsix:
name: Create VSIX
if: github.repository == 'microsoft/vscode-python'
needs: setup
- runs-on: ubuntu-latest
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - os: windows-latest
+ target: x86_64-pc-windows-msvc
+ vsix-target: win32-x64
+ - os: windows-latest
+ target: aarch64-pc-windows-msvc
+ vsix-target: win32-arm64
+ - os: ubuntu-latest
+ target: x86_64-unknown-linux-musl
+ vsix-target: linux-x64
+ # - os: ubuntu-latest
+ # target: aarch64-unknown-linux-gnu
+ # vsix-target: linux-arm64
+ # - os: ubuntu-latest
+ # target: arm-unknown-linux-gnueabihf
+ # vsix-target: linux-armhf
+ # - os: macos-latest
+ # target: x86_64-apple-darwin
+ # vsix-target: darwin-x64
+ # - os: macos-14
+ # target: aarch64-apple-darwin
+ # vsix-target: darwin-arm64
+ - os: ubuntu-latest
+ target: x86_64-unknown-linux-musl
+ vsix-target: alpine-x64
+ # - os: ubuntu-latest
+ # target: aarch64-unknown-linux-musl
+ # vsix-target: alpine-arm64
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: 'python-env-tools'
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Build VSIX
uses: ./.github/actions/build-vsix
with:
- node_version: ${{ env.NODE_VERSION }}
- vsix_name: ${{ needs.setup.outputs.vsix_name }}
- artifact_name: ${{ needs.setup.outputs.vsix_artifact_name }}
+ node_version: ${{ env.NODE_VERSION}}
+ vsix_name: ${{ needs.setup.outputs.vsix_basename }}-${{ matrix.vsix-target }}.vsix
+ artifact_name: ${{ needs.setup.outputs.vsix_artifact_name }}-${{ matrix.vsix-target }}
+ cargo_target: ${{ matrix.target }}
+ vsix_target: ${{ matrix.vsix-target }}
lint:
name: Lint
@@ -64,7 +115,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- name: Lint
uses: ./.github/actions/lint
@@ -77,34 +130,35 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Use Python ${{ env.PYTHON_VERSION }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- name: Install core Python requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- options: '-t ./pythonFiles/lib/python --no-cache-dir --implementation py'
+ options: '-t ./python_files/lib/python --no-cache-dir --implementation py'
- name: Install Jedi requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- requirements-file: './pythonFiles/jedilsp_requirements/requirements.txt'
- options: '-t ./pythonFiles/lib/jedilsp --no-cache-dir --implementation py'
+ requirements-file: './python_files/jedilsp_requirements/requirements.txt'
+ options: '-t ./python_files/lib/jedilsp --no-cache-dir --implementation py'
- name: Install other Python requirements
run: |
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Pyright
- uses: jakebailey/pyright-action@v2
+ uses: jakebailey/pyright-action@8ec14b5cfe41f26e5f41686a31eb6012758217ef # v3.0.2
with:
version: 1.1.308
- working-directory: 'pythonFiles'
+ working-directory: 'python_files'
python-tests:
name: Python Tests
@@ -120,30 +174,31 @@ jobs:
# macOS runners are expensive, and we assume that Ubuntu is enough to cover the Unix case.
os: [ubuntu-latest, windows-latest]
# Run the tests on the oldest and most recent versions of Python.
- python: ['3.8', '3.x', '3.12-dev']
+ python: ['3.10', '3.x', '3.13']
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
path: ${{ env.special-working-directory-relative }}
+ persist-credentials: false
- name: Use Python ${{ matrix.python }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install base Python requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ options: '-t "${{ env.special-working-directory-relative }}/python_files/lib/python" --no-cache-dir --implementation py'
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Python unit tests
- run: python pythonFiles/tests/run_all.py
+ run: python python_files/tests/run_all.py
tests:
name: Tests
@@ -163,12 +218,25 @@ jobs:
test-suite: [ts-unit, venv, single-workspace, multi-workspace, debugger, functional]
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
path: ${{ env.special-working-directory-relative }}
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: ${{ env.special-working-directory-relative }}/python-env-tools
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Install Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
@@ -184,46 +252,29 @@ jobs:
run: npx @vscode/l10n-dev@latest export ./src
- name: Install Python ${{ matrix.python }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- - name: Download get-pip.py
- run: |
- python -m pip install wheel
- python -m pip install -r build/build-install-requirements.txt
- python ./pythonFiles/download_get_pip.py
- shell: bash
+ - name: Upgrade Pip
+ run: python -m pip install -U pip
- - name: Install debugpy
- run: |
- # We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
-
- - name: Install core Python requirements
- uses: brettcannon/pip-secure-install@v1
- with:
- requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
- if: startsWith(matrix.python, 3.)
+ # For faster/better builds of sdists.
+ - name: Install build pre-requisite
+ run: python -m pip install wheel nox
- - name: Install Jedi requirements
- uses: brettcannon/pip-secure-install@v1
- with:
- requirements-file: '"${{ env.special-working-directory-relative }}/pythonFiles/jedilsp_requirements/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/jedilsp" --no-cache-dir --implementation py'
- if: startsWith(matrix.python, 3.)
+ - name: Install Python Extension dependencies (jedi, etc.)
+ run: nox --session install_python_libs
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
- - name: Install debugpy wheels (Python ${{ matrix.python }})
- run: |
- python -m pip install wheel
- python -m pip install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
+ - name: Rust Tool Chain setup
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Build Native Binaries
+ run: nox --session native_build
shell: bash
- if: matrix.test-suite == 'debugger'
- name: Install functional test requirements
run: python -m pip install --upgrade -r ./build/functional-test-requirements.txt
@@ -319,7 +370,7 @@ jobs:
env:
TEST_FILES_SUFFIX: testvirtualenvs
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testSingleWorkspace
working-directory: ${{ env.special-working-directory }}
@@ -328,7 +379,7 @@ jobs:
- name: Run single-workspace tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testSingleWorkspace
working-directory: ${{ env.special-working-directory }}
@@ -337,7 +388,7 @@ jobs:
- name: Run multi-workspace tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testMultiWorkspace
working-directory: ${{ env.special-working-directory }}
@@ -346,7 +397,7 @@ jobs:
- name: Run debugger tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testDebugger
working-directory: ${{ env.special-working-directory }}
@@ -367,13 +418,32 @@ jobs:
matrix:
# We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used,
# macOS runners are expensive, and we assume that Ubuntu is enough to cover the UNIX case.
- os: [ubuntu-latest, windows-latest]
+ include:
+ - os: windows-latest
+ vsix-target: win32-x64
+ - os: ubuntu-latest
+ vsix-target: linux-x64
+
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: ${{ env.special-working-directory-relative }}/python-env-tools
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Smoke tests
uses: ./.github/actions/smoke-tests
with:
node_version: ${{ env.NODE_VERSION }}
- artifact_name: ${{ needs.setup.outputs.vsix_artifact_name }}
+ artifact_name: ${{ needs.setup.outputs.vsix_artifact_name }}-${{ matrix.vsix-target }}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index d902a68878e0..5528fbbe9c0a 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -36,11 +36,13 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -65,4 +67,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@v4
diff --git a/.github/workflows/community-feedback-auto-comment.yml b/.github/workflows/community-feedback-auto-comment.yml
index cf3c4f51fe61..27f93400a023 100644
--- a/.github/workflows/community-feedback-auto-comment.yml
+++ b/.github/workflows/community-feedback-auto-comment.yml
@@ -12,7 +12,7 @@ jobs:
issues: write
steps:
- name: Check For Existing Comment
- uses: peter-evans/find-comment@v3
+ uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
id: finder
with:
issue-number: ${{ github.event.issue.number }}
@@ -21,7 +21,7 @@ jobs:
- name: Add Community Feedback Comment
if: steps.finder.outputs.comment-id == ''
- uses: peter-evans/create-or-update-comment@v4
+ uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
with:
issue-number: ${{ github.event.issue.number }}
body: |
diff --git a/.github/workflows/gen-issue-velocity.yml b/.github/workflows/gen-issue-velocity.yml
new file mode 100644
index 000000000000..41d79e4074d0
--- /dev/null
+++ b/.github/workflows/gen-issue-velocity.yml
@@ -0,0 +1,34 @@
+name: Issues Summary
+
+on:
+ schedule:
+ - cron: '0 0 * * 2' # Runs every Tuesday at midnight
+ workflow_dispatch:
+
+permissions:
+ issues: read
+
+jobs:
+ generate-summary:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '3.x'
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install requests
+
+ - name: Run summary script
+ run: python scripts/issue_velocity_summary_script.py
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/info-needed-closer.yml b/.github/workflows/info-needed-closer.yml
index 442799cd7a16..46892a58e800 100644
--- a/.github/workflows/info-needed-closer.yml
+++ b/.github/workflows/info-needed-closer.yml
@@ -6,21 +6,26 @@ on:
types: [trigger-needs-more-info]
workflow_dispatch:
+permissions:
+ issues: write
+
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: 'microsoft/vscode-github-triage-actions'
path: ./actions
+ persist-credentials: false
ref: stable
- name: Install Actions
run: npm install --production --prefix ./actions
- name: Run info-needed Closer
uses: ./actions/needs-more-info-closer
with:
+ token: ${{secrets.GITHUB_TOKEN}}
label: info-needed
closeDays: 30
closeComment: "Because we have not heard back with the information we requested, we are closing this issue for now. If you are able to provide the info later on, then we will be happy to re-open this issue to pick up where we left off. \n\nHappy Coding!"
diff --git a/.github/workflows/issue-labels.yml b/.github/workflows/issue-labels.yml
index 8b084aef409f..dcbd114086e2 100644
--- a/.github/workflows/issue-labels.yml
+++ b/.github/workflows/issue-labels.yml
@@ -5,7 +5,7 @@ on:
types: [opened, reopened]
env:
- TRIAGERS: '["karrtikr","karthiknadig","paulacamargo25","eleanorjboyd","anthonykim1"]'
+ TRIAGERS: '["karthiknadig","eleanorjboyd","anthonykim1"]'
permissions:
issues: write
@@ -17,11 +17,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: stable
path: ./actions
+ persist-credentials: false
- name: Install Actions
run: npm install --production --prefix ./actions
diff --git a/.github/workflows/lock-issues.yml b/.github/workflows/lock-issues.yml
index 47f243d71979..544d04ee185e 100644
--- a/.github/workflows/lock-issues.yml
+++ b/.github/workflows/lock-issues.yml
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Lock Issues'
- uses: dessant/lock-threads@v5
+ uses: dessant/lock-threads@7266a7ce5c1df01b1c6db85bf8cd86c737dadbe7 # v6.0.0
with:
github-token: ${{ github.token }}
issue-inactive-days: '30'
diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml
index 62dff5c876b3..c8a6f2dd416e 100644
--- a/.github/workflows/pr-check.yml
+++ b/.github/workflows/pr-check.yml
@@ -7,12 +7,13 @@ on:
- main
- release*
+permissions: {}
+
env:
- NODE_VERSION: 18.17.1
+ NODE_VERSION: 22.21.1
PYTHON_VERSION: '3.10' # YML treats 3.10 the number as 3.1, so quotes around 3.10
MOCHA_REPORTER_JUNIT: true # Use the mocha-multi-reporters and send output to both console (spec) and JUnit (mocha-junit-reporter). Also enables a reporter which exits the process running the tests if it haven't already.
ARTIFACT_NAME_VSIX: ms-python-insiders-vsix
- VSIX_NAME: ms-python-insiders.vsix
TEST_RESULTS_DIRECTORY: .
# Force a path with spaces and to test extension works in these scenarios
# Unicode characters are causing 2.7 failures so skip that for now.
@@ -22,24 +23,73 @@ env:
jobs:
build-vsix:
name: Create VSIX
- runs-on: ubuntu-latest
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - os: windows-latest
+ target: x86_64-pc-windows-msvc
+ vsix-target: win32-x64
+ - os: windows-latest
+ target: aarch64-pc-windows-msvc
+ vsix-target: win32-arm64
+ - os: ubuntu-latest
+ target: x86_64-unknown-linux-musl
+ vsix-target: linux-x64
+ # - os: ubuntu-latest
+ # target: aarch64-unknown-linux-gnu
+ # vsix-target: linux-arm64
+ # - os: ubuntu-latest
+ # target: arm-unknown-linux-gnueabihf
+ # vsix-target: linux-armhf
+ # - os: macos-latest
+ # target: x86_64-apple-darwin
+ # vsix-target: darwin-x64
+ # - os: macos-14
+ # target: aarch64-apple-darwin
+ # vsix-target: darwin-arm64
+ - os: ubuntu-latest
+ target: x86_64-unknown-linux-musl
+ vsix-target: alpine-x64
+ # - os: ubuntu-latest
+ # target: aarch64-unknown-linux-musl
+ # vsix-target: alpine-arm64
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: 'python-env-tools'
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Build VSIX
uses: ./.github/actions/build-vsix
with:
node_version: ${{ env.NODE_VERSION}}
- vsix_name: ${{ env.VSIX_NAME }}
- artifact_name: ${{ env.ARTIFACT_NAME_VSIX }}
+ vsix_name: 'ms-python-insiders-${{ matrix.vsix-target }}.vsix'
+ artifact_name: '${{ env.ARTIFACT_NAME_VSIX }}-${{ matrix.vsix-target }}'
+ cargo_target: ${{ matrix.target }}
+ vsix_target: ${{ matrix.vsix-target }}
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
- name: Lint
uses: ./.github/actions/lint
@@ -51,34 +101,47 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Use Python ${{ env.PYTHON_VERSION }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: 'python-env-tools'
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Install base Python requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- options: '-t ./pythonFiles/lib/python --no-cache-dir --implementation py'
+ options: '-t ./python_files/lib/python --no-cache-dir --implementation py'
- name: Install Jedi requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- requirements-file: './pythonFiles/jedilsp_requirements/requirements.txt'
- options: '-t ./pythonFiles/lib/jedilsp --no-cache-dir --implementation py'
+ requirements-file: './python_files/jedilsp_requirements/requirements.txt'
+ options: '-t ./python_files/lib/jedilsp --no-cache-dir --implementation py'
- name: Install other Python requirements
run: |
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Pyright
- uses: jakebailey/pyright-action@v2
+ uses: jakebailey/pyright-action@8ec14b5cfe41f26e5f41686a31eb6012758217ef # v3.0.2
with:
version: 1.1.308
- working-directory: 'pythonFiles'
+ working-directory: 'python_files'
python-tests:
name: Python Tests
@@ -94,30 +157,44 @@ jobs:
# macOS runners are expensive, and we assume that Ubuntu is enough to cover the Unix case.
os: [ubuntu-latest, windows-latest]
# Run the tests on the oldest and most recent versions of Python.
- python: ['3.8', '3.x', '3.12-dev']
+ python: ['3.10', '3.x', '3.13'] # run for 3 pytest versions, most recent stable, oldest version supported and pre-release
+ pytest-version: ['pytest', 'pytest@pre-release', 'pytest==6.2.0']
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
path: ${{ env.special-working-directory-relative }}
+ persist-credentials: false
- name: Use Python ${{ matrix.python }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
+ - name: Install specific pytest version
+ if: matrix.pytest-version == 'pytest@pre-release'
+ run: |
+ python -m pip install --pre pytest
+
+ - name: Install specific pytest version
+ if: matrix.pytest-version != 'pytest@pre-release'
+ run: |
+ python -m pip install "${{ matrix.pytest-version }}"
+
+ - name: Install specific pytest version
+ run: python -m pytest --version
- name: Install base Python requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ options: '-t "${{ env.special-working-directory-relative }}/python_files/lib/python" --no-cache-dir --implementation py'
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
- name: Run Python unit tests
- run: python pythonFiles/tests/run_all.py
+ run: python python_files/tests/run_all.py
tests:
name: Tests
@@ -138,12 +215,25 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
path: ${{ env.special-working-directory-relative }}
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: ${{ env.special-working-directory-relative }}/python-env-tools
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Install Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
@@ -159,44 +249,29 @@ jobs:
run: npx @vscode/l10n-dev@latest export ./src
- name: Use Python ${{ matrix.python }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- - name: Install debugpy
- run: |
- # We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
-
- - name: Download get-pip.py
- run: |
- python -m pip install wheel
- python -m pip install -r build/build-install-requirements.txt
- python ./pythonFiles/download_get_pip.py
- shell: bash
+ - name: Upgrade Pip
+ run: python -m pip install -U pip
- - name: Install base Python requirements
- uses: brettcannon/pip-secure-install@v1
- with:
- requirements-file: '"${{ env.special-working-directory-relative }}/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/python" --no-cache-dir --implementation py'
+ # For faster/better builds of sdists.
+ - name: Install build pre-requisite
+ run: python -m pip install wheel nox
- - name: Install Jedi requirements
- uses: brettcannon/pip-secure-install@v1
- with:
- requirements-file: '"${{ env.special-working-directory-relative }}/pythonFiles/jedilsp_requirements/requirements.txt"'
- options: '-t "${{ env.special-working-directory-relative }}/pythonFiles/lib/jedilsp" --no-cache-dir --implementation py'
+ - name: Install Python Extension dependencies (jedi, etc.)
+ run: nox --session install_python_libs
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
- - name: Install debugpy wheels (Python ${{ matrix.python }})
- run: |
- python -m pip install wheel
- python -m pip --disable-pip-version-check install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
+ - name: Rust Tool Chain setup
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Build Native Binaries
+ run: nox --session native_build
shell: bash
- if: matrix.test-suite == 'debugger'
- name: Install functional test requirements
run: python -m pip install --upgrade -r ./build/functional-test-requirements.txt
@@ -292,7 +367,7 @@ jobs:
env:
TEST_FILES_SUFFIX: testvirtualenvs
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testSingleWorkspace
working-directory: ${{ env.special-working-directory }}
@@ -301,7 +376,7 @@ jobs:
- name: Run single-workspace tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testSingleWorkspace
working-directory: ${{ env.special-working-directory }}
@@ -310,7 +385,7 @@ jobs:
- name: Run debugger tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testDebugger
working-directory: ${{ env.special-working-directory }}
@@ -321,6 +396,43 @@ jobs:
run: npm run test:functional
if: matrix.test-suite == 'functional'
+ native-tests:
+ name: Native Tests
+ # The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded.
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ working-directory: ${{ env.special-working-directory }}
+ strategy:
+ fail-fast: false
+ matrix:
+ # We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used,
+ # macOS runners are expensive, and we assume that Ubuntu is enough to cover the Unix case.
+ os: [ubuntu-latest, windows-latest]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v6
+ with:
+ path: ${{ env.special-working-directory-relative }}
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: ${{ env.special-working-directory-relative }}/python-env-tools
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
+
+ - name: Python Environment Tools tests
+ run: cargo test -- --nocapture
+ working-directory: ${{ env.special-working-directory }}/python-env-tools
+
smoke-tests:
name: Smoke tests
# The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded.
@@ -331,23 +443,45 @@ jobs:
matrix:
# We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used,
# macOS runners are expensive, and we assume that Ubuntu is enough to cover the UNIX case.
- os: [ubuntu-latest, windows-latest]
+ include:
+ - os: windows-latest
+ vsix-target: win32-x64
+ - os: ubuntu-latest
+ vsix-target: linux-x64
+
steps:
# Need the source to have the tests available.
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: python-env-tools
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Smoke tests
uses: ./.github/actions/smoke-tests
with:
node_version: ${{ env.NODE_VERSION }}
- artifact_name: ${{ env.ARTIFACT_NAME_VSIX }}
+ artifact_name: '${{ env.ARTIFACT_NAME_VSIX }}-${{ matrix.vsix-target }}'
### Coverage run
coverage:
name: Coverage
+ # TEMPORARILY DISABLED - hanging in CI, needs investigation
+ if: false
# The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded.
runs-on: ${{ matrix.os }}
+ needs: [lint, check-types, python-tests, tests, native-tests]
strategy:
fail-fast: false
matrix:
@@ -356,10 +490,24 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Checkout Python Environment Tools
+ uses: actions/checkout@v6
+ with:
+ repository: 'microsoft/python-environment-tools'
+ path: python-env-tools
+ persist-credentials: false
+ sparse-checkout: |
+ crates
+ Cargo.toml
+ Cargo.lock
+ sparse-checkout-cone-mode: false
- name: Install Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
@@ -374,31 +522,37 @@ jobs:
run: npx @vscode/l10n-dev@latest export ./src
- name: Use Python ${{ env.PYTHON_VERSION }}
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
cache-dependency-path: |
requirements.txt
- pythonFiles/jedilsp_requirements/requirements.txt
+ python_files/jedilsp_requirements/requirements.txt
build/test-requirements.txt
build/functional-test-requirements.txt
- name: Install base Python requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- options: '-t ./pythonFiles/lib/python --implementation py'
+ options: '-t ./python_files/lib/python --implementation py'
- name: Install Jedi requirements
- uses: brettcannon/pip-secure-install@v1
+ uses: brettcannon/pip-secure-install@92f400e3191171c1858cc0e0d9ac6320173fdb0c # v1.0.0
with:
- requirements-file: './pythonFiles/jedilsp_requirements/requirements.txt'
- options: '-t ./pythonFiles/lib/jedilsp --implementation py'
+ requirements-file: './python_files/jedilsp_requirements/requirements.txt'
+ options: '-t ./python_files/lib/jedilsp --implementation py'
- - name: Install debugpy
- run: |
- # We need to have debugpy so that tests relying on it keep passing, but we don't need install_debugpy's logic in the test phase.
- python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --implementation py --no-deps --upgrade --pre debugpy
+ - name: Install build pre-requisite
+ run: python -m pip install wheel nox
+ shell: bash
+
+ - name: Rust Tool Chain setup
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Build Native Binaries
+ run: nox --session native_build
+ shell: bash
- name: Install test requirements
run: python -m pip install --upgrade -r build/test-requirements.txt
@@ -474,7 +628,7 @@ jobs:
- name: Run Python unit tests
run: |
- python pythonFiles/tests/run_all.py
+ python python_files/tests/run_all.py
# The virtual environment based tests use the `testSingleWorkspace` set of tests
# with the environment variable `TEST_FILES_SUFFIX` set to `testvirtualenvs`,
@@ -487,7 +641,7 @@ jobs:
TEST_FILES_SUFFIX: testvirtualenvs
CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
CI_DISABLE_AUTO_SELECTION: 1
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testSingleWorkspace:cover
@@ -495,7 +649,7 @@ jobs:
env:
CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
CI_DISABLE_AUTO_SELECTION: 1
- uses: GabrielBB/xvfb-action@v1.6
+ uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
with:
run: npm run testSingleWorkspace:cover
@@ -504,7 +658,7 @@ jobs:
# env:
# CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
# CI_DISABLE_AUTO_SELECTION: 1
- # uses: GabrielBB/xvfb-action@v1.6
+ # uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
# with:
# run: npm run testMultiWorkspace:cover
@@ -513,7 +667,7 @@ jobs:
# env:
# CI_PYTHON_VERSION: ${{ env.PYTHON_VERSION }}
# CI_DISABLE_AUTO_SELECTION: 1
- # uses: GabrielBB/xvfb-action@v1.6
+ # uses: GabrielBB/xvfb-action@b706e4e27b14669b486812790492dc50ca16b465 # v1.7
# with:
# run: npm run testDebugger:cover
@@ -528,7 +682,7 @@ jobs:
run: npm run test:cover:report
- name: Upload HTML report
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v7
with:
name: ${{ runner.os }}-coverage-report-html
path: ./coverage
diff --git a/.github/workflows/pr-file-check.yml b/.github/workflows/pr-file-check.yml
index ba019c790e99..6364e5fa744e 100644
--- a/.github/workflows/pr-file-check.yml
+++ b/.github/workflows/pr-file-check.yml
@@ -3,21 +3,21 @@ name: PR files
on:
pull_request:
types:
- # On by default if you specify no types.
- 'opened'
- 'reopened'
- 'synchronize'
- # For `skip-label` only.
- 'labeled'
- 'unlabeled'
+permissions: {}
+
jobs:
changed-files-in-pr:
name: 'Check for changed files'
runs-on: ubuntu-latest
steps:
- name: 'package-lock.json matches package.json'
- uses: brettcannon/check-for-changed-files@v1.2.0
+ uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1
with:
prereq-pattern: 'package.json'
file-pattern: 'package-lock.json'
@@ -25,7 +25,7 @@ jobs:
failure-message: '${prereq-pattern} was edited but ${file-pattern} was not (the ${skip-label} label can be used to pass this check)'
- name: 'package.json matches package-lock.json'
- uses: brettcannon/check-for-changed-files@v1.2.0
+ uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1
with:
prereq-pattern: 'package-lock.json'
file-pattern: 'package.json'
@@ -33,7 +33,7 @@ jobs:
failure-message: '${prereq-pattern} was edited but ${file-pattern} was not (the ${skip-label} label can be used to pass this check)'
- name: 'Tests'
- uses: brettcannon/check-for-changed-files@v1.2.0
+ uses: brettcannon/check-for-changed-files@871d7b8b5917a4f6f06662e2262e8ffc51dff6d1 # v1.2.1
with:
prereq-pattern: src/**/*.ts
file-pattern: |
diff --git a/.github/workflows/pr-issue-check.yml b/.github/workflows/pr-issue-check.yml
new file mode 100644
index 000000000000..5587227d2848
--- /dev/null
+++ b/.github/workflows/pr-issue-check.yml
@@ -0,0 +1,31 @@
+name: PR issue check
+
+on:
+ pull_request:
+ types:
+ - 'opened'
+ - 'reopened'
+ - 'synchronize'
+ - 'labeled'
+ - 'unlabeled'
+
+permissions: {}
+
+jobs:
+ check-for-attached-issue:
+ name: 'Check for attached issue'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Ensure PR has an associated issue'
+ uses: actions/github-script@v9
+ with:
+ script: |
+ const labels = context.payload.pull_request.labels.map(label => label.name);
+ if (!labels.includes('skip-issue-check')) {
+ const prBody = context.payload.pull_request.body || '';
+ const issueLink = prBody.match(/https:\/\/github\.com\/\S+\/issues\/\d+/);
+ const issueReference = prBody.match(/#\d+/);
+ if (!issueLink && !issueReference) {
+ core.setFailed('No associated issue found in the PR description.');
+ }
+ }
diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml
index 730b8e5c5832..af24ac10772c 100644
--- a/.github/workflows/pr-labels.yml
+++ b/.github/workflows/pr-labels.yml
@@ -12,9 +12,12 @@ jobs:
classify:
name: 'Classify PR'
runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
steps:
- name: 'PR impact specified'
- uses: mheap/github-action-required-labels@v5
+ uses: mheap/github-action-required-labels@0ac283b4e65c1fb28ce6079dea5546ceca98ccbe # v5.5.2
with:
mode: exactly
count: 1
diff --git a/.github/workflows/python27-issue-response.yml b/.github/workflows/python27-issue-response.yml
index 4d51e9921ab4..9db84bca1a23 100644
--- a/.github/workflows/python27-issue-response.yml
+++ b/.github/workflows/python27-issue-response.yml
@@ -5,6 +5,8 @@ on:
jobs:
python27-issue-response:
runs-on: ubuntu-latest
+ permissions:
+ issues: write
if: "contains(github.event.issue.body, 'Python version (& distribution if applicable, e.g. Anaconda): 2.7')"
steps:
- name: Check for Python 2.7 string
diff --git a/.github/workflows/remove-needs-labels.yml b/.github/workflows/remove-needs-labels.yml
index 3d218e297a11..24352526d0d8 100644
--- a/.github/workflows/remove-needs-labels.yml
+++ b/.github/workflows/remove-needs-labels.yml
@@ -7,9 +7,11 @@ jobs:
classify:
name: 'Remove needs labels on issue closing'
runs-on: ubuntu-latest
+ permissions:
+ issues: write
steps:
- name: 'Removes needs labels on issue close'
- uses: actions-ecosystem/action-remove-labels@v1
+ uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.3.0
with:
labels: |
needs PR
diff --git a/.github/workflows/test-plan-item-validator.yml b/.github/workflows/test-plan-item-validator.yml
index 17f1740345f2..57db4a3e18a7 100644
--- a/.github/workflows/test-plan-item-validator.yml
+++ b/.github/workflows/test-plan-item-validator.yml
@@ -12,10 +12,11 @@ jobs:
if: contains(github.event.issue.labels.*.name, 'testplan-item') || contains(github.event.issue.labels.*.name, 'invalid-testplan-item')
steps:
- name: Checkout Actions
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: 'microsoft/vscode-github-triage-actions'
path: ./actions
+ persist-credentials: false
ref: stable
- name: Install Actions
diff --git a/.github/workflows/triage-info-needed.yml b/.github/workflows/triage-info-needed.yml
index 1ded54ea3f59..c7a37ba0c78d 100644
--- a/.github/workflows/triage-info-needed.yml
+++ b/.github/workflows/triage-info-needed.yml
@@ -7,20 +7,20 @@ on:
env:
TRIAGERS: '["karrtikr","karthiknadig","paulacamargo25","eleanorjboyd", "brettcannon","anthonykim1"]'
-permissions:
- issues: write
-
jobs:
add_label:
- runs-on: ubuntu-latest
if: contains(github.event.issue.labels.*.name, 'triage-needed') && !contains(github.event.issue.labels.*.name, 'info-needed')
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
steps:
- name: Checkout Actions
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: stable
path: ./actions
+ persist-credentials: false
- name: Install Actions
run: npm install --production --prefix ./actions
@@ -35,13 +35,16 @@ jobs:
remove_label:
if: contains(github.event.issue.labels.*.name, 'info-needed') && contains(github.event.issue.labels.*.name, 'triage-needed')
runs-on: ubuntu-latest
+ permissions:
+ issues: write
steps:
- name: Checkout Actions
- uses: actions/checkout@v4
+ uses: actions/checkout@v6
with:
repository: 'microsoft/vscode-github-triage-actions'
ref: stable
path: ./actions
+ persist-credentials: false
- name: Install Actions
run: npm install --production --prefix ./actions
diff --git a/.gitignore b/.gitignore
index 69166ccac1a4..2fa056f84fa6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,8 +23,8 @@ cucumber-report.json
**/.venv*/
port.txt
precommit.hook
-pythonFiles/lib/**
-pythonFiles/get-pip.py
+python_files/lib/**
+python_files/get-pip.py
debug_coverage*/**
languageServer/**
languageServer.*/**
@@ -48,3 +48,11 @@ dist/**
*.xlf
package.nls.*.json
l10n/
+python-env-tools/**
+# coverage files produced as test output
+python_files/tests/*/.data/.coverage*
+python_files/tests/*/.data/*/.coverage*
+src/testTestingRootWkspc/coverageWorkspace/.coverage
+
+# ignore ai artifacts generated and placed in this folder
+ai-artifacts/*
diff --git a/.nvmrc b/.nvmrc
index 860cc5000ae6..c6a66a6e6a68 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v18.17.1
+v22.21.1
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index 93a73827e7a2..15e6aada1d50 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -2,13 +2,11 @@
// See https://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
+ "charliermarsh.ruff",
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ms-python.python",
- "ms-python.black-formatter",
- "ms-python.vscode-pylance",
- "ms-python.isort",
- "ms-python.flake8"
+ "ms-python.vscode-pylance"
]
}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 82981a93305d..1e983413c8d4 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -8,7 +8,6 @@
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
- "stopOnEntry": false,
"smartStep": true,
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/out/**/*", "!${workspaceFolder}/**/node_modules**/*"],
@@ -31,19 +30,11 @@
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}", "${workspaceFolder}/data"],
- "stopOnEntry": false,
"smartStep": true,
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/out/**/*", "!${workspaceFolder}/**/node_modules**/*"],
"preLaunchTask": "Compile"
},
- {
- "name": "Python: Current File",
- "type": "python",
- "request": "launch",
- "program": "${file}",
- "console": "integratedTerminal"
- },
{
"name": "Tests (Debugger, VS Code, *.test.ts)",
"type": "extensionHost",
@@ -55,7 +46,6 @@
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test"
],
- "stopOnEntry": false,
"sourceMaps": true,
"smartStep": true,
"outFiles": ["${workspaceFolder}/out/**/*", "!${workspaceFolder}/**/node_modules**/*"],
@@ -83,7 +73,6 @@
"VSC_PYTHON_SMOKE_TEST": "1",
"TEST_FILES_SUFFIX": "smoke.test"
},
- "stopOnEntry": false,
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/out/**/*.js", "!${workspaceFolder}/**/node_modules**/*"],
"preLaunchTask": "Compile",
@@ -103,7 +92,6 @@
"env": {
"VSC_PYTHON_CI_TEST_GREP": "" // Modify this to run a subset of the single workspace tests
},
- "stopOnEntry": false,
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/out/**/*.js", "!${workspaceFolder}/**/node_modules**/*"],
"preLaunchTask": "Compile",
@@ -123,7 +111,6 @@
"env": {
"VSC_PYTHON_CI_TEST_GREP": "Language Server:"
},
- "stopOnEntry": false,
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/out/**/*.js", "!${workspaceFolder}/**/node_modules**/*"],
"preLaunchTask": "preTestJediLSP",
@@ -140,7 +127,9 @@
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test"
],
- "stopOnEntry": false,
+ "env": {
+ "VSC_PYTHON_CI_TEST_GREP": "" // Modify this to run a subset of the single workspace tests
+ },
"sourceMaps": true,
"smartStep": true,
"outFiles": ["${workspaceFolder}/out/**/*", "!${workspaceFolder}/**/node_modules**/*"],
@@ -236,11 +225,11 @@
"program": "${file}",
"request": "launch",
"skipFiles": ["/**"],
- "type": "pwa-node"
+ "type": "node"
},
{
"name": "Python: Current File",
- "type": "python",
+ "type": "debugpy",
"justMyCode": true,
"request": "launch",
"program": "${file}",
@@ -248,8 +237,8 @@
"cwd": "${workspaceFolder}"
},
{
- "name": "Listen",
- "type": "python",
+ "name": "Python: Attach Listen",
+ "type": "debugpy",
"request": "attach",
"listen": { "host": "localhost", "port": 5678 },
"justMyCode": true
@@ -257,17 +246,17 @@
{
"name": "Debug pytest plugin tests",
- "type": "python",
+ "type": "debugpy",
"request": "launch",
"module": "pytest",
- "args": ["${workspaceFolder}/pythonFiles/tests/pytestadapter"],
+ "args": ["${workspaceFolder}/python_files/tests/pytestadapter"],
"justMyCode": true
}
],
"compounds": [
{
- "name": "Debug Test Discovery",
- "configurations": ["Listen", "Extension"]
+ "name": "Debug Python and Extension",
+ "configurations": ["Python: Attach Listen", "Extension"]
}
]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 50864f0b5cd8..01de0d907706 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -28,7 +28,11 @@
"source.fixAll.eslint": "explicit",
"source.organizeImports.isort": "explicit"
},
- "editor.defaultFormatter": "ms-python.black-formatter",
+ "editor.defaultFormatter": "charliermarsh.ruff",
+ },
+ "[rust]": {
+ "editor.defaultFormatter": "rust-lang.rust-analyzer",
+ "editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
@@ -64,8 +68,11 @@
// Open merge editor for resolving conflicts.
"git.mergeEditor": true,
"python.testing.pytestArgs": [
- "pythonFiles/tests"
+ "python_files/tests"
],
"python.testing.unittestEnabled": false,
- "python.testing.pytestEnabled": true
+ "python.testing.pytestEnabled": true,
+ "rust-analyzer.linkedProjects": [
+ ".\\python-env-tools\\Cargo.toml"
+ ]
}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index e1468bdfc2ad..c5a054ed43cf 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -12,9 +12,7 @@
"type": "npm",
"script": "compile",
"isBackground": true,
- "problemMatcher": [
- "$tsc-watch"
- ],
+ "problemMatcher": ["$tsc-watch"],
"group": {
"kind": "build",
"isDefault": true
@@ -34,6 +32,31 @@
"script": "preTestJediLSP",
"problemMatcher": [],
"label": "preTestJediLSP"
+ },
+ {
+ "type": "npm",
+ "script": "check-python",
+ "problemMatcher": ["$python"],
+ "label": "npm: check-python",
+ "detail": "npm run check-python:ruff && npm run check-python:pyright"
+ },
+ {
+ "label": "npm: check-python (venv)",
+ "type": "shell",
+ "command": "bash",
+ "args": ["-lc", "source .venv/bin/activate && npm run check-python"],
+ "problemMatcher": [],
+ "detail": "Activates the repo .venv first (avoids pyenv/shim Python) then runs: npm run check-python",
+ "windows": {
+ "command": "pwsh",
+ "args": [
+ "-NoProfile",
+ "-ExecutionPolicy",
+ "Bypass",
+ "-Command",
+ ".\\.venv\\Scripts\\Activate.ps1; npm run check-python"
+ ]
+ }
}
]
}
diff --git a/.vscodeignore b/.vscodeignore
index 6788f9b6d8e1..d636ab48f361 100644
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -1,12 +1,15 @@
**/*.map
**/*.analyzer.html
+**/.env
*.vsix
.editorconfig
.env
.eslintrc
+.eslintignore
.gitattributes
.gitignore
.gitmodules
+.git*
.npmrc
.nvmrc
.nycrc
@@ -21,10 +24,13 @@ test.ipynb
tsconfig*.json
tsfmt.json
vscode-python-signing.*
+noxfile.py
+.config/**
.github/**
.mocha-reporter/**
.nvm/**
+.nox/**
.nyc_output
.prettierrc.js
.sonarcloud.properties
@@ -51,19 +57,33 @@ obj/**
out/**/*.stats.json
out/client/**/*.analyzer.html
out/coverconfig.json
-out/pythonFiles/**
+out/python_files/**
out/src/**
out/test/**
out/testMultiRootWkspc/**
precommit.hook
-pythonFiles/**/*.pyc
-pythonFiles/lib/**/*.egg-info/**
-pythonFiles/lib/python/bin/**
-pythonFiles/jedilsp_requirements/**
-pythonFiles/tests/**
+python_files/**/*.pyc
+python_files/lib/**/*.egg-info/**
+python_files/lib/jedilsp/bin/**
+python_files/lib/python/bin/**
+python_files/tests/**
scripts/**
src/**
test/**
tmp/**
typings/**
types/**
+**/__pycache__/**
+**/.devcontainer/**
+
+python-env-tools/.gitignore
+python-env-tools/bin/.gitignore
+python-env-tools/.github/**
+python-env-tools/.vscode/**
+python-env-tools/crates/**
+python-env-tools/target/**
+python-env-tools/Cargo.*
+python-env-tools/.cargo/**
+
+python-env-tools/**/*.md
+pythonExtensionApi/**
diff --git a/README.md b/README.md
index 3a56a09f73ed..e9dd52a538cd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Python extension for Visual Studio Code
-A [Visual Studio Code](https://code.visualstudio.com/) [extension](https://marketplace.visualstudio.com/VSCode) with rich support for the [Python language](https://www.python.org/) (for all [actively supported versions](https://devguide.python.org/#status-of-python-branches) of the language: >=3.7), including features such as IntelliSense (Pylance), linting, debugging (Python Debugger), code navigation, code formatting, refactoring, variable explorer, test explorer, and more!
+A [Visual Studio Code](https://code.visualstudio.com/) [extension](https://marketplace.visualstudio.com/VSCode) with rich support for the [Python language](https://www.python.org/) (for all [actively supported Python versions](https://devguide.python.org/versions/#supported-versions)), providing access points for extensions to seamlessly integrate and offer support for IntelliSense (Pylance), debugging (Python Debugger), formatting, linting, code navigation, refactoring, variable explorer, test explorer, environment management (**NEW** Python Environments Extension).
## Support for [vscode.dev](https://vscode.dev/)
@@ -9,13 +9,35 @@ The Python extension does offer [some support](https://github.com/microsoft/vsco
## Installed extensions
-The Python extension will automatically install the [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) extension to give you the best experience when working with Python files. However, Pylance is an optional dependency, meaning the Python extension will remain fully functional if it fails to be installed. You can also [uninstall](https://code.visualstudio.com/docs/editor/extension-marketplace#_uninstall-an-extension) it at the expense of some features if youβre using a different language server.
+The Python extension will automatically install the following extensions by default to provide the best Python development experience in VS Code:
-Extensions installed through the marketplace are subject to the [Marketplace Terms of Use](https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio-Marketplace-Terms-of-Use.pdf).
+- [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) β performant Python language support
+- [Python Debugger](https://marketplace.visualstudio.com/items?itemName=ms-python.debugpy) β seamless debug experience with debugpy
+- **(NEW)** [Python Environments](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-python-envs) β dedicated environment management (see below)
+
+These extensions are optional dependencies, meaning the Python extension will remain fully functional if they fail to be installed. Any or all of these extensions can be [disabled](https://code.visualstudio.com/docs/editor/extension-marketplace#_disable-an-extension) or [uninstalled](https://code.visualstudio.com/docs/editor/extension-marketplace#_uninstall-an-extension) at the expense of some features. Extensions installed through the marketplace are subject to the [Marketplace Terms of Use](https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio-Marketplace-Terms-of-Use.pdf).
+
+### About the Python Environments Extension
+
+You may now see that the **Python Environments Extension** is installed for you, but it may or may not be "enabled" in your VS Code experience. Enablement is controlled by the setting `"python.useEnvironmentsExtension": true` (or `false`).
+
+- If you set this setting to `true`, you will manually opt in to using the Python Environments Extension for environment management.
+- If you do not have this setting specified, you may be randomly assigned to have it turned on as we roll it out until it becomes the default experience for all users.
+
+The Python Environments Extension is still under active development and experimentation. Its goal is to provide a dedicated view and improved workflows for creating, deleting, and switching between Python environments, as well as managing packages. If you have feedback, please let us know via [issues](https://github.com/microsoft/vscode-python/issues).
+
+## Extensibility
+
+The Python extension provides pluggable access points for extensions that extend various feature areas to further improve your Python development experience. These extensions are all optional and depend on your project configuration and preferences.
+
+- [Python formatters](https://code.visualstudio.com/docs/python/formatting#_choose-a-formatter)
+- [Python linters](https://code.visualstudio.com/docs/python/linting#_choose-a-linter)
+
+If you encounter issues with any of the listed extensions, please file an issue in its corresponding repo.
## Quick start
-- **Step 1.** [Install a supported version of Python on your system](https://code.visualstudio.com/docs/python/python-tutorial#_prerequisites) (note: that the system install of Python on macOS is not supported).
+- **Step 1.** [Install a supported version of Python on your system](https://code.visualstudio.com/docs/python/python-tutorial#_prerequisites) (note: the system install of Python on macOS is not supported).
- **Step 2.** [Install the Python extension for Visual Studio Code](https://code.visualstudio.com/docs/editor/extension-gallery).
- **Step 3.** Open or create a Python file and start coding!
@@ -58,9 +80,8 @@ Open the Command Palette (Command+Shift+P on macOS and Ctrl+Shift+P on Windows/L
| Command | Description |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Python: Select Interpreter` | Switch between Python interpreters, versions, and environments. |
-| `Python: Start REPL` | Start an interactive Python REPL using the selected interpreter in the VS Code terminal. |
+| `Python: Start Terminal REPL` | Start an interactive Python REPL using the selected interpreter in the VS Code terminal. |
| `Python: Run Python File in Terminal` | Runs the active Python file in the VS Code terminal. You can also run a Python file by right-clicking on the file and selecting `Run Python File in Terminal`. |
-| `Format Document` | Formats code using the provided [formatter](https://code.visualstudio.com/docs/python/formatting) in the `settings.json` file. |
| `Python: Configure Tests` | Select a test framework and configure it to display the Test Explorer. |
To see all available Python commands, open the Command Palette and type `Python`. For Jupyter extension commands, just type `Jupyter`.
@@ -69,13 +90,13 @@ To see all available Python commands, open the Command Palette and type `Python`
Learn more about the rich features of the Python extension:
-- [IntelliSense](https://code.visualstudio.com/docs/python/editing#_autocomplete-and-intellisense): Edit your code with auto-completion, code navigation, syntax checking and more
-- [Linting](https://code.visualstudio.com/docs/python/linting): Get additional code analysis with Pylint, Flake8 and more
-- [Code formatting](https://code.visualstudio.com/docs/python/formatting): Format your code with black, autopep or yapf
-- [Debugging](https://code.visualstudio.com/docs/python/debugging): Debug your Python scripts, web apps, remote or multi-threaded processes
+- [IntelliSense](https://code.visualstudio.com/docs/python/editing#_autocomplete-and-intellisense): Edit your code with auto-completion, code navigation, syntax checking and more.
+- [Linting](https://code.visualstudio.com/docs/python/linting): Get additional code analysis with Pylint, Flake8 and more.
+- [Code formatting](https://code.visualstudio.com/docs/python/formatting): Format your code with black, autopep or yapf.
+- [Debugging](https://code.visualstudio.com/docs/python/debugging): Debug your Python scripts, web apps, remote or multi-threaded processes.
- [Testing](https://code.visualstudio.com/docs/python/unit-testing): Run and debug tests through the Test Explorer with unittest or pytest.
-- [Jupyter Notebooks](https://code.visualstudio.com/docs/python/jupyter-support): Create and edit Jupyter Notebooks, add and run code cells, render plots, visualize variables through the variable explorer, visualize dataframes with the data viewer, and more
-- [Environments](https://code.visualstudio.com/docs/python/environments): Automatically activate and switch between virtualenv, venv, pipenv, conda and pyenv environments
+- [Jupyter Notebooks](https://code.visualstudio.com/docs/python/jupyter-support): Create and edit Jupyter Notebooks, add and run code cells, render plots, visualize variables through the variable explorer, visualize dataframes with the data viewer, and more.
+- [Environments](https://code.visualstudio.com/docs/python/environments): Automatically activate and switch between virtualenv, venv, pipenv, conda and pyenv environments.
- [Refactoring](https://code.visualstudio.com/docs/python/editing#_refactoring): Restructure your Python code with variable extraction and method extraction. Additionally, there is componentized support to enable additional refactoring, such as import sorting, through extensions including [isort](https://marketplace.visualstudio.com/items?itemName=ms-python.isort) and [Ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff).
@@ -86,13 +107,13 @@ The extension is available in multiple languages: `de`, `en`, `es`, `fa`, `fr`,
## Questions, issues, feature requests, and contributions
-- If you have a question about how to accomplish something with the extension, please [ask on Stack Overflow](https://stackoverflow.com/questions/tagged/visual-studio-code+python)
-- If you come across a problem with the extension, please [file an issue](https://github.com/microsoft/vscode-python)
-- Contributions are always welcome! Please see our [contributing guide](https://github.com/Microsoft/vscode-python/blob/main/CONTRIBUTING.md) for more details
+- If you have a question about how to accomplish something with the extension, please [ask on our Discussions page](https://github.com/microsoft/vscode-python/discussions/categories/q-a).
+- If you come across a problem with the extension, please [file an issue](https://github.com/microsoft/vscode-python).
+- Contributions are always welcome! Please see our [contributing guide](https://github.com/Microsoft/vscode-python/blob/main/CONTRIBUTING.md) for more details.
- Any and all feedback is appreciated and welcome!
- - If someone has already [filed an issue](https://github.com/Microsoft/vscode-python) that encompasses your feedback, please leave a π/π reaction on the issue
- - Otherwise please start a [new discussion](https://github.com/microsoft/vscode-python/discussions/categories/ideas)
-- If you're interested in the development of the extension, you can read about our [development process](https://github.com/Microsoft/vscode-python/blob/main/CONTRIBUTING.md#development-process)
+ - If someone has already [filed an issue](https://github.com/Microsoft/vscode-python) that encompasses your feedback, please leave a π/π reaction on the issue.
+ - Otherwise please start a [new discussion](https://github.com/microsoft/vscode-python/discussions/categories/ideas).
+- If you're interested in the development of the extension, you can read about our [development process](https://github.com/Microsoft/vscode-python/blob/main/CONTRIBUTING.md#development-process).
## Data and telemetry
@@ -100,6 +121,6 @@ The Microsoft Python Extension for Visual Studio Code collects usage
data and sends it to Microsoft to help improve our products and
services. Read our
[privacy statement](https://privacy.microsoft.com/privacystatement) to
-learn more. This extension respects the `telemetry.enableTelemetry`
+learn more. This extension respects the `telemetry.telemetryLevel`
setting which you can learn more about at
https://code.visualstudio.com/docs/supporting/faq#_how-to-disable-telemetry-reporting.
diff --git a/build/azure-pipeline.pre-release.yml b/build/azure-pipeline.pre-release.yml
index bb52f983d02e..c300039f4ef4 100644
--- a/build/azure-pipeline.pre-release.yml
+++ b/build/azure-pipeline.pre-release.yml
@@ -29,53 +29,130 @@ extends:
parameters:
publishExtension: ${{ parameters.publishExtension }}
ghCreateTag: false
+ standardizedVersioning: true
l10nSourcePaths: ./src/client
+
+ buildPlatforms:
+ - name: Linux
+ vsceTarget: 'web'
+ - name: Linux
+ packageArch: arm64
+ vsceTarget: linux-arm64
+ - name: Linux
+ packageArch: arm
+ vsceTarget: linux-armhf
+ - name: Linux
+ packageArch: x64
+ vsceTarget: linux-x64
+ - name: Linux
+ packageArch: arm64
+ vsceTarget: alpine-arm64
+ - name: Linux
+ packageArch: x64
+ vsceTarget: alpine-x64
+ - name: MacOS
+ packageArch: arm64
+ vsceTarget: darwin-arm64
+ - name: MacOS
+ packageArch: x64
+ vsceTarget: darwin-x64
+ - name: Windows
+ packageArch: arm
+ vsceTarget: win32-arm64
+ - name: Windows
+ packageArch: x64
+ vsceTarget: win32-x64
+
buildSteps:
- task: NodeTool@0
inputs:
- versionSpec: '18.17.1'
+ versionSpec: '22.17.0'
displayName: Select Node version
- task: UsePythonVersion@0
inputs:
- versionSpec: '3.8'
+ versionSpec: '3.10'
addToPath: true
architecture: 'x64'
displayName: Select Python version
- - script: npm ci
- displayName: Install NPM dependencies
-
- script: python -m pip install -U pip
displayName: Upgrade pip
- - script: python -m pip install wheel
- displayName: Install wheel
-
- - script: |
- python -m pip --disable-pip-version-check install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
- python ./pythonFiles/download_get_pip.py
- displayName: Install debugpy and get-pip.py
+ - script: python -m pip install wheel nox
+ displayName: Install wheel and nox
- - script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --implementation py -r ./requirements.txt
- displayName: Install Python dependencies
-
- - script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/jedilsp --implementation py --platform any --abi none -r ./pythonFiles/jedilsp_requirements/requirements.txt
- displayName: Install Jedi Language Server
+ - script: npm ci
+ displayName: Install NPM dependencies
- - script: |
- python ./build/update_ext_version.py --for-publishing
- displayName: Update build number
+ - script: nox --session install_python_libs
+ displayName: Install Jedi, get-pip, etc
- - script: |
- python ./build/update_package_file.py
+ - script: python ./build/update_package_file.py
displayName: Update telemetry in package.json
- script: npm run addExtensionPackDependencies
displayName: Update optional extension dependencies
- - script: gulp prePublishBundle
+ - script: npx gulp prePublishBundle
displayName: Build
+
+ - bash: |
+ mkdir -p $(Build.SourcesDirectory)/python-env-tools/bin
+ chmod +x $(Build.SourcesDirectory)/python-env-tools/bin
+ displayName: Make Directory for python-env-tool binary
+
+ - bash: |
+ if [ "$(vsceTarget)" == "win32-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-pc-windows-msvc"
+ elif [ "$(vsceTarget)" == "win32-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-pc-windows-msvc"
+ elif [ "$(vsceTarget)" == "linux-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ elif [ "$(vsceTarget)" == "linux-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-unknown-linux-gnu"
+ elif [ "$(vsceTarget)" == "linux-armhf" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]armv7-unknown-linux-gnueabihf"
+ elif [ "$(vsceTarget)" == "darwin-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-apple-darwin"
+ elif [ "$(vsceTarget)" == "darwin-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-apple-darwin"
+ elif [ "$(vsceTarget)" == "alpine-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ elif [ "$(vsceTarget)" == "alpine-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-unknown-linux-gnu"
+ elif [ "$(vsceTarget)" == "web" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ else
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ fi
+ displayName: Set buildTarget variable
+
+ - task: DownloadPipelineArtifact@2
+ inputs:
+ buildType: 'specific'
+ project: 'Monaco'
+ definition: 591
+ buildVersionToDownload: 'latest'
+ branchName: 'refs/heads/main'
+ targetPath: '$(Build.SourcesDirectory)/python-env-tools/bin'
+ artifactName: 'bin-$(buildTarget)'
+ itemPattern: |
+ pet.exe
+ pet
+ ThirdPartyNotices.txt
+
+ - bash: |
+ ls -lf ./python-env-tools/bin
+ chmod +x ./python-env-tools/bin/pet*
+ ls -lf ./python-env-tools/bin
+ displayName: Set chmod for pet binary
+
+ - script: python -c "import shutil; shutil.rmtree('.nox', ignore_errors=True)"
+ displayName: Clean up Nox
+
+ tsa:
+ config:
+ areaPath: 'Visual Studio Code Python Extensions'
+ serviceTreeID: '6e6194bc-7baa-4486-86d0-9f5419626d46'
+ enabled: true
diff --git a/build/azure-pipeline.stable.yml b/build/azure-pipeline.stable.yml
index 02f8bd38cf81..024417da0e00 100644
--- a/build/azure-pipeline.stable.yml
+++ b/build/azure-pipeline.stable.yml
@@ -25,65 +25,129 @@ extends:
parameters:
publishExtension: ${{ parameters.publishExtension }}
l10nSourcePaths: ./src/client
+
+ buildPlatforms:
+ - name: Linux
+ vsceTarget: 'web'
+ - name: Linux
+ packageArch: arm64
+ vsceTarget: linux-arm64
+ - name: Linux
+ packageArch: arm
+ vsceTarget: linux-armhf
+ - name: Linux
+ packageArch: x64
+ vsceTarget: linux-x64
+ - name: Linux
+ packageArch: arm64
+ vsceTarget: alpine-arm64
+ - name: Linux
+ packageArch: x64
+ vsceTarget: alpine-x64
+ - name: MacOS
+ packageArch: arm64
+ vsceTarget: darwin-arm64
+ - name: MacOS
+ packageArch: x64
+ vsceTarget: darwin-x64
+ - name: Windows
+ packageArch: arm
+ vsceTarget: win32-arm64
+ - name: Windows
+ packageArch: x64
+ vsceTarget: win32-x64
+
buildSteps:
- task: NodeTool@0
inputs:
- versionSpec: '18.17.1'
+ versionSpec: '22.17.0'
displayName: Select Node version
- task: UsePythonVersion@0
inputs:
- versionSpec: '3.8'
+ versionSpec: '3.10'
addToPath: true
architecture: 'x64'
displayName: Select Python version
- - script: npm ci
- displayName: Install NPM dependencies
-
- script: python -m pip install -U pip
displayName: Upgrade pip
- - script: python -m pip install wheel
- displayName: Install wheel
-
- - script: |
- python -m pip --disable-pip-version-check install -r build/build-install-requirements.txt
- python ./pythonFiles/install_debugpy.py
- python ./pythonFiles/download_get_pip.py
- displayName: Install debugpy and get-pip.py
+ - script: python -m pip install wheel nox
+ displayName: Install wheel and nox
- - script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --implementation py -r ./requirements.txt
- displayName: Install Python dependencies
-
- - script: |
- python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/jedilsp --implementation py --platform any --abi none -r ./pythonFiles/jedilsp_requirements/requirements.txt
- displayName: Install Jedi Language Server
+ - script: npm ci
+ displayName: Install NPM dependencies
- - script: |
- python ./build/update_ext_version.py --release --for-publishing
- displayName: Update build number
+ - script: nox --session install_python_libs
+ displayName: Install Jedi, get-pip, etc
- - script: |
- python ./build/update_package_file.py
+ - script: python ./build/update_package_file.py
displayName: Update telemetry in package.json
- script: npm run addExtensionPackDependencies
displayName: Update optional extension dependencies
- - script: gulp prePublishBundle
+ - script: npx gulp prePublishBundle
displayName: Build
+
+ - bash: |
+ mkdir -p $(Build.SourcesDirectory)/python-env-tools/bin
+ chmod +x $(Build.SourcesDirectory)/python-env-tools/bin
+ displayName: Make Directory for python-env-tool binary
+
+ - bash: |
+ if [ "$(vsceTarget)" == "win32-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-pc-windows-msvc"
+ elif [ "$(vsceTarget)" == "win32-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-pc-windows-msvc"
+ elif [ "$(vsceTarget)" == "linux-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ elif [ "$(vsceTarget)" == "linux-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-unknown-linux-gnu"
+ elif [ "$(vsceTarget)" == "linux-armhf" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]armv7-unknown-linux-gnueabihf"
+ elif [ "$(vsceTarget)" == "darwin-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-apple-darwin"
+ elif [ "$(vsceTarget)" == "darwin-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-apple-darwin"
+ elif [ "$(vsceTarget)" == "alpine-x64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ elif [ "$(vsceTarget)" == "alpine-arm64" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]aarch64-unknown-linux-gnu"
+ elif [ "$(vsceTarget)" == "web" ]; then
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ else
+ echo "##vso[task.setvariable variable=buildTarget]x86_64-unknown-linux-musl"
+ fi
+ displayName: Set buildTarget variable
+
+ - task: DownloadPipelineArtifact@2
+ inputs:
+ buildType: 'specific'
+ project: 'Monaco'
+ definition: 593
+ buildVersionToDownload: 'latestFromBranch'
+ branchName: 'refs/heads/release/2026.4'
+ targetPath: '$(Build.SourcesDirectory)/python-env-tools/bin'
+ artifactName: 'bin-$(buildTarget)'
+ itemPattern: |
+ pet.exe
+ pet
+ ThirdPartyNotices.txt
+
+ - bash: |
+ ls -lf ./python-env-tools/bin
+ chmod +x ./python-env-tools/bin/pet*
+ ls -lf ./python-env-tools/bin
+ displayName: Set chmod for pet binary
+
+ - script: python -c "import shutil; shutil.rmtree('.nox', ignore_errors=True)"
+ displayName: Clean up Nox
tsa:
- enabled: true
- options:
- codebaseName: 'devdiv_$(Build.Repository.Name)'
- serviceTreeID: '6e6194bc-7baa-4486-86d0-9f5419626d46'
- instanceUrl: 'https://devdiv.visualstudio.com/defaultcollection'
- projectName: 'DevDiv'
- areaPath: "DevDiv\\VS Code (compliance tracking only)\\Visual Studio Code Python Extensions"
- notificationAliases:
- - 'stbatt@microsoft.com'
- - 'lszomoru@microsoft.com'
- - 'brcan@microsoft.com'
- - 'kanadig@microsoft.com'
+ config:
+ areaPath: 'Visual Studio Code Python Extensions'
+ serviceTreeID: '6e6194bc-7baa-4486-86d0-9f5419626d46'
+ enabled: true
+ apiScanDependentPipelineId: '593' # python-environment-tools
+ apiScanSoftwareVersion: '2024'
diff --git a/build/azure-pipelines/pipeline.yml b/build/azure-pipelines/pipeline.yml
index adb2fa5d1c30..0796e38ca598 100644
--- a/build/azure-pipelines/pipeline.yml
+++ b/build/azure-pipelines/pipeline.yml
@@ -37,13 +37,13 @@ extends:
testPlatforms:
- name: Linux
nodeVersions:
- - 18.17.1
+ - 22.21.1
- name: MacOS
nodeVersions:
- - 18.17.1
+ - 22.21.1
- name: Windows
nodeVersions:
- - 18.17.1
+ - 22.21.1
testSteps:
- template: /build/azure-pipelines/templates/test-steps.yml@self
parameters:
diff --git a/build/ci/addEnvPath.py b/build/ci/addEnvPath.py
index abad9ec3b5c9..66eff2a7b25d 100644
--- a/build/ci/addEnvPath.py
+++ b/build/ci/addEnvPath.py
@@ -3,7 +3,8 @@
#Adds the virtual environment's executable path to json file
-import json,sys
+import json
+import sys
import os.path
jsonPath = sys.argv[1]
key = sys.argv[2]
diff --git a/build/ci/conda_env_1.yml b/build/ci/conda_env_1.yml
index e9d08d0820a4..e3230ad0096e 100644
--- a/build/ci/conda_env_1.yml
+++ b/build/ci/conda_env_1.yml
@@ -1,4 +1,4 @@
name: conda_env_1
dependencies:
- - python=3.8
+ - python=3.10
- pip
diff --git a/build/ci/conda_env_2.yml b/build/ci/conda_env_2.yml
index 80b946c3cc14..38f551da2580 100644
--- a/build/ci/conda_env_2.yml
+++ b/build/ci/conda_env_2.yml
@@ -1,4 +1,4 @@
name: conda_env_2
dependencies:
- - python=3.8
+ - python=3.10
- pip
diff --git a/build/ci/scripts/spec_with_pid.js b/build/ci/scripts/spec_with_pid.js
index 9815feaac76a..a8453353aa79 100644
--- a/build/ci/scripts/spec_with_pid.js
+++ b/build/ci/scripts/spec_with_pid.js
@@ -98,5 +98,6 @@ Spec.description = 'hierarchical & verbose [default]';
* Expose `Spec`.
*/
+// eslint-disable-next-line no-global-assign
exports = Spec;
module.exports = exports;
diff --git a/build/existingFiles.json b/build/existingFiles.json
index 1f5acc727d8e..48ab84ff565d 100644
--- a/build/existingFiles.json
+++ b/build/existingFiles.json
@@ -500,7 +500,7 @@
"src/test/providers/shebangCodeLenseProvider.test.ts",
"src/test/providers/symbolProvider.unit.test.ts",
"src/test/providers/terminal.unit.test.ts",
- "src/test/pythonFiles/formatting/dummy.ts",
+ "src/test/python_files/formatting/dummy.ts",
"src/test/refactor/extension.refactor.extract.method.test.ts",
"src/test/refactor/extension.refactor.extract.var.test.ts",
"src/test/refactor/rename.test.ts",
diff --git a/build/functional-test-requirements.txt b/build/functional-test-requirements.txt
index d45208f671f4..5c3a9e3116ed 100644
--- a/build/functional-test-requirements.txt
+++ b/build/functional-test-requirements.txt
@@ -1,3 +1,5 @@
# List of requirements for functional tests
versioneer
numpy
+pytest
+pytest-cov
diff --git a/build/license-header.txt b/build/license-header.txt
index 2a8122642cb2..2970b03d7a1c 100644
--- a/build/license-header.txt
+++ b/build/license-header.txt
@@ -1,7 +1,7 @@
PLEASE NOTE: This is the license for the Python extension for Visual Studio Code. The Python extension automatically installs other extensions as optional dependencies, which can be uninstalled at any time. These extensions have separate licenses:
- - The Jupyter extension is released under an MIT License:
- https://marketplace.visualstudio.com/items/ms-toolsai.jupyter/license
+ - The Python Debugger extension is released under an MIT License:
+ https://marketplace.visualstudio.com/items/ms-python.debugpy/license
- The Pylance extension is only available in binary form and is released under a Microsoft proprietary license, the terms of which are available here:
https://marketplace.visualstudio.com/items/ms-python.vscode-pylance/license
diff --git a/build/test-requirements.txt b/build/test-requirements.txt
index 0650e86fb3d3..ff9afdfc8a2e 100644
--- a/build/test-requirements.txt
+++ b/build/test-requirements.txt
@@ -12,6 +12,8 @@ flask
fastapi
uvicorn
django
+testscenarios
+testtools
# Integrated TensorBoard tests
tensorboard
@@ -19,3 +21,22 @@ torch-tb-profiler
# extension build tests
freezegun
+
+# testing custom pytest plugin require the use of named pipes
+namedpipe; platform_system == "Windows"
+
+# typing for Django files
+django-stubs
+
+coverage
+pytest-cov
+pytest-json
+pytest-timeout
+
+
+# for pytest-describe related tests
+pytest-describe
+
+# for pytest-ruff related tests
+pytest-ruff
+pytest-black
diff --git a/build/update_ext_version.py b/build/update_ext_version.py
index 6ac2b15bbf0f..6d709ae05f7f 100644
--- a/build/update_ext_version.py
+++ b/build/update_ext_version.py
@@ -86,7 +86,7 @@ def main(package_json: pathlib.Path, argv: Sequence[str]) -> None:
raise ValueError(
f"Major version [{major}] must be the current year [{current_year}].",
f"If changing major version after new year's, change to {current_year}.1.0",
- f"Minor version must be updated based on release or pre-release channel.",
+ "Minor version must be updated based on release or pre-release channel.",
)
if args.release and not is_even(minor):
@@ -102,9 +102,7 @@ def main(package_json: pathlib.Path, argv: Sequence[str]) -> None:
if args.build_id:
# If build id is provided it should fall within the 0-INT32 max range
# that the max allowed value for publishing to the Marketplace.
- if args.build_id < 0 or (
- args.for_publishing and args.build_id > ((2**32) - 1)
- ):
+ if args.build_id < 0 or (args.for_publishing and args.build_id > ((2**32) - 1)):
raise ValueError(f"Build ID must be within [0, {(2**32) - 1}]")
package["version"] = ".".join((major, minor, str(args.build_id)))
diff --git a/data/.vscode/settings.json b/data/.vscode/settings.json
deleted file mode 100644
index 6f329d0777a4..000000000000
--- a/data/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "python.defaultInterpreterPath": "/usr/bin/python3"
-}
diff --git a/data/test.py b/data/test.py
deleted file mode 100644
index 3b316dc1e8d1..000000000000
--- a/data/test.py
+++ /dev/null
@@ -1,2 +0,0 @@
-#%%
-print('hello')
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 000000000000..8e1aa990a2c2
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,393 @@
+/**
+ * ESLint Configuration for VS Code Python Extension
+ * This file configures linting rules for the TypeScript/JavaScript codebase.
+ * It uses the new flat config format introduced in ESLint 8.21.0
+ */
+
+// Import essential ESLint plugins and configurations
+import tseslint from '@typescript-eslint/eslint-plugin';
+import tsParser from '@typescript-eslint/parser';
+import noOnlyTests from 'eslint-plugin-no-only-tests';
+import prettier from 'eslint-config-prettier';
+import importPlugin from 'eslint-plugin-import';
+import js from '@eslint/js';
+import noBadGdprCommentPlugin from './.eslintplugin/no-bad-gdpr-comment.js'; // Ensure the path is correct
+
+export default [
+ {
+ ignores: ['**/node_modules/**', '**/out/**'],
+ },
+ // Base configuration for all files
+ {
+ ignores: [
+ '**/node_modules/**',
+ '**/out/**',
+ 'src/test/analysisEngineTest.ts',
+ 'src/test/ciConstants.ts',
+ 'src/test/common.ts',
+ 'src/test/constants.ts',
+ 'src/test/core.ts',
+ 'src/test/extension-version.functional.test.ts',
+ 'src/test/fixtures.ts',
+ 'src/test/index.ts',
+ 'src/test/initialize.ts',
+ 'src/test/mockClasses.ts',
+ 'src/test/performanceTest.ts',
+ 'src/test/proc.ts',
+ 'src/test/smokeTest.ts',
+ 'src/test/standardTest.ts',
+ 'src/test/startupTelemetry.unit.test.ts',
+ 'src/test/testBootstrap.ts',
+ 'src/test/testLogger.ts',
+ 'src/test/testRunner.ts',
+ 'src/test/textUtils.ts',
+ 'src/test/unittests.ts',
+ 'src/test/vscode-mock.ts',
+ 'src/test/interpreters/mocks.ts',
+ 'src/test/interpreters/virtualEnvs/condaInheritEnvPrompt.unit.test.ts',
+ 'src/test/interpreters/pythonPathUpdaterFactory.unit.test.ts',
+ 'src/test/interpreters/activation/service.unit.test.ts',
+ 'src/test/interpreters/helpers.unit.test.ts',
+ 'src/test/interpreters/display.unit.test.ts',
+ 'src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts',
+ 'src/test/terminals/codeExecution/codeExecutionManager.unit.test.ts',
+ 'src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts',
+ 'src/test/activation/activeResource.unit.test.ts',
+ 'src/test/activation/extensionSurvey.unit.test.ts',
+ 'src/test/utils/fs.ts',
+ 'src/test/api.functional.test.ts',
+ 'src/test/testing/common/debugLauncher.unit.test.ts',
+ 'src/test/testing/common/services/configSettingService.unit.test.ts',
+ 'src/test/common/exitCIAfterTestReporter.ts',
+ 'src/test/common/terminals/activator/index.unit.test.ts',
+ 'src/test/common/terminals/activator/base.unit.test.ts',
+ 'src/test/common/terminals/shellDetector.unit.test.ts',
+ 'src/test/common/terminals/service.unit.test.ts',
+ 'src/test/common/terminals/helper.unit.test.ts',
+ 'src/test/common/terminals/activation.unit.test.ts',
+ 'src/test/common/terminals/shellDetectors/shellDetectors.unit.test.ts',
+ 'src/test/common/terminals/environmentActivationProviders/terminalActivation.testvirtualenvs.ts',
+ 'src/test/common/socketStream.test.ts',
+ 'src/test/common/configSettings.test.ts',
+ 'src/test/common/experiments/telemetry.unit.test.ts',
+ 'src/test/common/platform/filesystem.unit.test.ts',
+ 'src/test/common/platform/errors.unit.test.ts',
+ 'src/test/common/platform/utils.ts',
+ 'src/test/common/platform/fs-temp.unit.test.ts',
+ 'src/test/common/platform/fs-temp.functional.test.ts',
+ 'src/test/common/platform/filesystem.functional.test.ts',
+ 'src/test/common/platform/filesystem.test.ts',
+ 'src/test/common/utils/cacheUtils.unit.test.ts',
+ 'src/test/common/utils/decorators.unit.test.ts',
+ 'src/test/common/utils/version.unit.test.ts',
+ 'src/test/common/configSettings/configSettings.unit.test.ts',
+ 'src/test/common/serviceRegistry.unit.test.ts',
+ 'src/test/common/extensions.unit.test.ts',
+ 'src/test/common/variables/envVarsService.unit.test.ts',
+ 'src/test/common/helpers.test.ts',
+ 'src/test/common/application/commands/reloadCommand.unit.test.ts',
+ 'src/test/common/installer/channelManager.unit.test.ts',
+ 'src/test/common/installer/pipInstaller.unit.test.ts',
+ 'src/test/common/installer/pipEnvInstaller.unit.test.ts',
+ 'src/test/common/socketCallbackHandler.test.ts',
+ 'src/test/common/process/decoder.test.ts',
+ 'src/test/common/process/processFactory.unit.test.ts',
+ 'src/test/common/process/pythonToolService.unit.test.ts',
+ 'src/test/common/process/proc.observable.test.ts',
+ 'src/test/common/process/logger.unit.test.ts',
+ 'src/test/common/process/proc.exec.test.ts',
+ 'src/test/common/process/pythonProcess.unit.test.ts',
+ 'src/test/common/process/proc.unit.test.ts',
+ 'src/test/common/interpreterPathService.unit.test.ts',
+ 'src/test/debugger/extension/adapter/adapter.test.ts',
+ 'src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts',
+ 'src/test/debugger/extension/adapter/factory.unit.test.ts',
+ 'src/test/debugger/extension/adapter/logging.unit.test.ts',
+ 'src/test/debugger/extension/hooks/childProcessAttachHandler.unit.test.ts',
+ 'src/test/debugger/extension/hooks/childProcessAttachService.unit.test.ts',
+ 'src/test/debugger/utils.ts',
+ 'src/test/debugger/envVars.test.ts',
+ 'src/test/telemetry/index.unit.test.ts',
+ 'src/test/telemetry/envFileTelemetry.unit.test.ts',
+ 'src/test/application/diagnostics/checks/macPythonInterpreter.unit.test.ts',
+ 'src/test/application/diagnostics/checks/pythonInterpreter.unit.test.ts',
+ 'src/test/application/diagnostics/checks/powerShellActivation.unit.test.ts',
+ 'src/test/application/diagnostics/checks/envPathVariable.unit.test.ts',
+ 'src/test/application/diagnostics/applicationDiagnostics.unit.test.ts',
+ 'src/test/application/diagnostics/promptHandler.unit.test.ts',
+ 'src/test/application/diagnostics/commands/ignore.unit.test.ts',
+ 'src/test/performance/load.perf.test.ts',
+ 'src/client/interpreter/configuration/interpreterSelector/commands/base.ts',
+ 'src/client/interpreter/configuration/interpreterSelector/commands/resetInterpreter.ts',
+ 'src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts',
+ 'src/client/interpreter/configuration/services/globalUpdaterService.ts',
+ 'src/client/interpreter/configuration/services/workspaceUpdaterService.ts',
+ 'src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts',
+ 'src/client/interpreter/helpers.ts',
+ 'src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts',
+ 'src/client/interpreter/display/index.ts',
+ 'src/client/extension.ts',
+ 'src/client/startupTelemetry.ts',
+ 'src/client/terminals/codeExecution/terminalCodeExecution.ts',
+ 'src/client/terminals/codeExecution/codeExecutionManager.ts',
+ 'src/client/terminals/codeExecution/djangoContext.ts',
+ 'src/client/activation/commands.ts',
+ 'src/client/activation/progress.ts',
+ 'src/client/activation/extensionSurvey.ts',
+ 'src/client/activation/common/analysisOptions.ts',
+ 'src/client/activation/languageClientMiddleware.ts',
+ 'src/client/testing/serviceRegistry.ts',
+ 'src/client/testing/main.ts',
+ 'src/client/testing/configurationFactory.ts',
+ 'src/client/testing/common/constants.ts',
+ 'src/client/testing/common/testUtils.ts',
+ 'src/client/common/helpers.ts',
+ 'src/client/common/net/browser.ts',
+ 'src/client/common/net/socket/socketCallbackHandler.ts',
+ 'src/client/common/net/socket/socketServer.ts',
+ 'src/client/common/net/socket/SocketStream.ts',
+ 'src/client/common/contextKey.ts',
+ 'src/client/common/experiments/telemetry.ts',
+ 'src/client/common/platform/serviceRegistry.ts',
+ 'src/client/common/platform/errors.ts',
+ 'src/client/common/platform/fs-temp.ts',
+ 'src/client/common/platform/fs-paths.ts',
+ 'src/client/common/platform/registry.ts',
+ 'src/client/common/platform/pathUtils.ts',
+ 'src/client/common/persistentState.ts',
+ 'src/client/common/terminal/activator/base.ts',
+ 'src/client/common/terminal/activator/powershellFailedHandler.ts',
+ 'src/client/common/terminal/activator/index.ts',
+ 'src/client/common/terminal/helper.ts',
+ 'src/client/common/terminal/syncTerminalService.ts',
+ 'src/client/common/terminal/factory.ts',
+ 'src/client/common/terminal/commandPrompt.ts',
+ 'src/client/common/terminal/service.ts',
+ 'src/client/common/terminal/shellDetector.ts',
+ 'src/client/common/terminal/shellDetectors/userEnvironmentShellDetector.ts',
+ 'src/client/common/terminal/shellDetectors/vscEnvironmentShellDetector.ts',
+ 'src/client/common/terminal/shellDetectors/terminalNameShellDetector.ts',
+ 'src/client/common/terminal/shellDetectors/settingsShellDetector.ts',
+ 'src/client/common/terminal/shellDetectors/baseShellDetector.ts',
+ 'src/client/common/utils/decorators.ts',
+ 'src/client/common/utils/enum.ts',
+ 'src/client/common/utils/platform.ts',
+ 'src/client/common/utils/stopWatch.ts',
+ 'src/client/common/utils/random.ts',
+ 'src/client/common/utils/sysTypes.ts',
+ 'src/client/common/utils/misc.ts',
+ 'src/client/common/utils/cacheUtils.ts',
+ 'src/client/common/utils/workerPool.ts',
+ 'src/client/common/extensions.ts',
+ 'src/client/common/variables/serviceRegistry.ts',
+ 'src/client/common/variables/environment.ts',
+ 'src/client/common/variables/types.ts',
+ 'src/client/common/variables/systemVariables.ts',
+ 'src/client/common/cancellation.ts',
+ 'src/client/common/interpreterPathService.ts',
+ 'src/client/common/application/applicationShell.ts',
+ 'src/client/common/application/languageService.ts',
+ 'src/client/common/application/clipboard.ts',
+ 'src/client/common/application/workspace.ts',
+ 'src/client/common/application/debugSessionTelemetry.ts',
+ 'src/client/common/application/documentManager.ts',
+ 'src/client/common/application/debugService.ts',
+ 'src/client/common/application/commands/reloadCommand.ts',
+ 'src/client/common/application/terminalManager.ts',
+ 'src/client/common/application/applicationEnvironment.ts',
+ 'src/client/common/errors/errorUtils.ts',
+ 'src/client/common/installer/serviceRegistry.ts',
+ 'src/client/common/installer/channelManager.ts',
+ 'src/client/common/installer/moduleInstaller.ts',
+ 'src/client/common/installer/types.ts',
+ 'src/client/common/installer/pipEnvInstaller.ts',
+ 'src/client/common/installer/productService.ts',
+ 'src/client/common/installer/pipInstaller.ts',
+ 'src/client/common/installer/productPath.ts',
+ 'src/client/common/process/currentProcess.ts',
+ 'src/client/common/process/processFactory.ts',
+ 'src/client/common/process/serviceRegistry.ts',
+ 'src/client/common/process/pythonToolService.ts',
+ 'src/client/common/process/internal/python.ts',
+ 'src/client/common/process/internal/scripts/testing_tools.ts',
+ 'src/client/common/process/types.ts',
+ 'src/client/common/process/logger.ts',
+ 'src/client/common/process/pythonProcess.ts',
+ 'src/client/common/process/pythonEnvironment.ts',
+ 'src/client/common/process/decoder.ts',
+ 'src/client/debugger/extension/adapter/remoteLaunchers.ts',
+ 'src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts',
+ 'src/client/debugger/extension/adapter/factory.ts',
+ 'src/client/debugger/extension/adapter/activator.ts',
+ 'src/client/debugger/extension/adapter/logging.ts',
+ 'src/client/debugger/extension/hooks/eventHandlerDispatcher.ts',
+ 'src/client/debugger/extension/hooks/childProcessAttachService.ts',
+ 'src/client/debugger/extension/attachQuickPick/wmicProcessParser.ts',
+ 'src/client/debugger/extension/attachQuickPick/factory.ts',
+ 'src/client/debugger/extension/attachQuickPick/psProcessParser.ts',
+ 'src/client/debugger/extension/attachQuickPick/picker.ts',
+ 'src/client/application/serviceRegistry.ts',
+ 'src/client/application/diagnostics/base.ts',
+ 'src/client/application/diagnostics/applicationDiagnostics.ts',
+ 'src/client/application/diagnostics/filter.ts',
+ 'src/client/application/diagnostics/promptHandler.ts',
+ 'src/client/application/diagnostics/commands/base.ts',
+ 'src/client/application/diagnostics/commands/ignore.ts',
+ 'src/client/application/diagnostics/commands/factory.ts',
+ 'src/client/application/diagnostics/commands/execVSCCommand.ts',
+ 'src/client/application/diagnostics/commands/launchBrowser.ts',
+ ],
+ linterOptions: {
+ reportUnusedDisableDirectives: 'off',
+ },
+ rules: {
+ ...js.configs.recommended.rules,
+ 'no-undef': 'off',
+ },
+ },
+ // TypeScript-specific configuration
+ {
+ files: ['**/*.ts', '**/*.tsx', '**/*.js', 'src', 'pythonExtensionApi/src'],
+ languageOptions: {
+ parser: tsParser,
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ },
+ globals: {
+ ...(js.configs.recommended.languageOptions?.globals || {}),
+ mocha: true,
+ require: 'readonly',
+ process: 'readonly',
+ exports: 'readonly',
+ module: 'readonly',
+ __dirname: 'readonly',
+ __filename: 'readonly',
+ setTimeout: 'readonly',
+ setInterval: 'readonly',
+ clearTimeout: 'readonly',
+ clearInterval: 'readonly',
+ },
+ },
+ plugins: {
+ '@typescript-eslint': tseslint,
+ 'no-only-tests': noOnlyTests,
+ import: importPlugin,
+ prettier: prettier,
+ 'no-bad-gdpr-comment': noBadGdprCommentPlugin, // Register your plugin
+ },
+ settings: {
+ 'import/resolver': {
+ node: {
+ extensions: ['.js', '.ts'],
+ },
+ },
+ },
+ rules: {
+ 'no-bad-gdpr-comment/no-bad-gdpr-comment': 'warn', // Enable your rule
+ // Base configurations
+ ...tseslint.configs.recommended.rules,
+ ...prettier.rules,
+
+ // TypeScript-specific rules
+ '@typescript-eslint/ban-ts-comment': [
+ 'error',
+ {
+ 'ts-ignore': 'allow-with-description',
+ },
+ ],
+ '@typescript-eslint/ban-types': 'off',
+ '@typescript-eslint/explicit-module-boundary-types': 'off',
+ '@typescript-eslint/no-empty-interface': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-namespace': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'off',
+ '@typescript-eslint/no-loss-of-precision': 'off',
+ '@typescript-eslint/no-unused-vars': [
+ 'warn',
+ {
+ varsIgnorePattern: '^_',
+ argsIgnorePattern: '^_',
+ },
+ ],
+ '@typescript-eslint/no-var-requires': 'off',
+ '@typescript-eslint/no-use-before-define': [
+ 'error',
+ {
+ functions: false,
+ },
+ ],
+
+ // Import rules
+ 'import/extensions': 'off',
+ 'import/namespace': 'off',
+ 'import/no-extraneous-dependencies': 'off',
+ 'import/no-unresolved': 'off',
+ 'import/prefer-default-export': 'off',
+
+ // Testing rules
+ 'no-only-tests/no-only-tests': [
+ 'error',
+ {
+ block: ['test', 'suite'],
+ focus: ['only'],
+ },
+ ],
+
+ // Code style rules
+ 'linebreak-style': 'off',
+ 'no-bitwise': 'off',
+ 'no-console': 'off',
+ 'no-underscore-dangle': 'off',
+ 'operator-assignment': 'off',
+ 'func-names': 'off',
+
+ // Error handling and control flow
+ 'no-empty': ['error', { allowEmptyCatch: true }],
+ 'no-async-promise-executor': 'off',
+ 'no-await-in-loop': 'off',
+ 'no-unreachable': 'off',
+ 'no-void': 'off',
+
+ // Duplicates and overrides (TypeScript handles these)
+ 'no-dupe-class-members': 'off',
+ 'no-redeclare': 'off',
+ 'no-undef': 'off',
+
+ // Miscellaneous rules
+ 'no-control-regex': 'off',
+ 'no-extend-native': 'off',
+ 'no-inner-declarations': 'off',
+ 'no-multi-str': 'off',
+ 'no-param-reassign': 'off',
+ 'no-prototype-builtins': 'off',
+ 'no-empty-function': 'off',
+ 'no-template-curly-in-string': 'off',
+ 'no-useless-escape': 'off',
+ 'no-extra-parentheses': 'off',
+ 'no-extra-paren': 'off',
+ '@typescript-eslint/no-extra-parens': 'off',
+ strict: 'off',
+
+ // Restricted syntax
+ 'no-restricted-syntax': [
+ 'error',
+ {
+ selector: 'ForInStatement',
+ message:
+ 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
+ },
+ {
+ selector: 'LabeledStatement',
+ message:
+ 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.',
+ },
+ {
+ selector: 'WithStatement',
+ message:
+ '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.',
+ },
+ ],
+ },
+ },
+];
diff --git a/gulpfile.js b/gulpfile.js
index da46943f7335..0b919f16572a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -98,9 +98,11 @@ async function addExtensionPackDependencies() {
// extension dependencies need not be installed during development
const packageJsonContents = await fsExtra.readFile('package.json', 'utf-8');
const packageJson = JSON.parse(packageJsonContents);
- packageJson.extensionPack = ['ms-python.vscode-pylance', 'ms-python.debugpy'].concat(
- packageJson.extensionPack ? packageJson.extensionPack : [],
- );
+ packageJson.extensionPack = [
+ 'ms-python.vscode-pylance',
+ 'ms-python.debugpy',
+ 'ms-python.vscode-python-envs',
+ ].concat(packageJson.extensionPack ? packageJson.extensionPack : []);
// Remove potential duplicates.
packageJson.extensionPack = packageJson.extensionPack.filter(
(item, index) => packageJson.extensionPack.indexOf(item) === index,
@@ -222,12 +224,6 @@ function getAllowedWarningsForWebPack(buildConfig) {
throw new Error('Unknown WebPack Configuration');
}
}
-gulp.task('renameSourceMaps', async () => {
- // By default source maps will be disabled in the extension.
- // Users will need to use the command `python.enableSourceMapSupport` to enable source maps.
- const extensionSourceMap = path.join(__dirname, 'out', 'client', 'extension.js.map');
- await fsExtra.rename(extensionSourceMap, `${extensionSourceMap}.disabled`);
-});
gulp.task('verifyBundle', async () => {
const matches = await glob.sync(path.join(__dirname, '*.vsix'));
@@ -238,7 +234,7 @@ gulp.task('verifyBundle', async () => {
}
});
-gulp.task('prePublishBundle', gulp.series('webpack', 'renameSourceMaps'));
+gulp.task('prePublishBundle', gulp.series('webpack'));
gulp.task('checkDependencies', gulp.series('checkNativeDependencies'));
gulp.task('prePublishNonBundle', gulp.series('compile'));
diff --git a/noxfile.py b/noxfile.py
index b9ebba64544a..3991ee8c025a 100644
--- a/noxfile.py
+++ b/noxfile.py
@@ -1,18 +1,40 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
+import os
import pathlib
import nox
import shutil
+import sys
+import sysconfig
+import uuid
+
+EXT_ROOT = pathlib.Path(__file__).parent
+
+
+def delete_dir(path: pathlib.Path, ignore_errors=None):
+ attempt = 0
+ known = []
+ while attempt < 5:
+ try:
+ shutil.rmtree(os.fspath(path), ignore_errors=ignore_errors)
+ return
+ except PermissionError as pe:
+ if os.fspath(pe.filename) in known:
+ break
+ print(f"Changing permissions on {pe.filename}")
+ os.chmod(pe.filename, 0o666)
+
+ shutil.rmtree(os.fspath(path))
@nox.session()
def install_python_libs(session: nox.Session):
requirements = [
- ("./pythonFiles/lib/python", "./requirements.txt"),
+ ("./python_files/lib/python", "./requirements.txt"),
(
- "./pythonFiles/lib/jedilsp",
- "./pythonFiles/jedilsp_requirements/requirements.txt",
+ "./python_files/lib/jedilsp",
+ "./python_files/jedilsp_requirements/requirements.txt",
),
]
for target, file in requirements:
@@ -31,20 +53,109 @@ def install_python_libs(session: nox.Session):
)
session.install("packaging")
-
- # Install debugger
- session.run(
- "python",
- "./pythonFiles/install_debugpy.py",
- env={"PYTHONPATH": "./pythonFiles/lib/temp"},
- )
+ session.install("debugpy")
# Download get-pip script
session.run(
"python",
- "./pythonFiles/download_get_pip.py",
- env={"PYTHONPATH": "./pythonFiles/lib/temp"},
+ "./python_files/download_get_pip.py",
+ env={"PYTHONPATH": "./python_files/lib/temp"},
)
- if pathlib.Path("./pythonFiles/lib/temp").exists():
- shutil.rmtree("./pythonFiles/lib/temp")
+ if pathlib.Path("./python_files/lib/temp").exists():
+ shutil.rmtree("./python_files/lib/temp")
+
+
+@nox.session()
+def native_build(session: nox.Session):
+ source_dir = pathlib.Path(pathlib.Path.cwd() / "python-env-tools").resolve()
+ dest_dir = pathlib.Path(pathlib.Path.cwd() / "python-env-tools").resolve()
+
+ with session.cd(source_dir):
+ if not pathlib.Path(dest_dir / "bin").exists():
+ pathlib.Path(dest_dir / "bin").mkdir()
+
+ if not pathlib.Path(dest_dir / "bin" / ".gitignore").exists():
+ pathlib.Path(dest_dir / "bin" / ".gitignore").write_text(
+ "*\n", encoding="utf-8"
+ )
+
+ ext = sysconfig.get_config_var("EXE") or ""
+ target = os.environ.get("CARGO_TARGET", None)
+
+ session.run("cargo", "fetch", external=True)
+ if target:
+ session.run(
+ "cargo",
+ "build",
+ "--frozen",
+ "--release",
+ "--target",
+ target,
+ external=True,
+ )
+ source = source_dir / "target" / target / "release" / f"pet{ext}"
+ else:
+ session.run(
+ "cargo",
+ "build",
+ "--frozen",
+ "--release",
+ external=True,
+ )
+ source = source_dir / "target" / "release" / f"pet{ext}"
+ dest = dest_dir / "bin" / f"pet{ext}"
+ shutil.copy(source, dest)
+
+ # Remove python-env-tools/bin exclusion from .vscodeignore
+ vscode_ignore = EXT_ROOT / ".vscodeignore"
+ remove_patterns = ("python-env-tools/bin/**",)
+ lines = vscode_ignore.read_text(encoding="utf-8").splitlines()
+ filtered_lines = [line for line in lines if not line.startswith(remove_patterns)]
+ vscode_ignore.write_text("\n".join(filtered_lines) + "\n", encoding="utf-8")
+
+
+@nox.session()
+def checkout_native(session: nox.Session):
+ dest = (pathlib.Path.cwd() / "python-env-tools").resolve()
+ if dest.exists():
+ shutil.rmtree(os.fspath(dest))
+
+ temp_dir = os.getenv("TEMP") or os.getenv("TMP") or "/tmp"
+ temp_dir = pathlib.Path(temp_dir) / str(uuid.uuid4()) / "python-env-tools"
+ temp_dir.mkdir(0o766, parents=True)
+
+ session.log(f"Cloning python-environment-tools to {temp_dir}")
+ try:
+ with session.cd(temp_dir):
+ session.run("git", "init", external=True)
+ session.run(
+ "git",
+ "remote",
+ "add",
+ "origin",
+ "https://github.com/microsoft/python-environment-tools",
+ external=True,
+ )
+ session.run("git", "fetch", "origin", "main", external=True)
+ session.run(
+ "git", "checkout", "--force", "-B", "main", "origin/main", external=True
+ )
+ delete_dir(temp_dir / ".git")
+ delete_dir(temp_dir / ".github")
+ delete_dir(temp_dir / ".vscode")
+ (temp_dir / "CODE_OF_CONDUCT.md").unlink()
+ shutil.move(os.fspath(temp_dir), os.fspath(dest))
+ except PermissionError as e:
+ print(f"Permission error: {e}")
+ if not dest.exists():
+ raise
+ finally:
+ delete_dir(temp_dir.parent, ignore_errors=True)
+
+
+@nox.session()
+def setup_repo(session: nox.Session):
+ install_python_libs(session)
+ checkout_native(session)
+ native_build(session)
diff --git a/package-lock.json b/package-lock.json
index 62105cb4fabb..82053df77576 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,43 +1,40 @@
{
"name": "python",
- "version": "2024.1.0-dev",
+ "version": "2026.5.0-dev",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "python",
- "version": "2024.1.0-dev",
+ "version": "2026.5.0-dev",
"license": "MIT",
"dependencies": {
- "@iarna/toml": "^2.2.5",
+ "@iarna/toml": "^3.0.0",
"@vscode/extension-telemetry": "^0.8.4",
- "@vscode/jupyter-lsp-middleware": "^0.2.50",
"arch": "^2.1.0",
- "fs-extra": "^10.0.1",
+ "fs-extra": "^11.2.0",
"glob": "^7.2.0",
- "hash.js": "^1.1.7",
"iconv-lite": "^0.6.3",
- "inversify": "^5.0.4",
+ "inversify": "^6.0.2",
"jsonc-parser": "^3.0.0",
- "lodash": "^4.17.21",
- "minimatch": "^5.0.1",
+ "lodash": "^4.18.1",
+ "minimatch": "^5.1.8",
"named-js-regexp": "^1.3.3",
"node-stream-zip": "^1.6.0",
- "reflect-metadata": "^0.1.12",
+ "reflect-metadata": "^0.2.2",
"rxjs": "^6.5.4",
"rxjs-compat": "^6.5.4",
"semver": "^7.5.2",
"stack-trace": "0.0.10",
"sudo-prompt": "^9.2.1",
- "tmp": "^0.0.33",
+ "tmp": "^0.2.5",
"uint64be": "^3.0.0",
"unicode": "^14.0.0",
- "untildify": "^4.0.0",
"vscode-debugprotocol": "^1.28.0",
- "vscode-jsonrpc": "^8.2.0",
- "vscode-languageclient": "^9.0.1",
- "vscode-languageserver-protocol": "^3.17.5",
- "vscode-tas-client": "^0.1.75",
+ "vscode-jsonrpc": "^9.0.0-next.5",
+ "vscode-languageclient": "^10.0.0-next.12",
+ "vscode-languageserver-protocol": "^3.17.6-next.10",
+ "vscode-tas-client": "^0.1.84",
"which": "^2.0.2",
"winreg": "^1.2.4",
"xml2js": "^0.5.0"
@@ -49,45 +46,46 @@
"@types/chai-arrays": "^2.0.0",
"@types/chai-as-promised": "^7.1.0",
"@types/download": "^8.0.1",
- "@types/fs-extra": "^9.0.13",
+ "@types/fs-extra": "^11.0.4",
"@types/glob": "^7.2.0",
"@types/lodash": "^4.14.104",
"@types/mocha": "^9.1.0",
- "@types/node": "^18.17.1",
+ "@types/node": "^22.19.1",
"@types/semver": "^5.5.0",
"@types/shortid": "^0.0.29",
- "@types/sinon": "^10.0.11",
+ "@types/sinon": "^17.0.3",
"@types/stack-trace": "0.0.29",
"@types/tmp": "^0.0.33",
- "@types/vscode": "^1.81.0",
+ "@types/vscode": "^1.95.0",
"@types/which": "^2.0.1",
"@types/winreg": "^1.2.30",
"@types/xml2js": "^0.4.2",
- "@typescript-eslint/eslint-plugin": "^3.7.0",
- "@typescript-eslint/parser": "^3.7.0",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
"@vscode/test-electron": "^2.3.8",
- "@vscode/vsce": "^2.18.0",
+ "@vscode/vsce": "^2.27.0",
"bent": "^7.3.12",
"chai": "^4.1.2",
"chai-arrays": "^2.0.0",
"chai-as-promised": "^7.1.1",
"copy-webpack-plugin": "^9.1.0",
+ "cross-env": "^7.0.3",
"cross-spawn": "^6.0.5",
"del": "^6.0.0",
"download": "^8.0.0",
- "eslint": "^7.2.0",
- "eslint-config-airbnb": "^18.2.0",
+ "eslint": "^8.57.1",
"eslint-config-prettier": "^8.3.0",
- "eslint-plugin-import": "^2.25.4",
+ "eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
+ "eslint-plugin-no-only-tests": "^3.3.0",
"eslint-plugin-react": "^7.20.3",
"eslint-plugin-react-hooks": "^4.0.0",
"expose-loader": "^3.1.0",
"flat": "^5.0.2",
"get-port": "^5.1.1",
- "gulp": "^4.0.0",
+ "gulp": "^5.0.0",
"gulp-typescript": "^5.0.0",
- "mocha": "^9.2.2",
+ "mocha": "^11.1.0",
"mocha-junit-reporter": "^2.0.2",
"mocha-multi-reporters": "^1.1.7",
"node-has-native-dependencies": "^1.0.2",
@@ -97,16 +95,16 @@
"prettier": "^2.0.2",
"rewiremock": "^3.13.0",
"shortid": "^2.2.8",
- "sinon": "^13.0.1",
+ "sinon": "^18.0.0",
"source-map-support": "^0.5.12",
"ts-loader": "^9.2.8",
"ts-mockito": "^2.5.0",
"ts-node": "^10.7.0",
"tsconfig-paths-webpack-plugin": "^3.2.0",
"typemoq": "^2.1.0",
- "typescript": "4.5.5",
- "uuid": "^8.3.2",
- "webpack": "^5.76.0",
+ "typescript": "~5.2",
+ "uuid": "^14.0.0",
+ "webpack": "^5.105.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2",
"webpack-fix-default-import-plugin": "^1.0.3",
@@ -117,7 +115,7 @@
"yargs": "^15.3.1"
},
"engines": {
- "vscode": "^1.82.0"
+ "vscode": "^1.95.0"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -176,6 +174,55 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
+ "node_modules/@azure/core-client": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz",
+ "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==",
+ "dev": true,
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "@azure/core-auth": "^1.4.0",
+ "@azure/core-rest-pipeline": "^1.9.1",
+ "@azure/core-tracing": "^1.0.0",
+ "@azure/core-util": "^1.6.1",
+ "@azure/logger": "^1.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-client/node_modules/@azure/abort-controller": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-client/node_modules/@azure/core-util": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz",
+ "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==",
+ "dev": true,
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-client/node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "dev": true
+ },
"node_modules/@azure/core-rest-pipeline": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz",
@@ -238,6 +285,14 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
+ "node_modules/@azure/core-rest-pipeline/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/@azure/core-tracing": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz",
@@ -271,6 +326,62 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
+ "node_modules/@azure/identity": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.2.1.tgz",
+ "integrity": "sha512-U8hsyC9YPcEIzoaObJlRDvp7KiF0MGS7xcWbyJSVvXRkC/HXo1f0oYeBYmEvVgRfacw7GHf6D6yAoh9JHz6A5Q==",
+ "dev": true,
+ "dependencies": {
+ "@azure/abort-controller": "^1.0.0",
+ "@azure/core-auth": "^1.5.0",
+ "@azure/core-client": "^1.4.0",
+ "@azure/core-rest-pipeline": "^1.1.0",
+ "@azure/core-tracing": "^1.0.0",
+ "@azure/core-util": "^1.3.0",
+ "@azure/logger": "^1.0.0",
+ "@azure/msal-browser": "^3.11.1",
+ "@azure/msal-node": "^2.9.2",
+ "events": "^3.0.0",
+ "jws": "^4.0.0",
+ "open": "^8.0.0",
+ "stoppable": "^1.1.0",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/identity/node_modules/@azure/core-util": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz",
+ "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==",
+ "dev": true,
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/identity/node_modules/@azure/core-util/node_modules/@azure/abort-controller": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/identity/node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "dev": true
+ },
"node_modules/@azure/logger": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz",
@@ -287,6 +398,59 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
+ "node_modules/@azure/msal-browser": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.14.0.tgz",
+ "integrity": "sha512-Un85LhOoecJ3HDTS3Uv3UWnXC9/43ZSO+Kc+anSqpZvcEt58SiO/3DuVCAe1A3I5UIBYJNMgTmZPGXQ0MVYrwA==",
+ "dev": true,
+ "dependencies": {
+ "@azure/msal-common": "14.10.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-common": {
+ "version": "14.10.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.10.0.tgz",
+ "integrity": "sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-node": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.9.2.tgz",
+ "integrity": "sha512-8tvi6Cos3m+0KmRbPjgkySXi+UQU/QiuVRFnrxIwt5xZlEEFa69O04RTaNESGgImyBBlYbo2mfE8/U8Bbdk1WQ==",
+ "dev": true,
+ "dependencies": {
+ "@azure/msal-common": "14.12.0",
+ "jsonwebtoken": "^9.0.0",
+ "uuid": "^8.3.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@azure/msal-node/node_modules/@azure/msal-common": {
+ "version": "14.12.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.12.0.tgz",
+ "integrity": "sha512-IDDXmzfdwmDkv4SSmMEyAniJf6fDu3FJ7ncOjlxkDuT85uSnLEhZi3fGZpoR7T4XZpOMx9teM9GXBgrfJgyeBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@azure/msal-node/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/@azure/opentelemetry-instrumentation-azure-sdk": {
"version": "1.0.0-beta.5",
"resolved": "https://registry.npmjs.org/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz",
@@ -309,12 +473,18 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/@babel/code-frame": {
- "version": "7.12.11",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
- "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/highlight": "^7.10.4"
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
}
},
"node_modules/@babel/compat-data": {
@@ -356,18 +526,6 @@
"url": "https://opencollective.com/babel"
}
},
- "node_modules/@babel/core/node_modules/@babel/code-frame": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
- "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
- "dev": true,
- "dependencies": {
- "@babel/highlight": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/core/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -524,19 +682,21 @@
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
- "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
@@ -551,38 +711,28 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz",
- "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz",
+ "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.6",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/highlight": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
- "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "node_modules/@babel/parser": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
+ "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "@babel/types": "^7.27.1"
},
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
- "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
- "dev": true,
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -591,49 +741,38 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.17.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
- "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
+ "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
"dev": true,
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
+ "license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/runtime-corejs3": {
- "version": "7.10.5",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.5.tgz",
- "integrity": "sha512-RMafpmrNB5E/bwdSphLr8a8++9TosnyJp98RZzI6VOx2R2CCMpsXXXRvmI700O9oEKpXdZat6oEK68/F0zjd4A==",
- "dev": true,
- "dependencies": {
- "core-js-pure": "^3.0.0",
- "regenerator-runtime": "^0.13.4"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.27.1.tgz",
+ "integrity": "sha512-909rVuj3phpjW6y0MCXAZ5iNeORePa6ldJvp2baWGcTjwqbBDDz6xoS5JHJ7lS88NlwLYj07ImL/8IUMtDZzTA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
+ "core-js-pure": "^3.30.2"
},
"engines": {
"node": ">=6.9.0"
}
},
- "node_modules/@babel/template/node_modules/@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
+ "node_modules/@babel/template": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -660,19 +799,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/traverse/node_modules/@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
- "dev": true,
- "dependencies": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/traverse/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -691,14 +817,14 @@
}
},
"node_modules/@babel/types": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
- "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
+ "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
},
"engines": {
"node": ">=6.9.0"
@@ -734,33 +860,69 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
+ "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
+ "dev": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
"node_modules/@eslint/eslintrc": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
- "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
- "debug": "^4.1.1",
- "espree": "^7.3.0",
- "globals": "^13.9.0",
- "ignore": "^4.0.6",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
"import-fresh": "^3.2.1",
- "js-yaml": "^3.13.1",
- "minimatch": "^3.0.4",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
"node_modules/@eslint/eslintrc/node_modules/debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -772,10 +934,11 @@
}
},
"node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
- "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"type-fest": "^0.20.2"
},
@@ -786,20 +949,24 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/@eslint/eslintrc/node_modules/ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
- "engines": {
- "node": ">= 4"
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@eslint/eslintrc/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -807,11 +974,19 @@
"node": "*"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@eslint/eslintrc/node_modules/type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
+ "license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
@@ -819,27 +994,61 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@gulpjs/messages": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz",
+ "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/@gulpjs/to-absolute-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz",
+ "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==",
+ "dev": true,
+ "dependencies": {
+ "is-negated-glob": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
- "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
"dev": true,
+ "license": "Apache-2.0",
"dependencies": {
- "@humanwhocodes/object-schema": "^1.2.0",
- "debug": "^4.1.1",
- "minimatch": "^3.0.4"
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
},
"engines": {
"node": ">=10.10.0"
}
},
"node_modules/@humanwhocodes/config-array/node_modules/debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -851,10 +1060,11 @@
}
},
"node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -862,27 +1072,154 @@
"node": "*"
}
},
+ "node_modules/@humanwhocodes/config-array/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/@iarna/toml": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
- "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz",
+ "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q==",
+ "license": "ISC"
},
- "node_modules/@istanbuljs/load-nyc-config": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
- "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "camelcase": "^5.3.1",
- "find-up": "^4.1.0",
- "js-yaml": "^3.13.1",
- "resolve-from": "^5.0.0"
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
+ "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
},
"engines": {
"node": ">=8"
@@ -913,14 +1250,14 @@
}
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
- "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
@@ -936,22 +1273,22 @@
}
},
"node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
- "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
@@ -961,13 +1298,13 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
- "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"dependencies": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@microsoft/1ds-core-js": {
@@ -1290,54 +1627,82 @@
"node": ">=14"
}
},
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
"integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
"dev": true
},
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@sindresorhus/is": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
"integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/@sinonjs/commons": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
- "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
"dev": true,
"dependencies": {
"type-detect": "4.0.8"
}
},
"node_modules/@sinonjs/fake-timers": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.1.tgz",
- "integrity": "sha512-Wp5vwlZ0lOqpSYGKqr53INws9HLkt6JDc/pDZcPf7bchQnrXJMXPns8CXx0hFikMSGSWfvtvvpb2gtMVfkWagA==",
+ "version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
+ "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
"dev": true,
"dependencies": {
- "@sinonjs/commons": "^1.7.0"
+ "@sinonjs/commons": "^3.0.0"
}
},
"node_modules/@sinonjs/samsam": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz",
- "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
+ "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
"dev": true,
"dependencies": {
- "@sinonjs/commons": "^1.6.0",
+ "@sinonjs/commons": "^2.0.0",
"lodash.get": "^4.4.2",
"type-detect": "^4.0.8"
}
},
+ "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
+ "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
"node_modules/@sinonjs/text-encoding": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
- "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz",
+ "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==",
"dev": true
},
"node_modules/@tootallnate/once": {
@@ -1433,9 +1798,9 @@
}
},
"node_modules/@types/eslint": {
- "version": "8.4.1",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz",
- "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true,
"dependencies": {
"@types/estree": "*",
@@ -1443,33 +1808,28 @@
}
},
"node_modules/@types/eslint-scope": {
- "version": "3.7.3",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz",
- "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==",
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
"dev": true,
"dependencies": {
"@types/eslint": "*",
"@types/estree": "*"
}
},
- "node_modules/@types/eslint-visitor-keys": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
- "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
- "dev": true
- },
"node_modules/@types/estree": {
- "version": "0.0.51",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
- "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true
},
"node_modules/@types/fs-extra": {
- "version": "9.0.13",
- "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
- "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
+ "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
"dev": true,
"dependencies": {
+ "@types/jsonfile": "*",
"@types/node": "*"
}
},
@@ -1495,23 +1855,46 @@
}
},
"node_modules/@types/got/node_modules/form-data": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
- "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz",
+ "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==",
"dev": true,
"dependencies": {
"asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.35",
+ "safe-buffer": "^5.2.1"
},
"engines": {
"node": ">= 0.12"
}
},
+ "node_modules/@types/got/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/@types/json-schema": {
- "version": "7.0.9",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
- "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"node_modules/@types/json5": {
@@ -1520,6 +1903,15 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
+ "node_modules/@types/jsonfile": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
+ "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/lodash": {
"version": "4.14.181",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz",
@@ -1539,10 +1931,14 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.17.14",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz",
- "integrity": "sha512-ZE/5aB73CyGqgQULkLG87N9GnyGe5TcQjv34pwS8tfBs1IkCh0ASM69mydb2znqd6v0eX+9Ytvk6oQRqu8T1Vw==",
- "dev": true
+ "version": "22.19.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz",
+ "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
},
"node_modules/@types/semver": {
"version": "5.5.0",
@@ -1562,9 +1958,9 @@
"dev": true
},
"node_modules/@types/sinon": {
- "version": "10.0.11",
- "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz",
- "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==",
+ "version": "17.0.3",
+ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz",
+ "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==",
"dev": true,
"dependencies": {
"@types/sinonjs__fake-timers": "*"
@@ -1595,10 +1991,11 @@
"dev": true
},
"node_modules/@types/vscode": {
- "version": "1.81.0",
- "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.81.0.tgz",
- "integrity": "sha512-YIaCwpT+O2E7WOMq0eCgBEABE++SX3Yl/O02GoMIF2DO3qAtvw7m6BXFYsxnc6XyzwZgh6/s/UG78LSSombl2w==",
- "dev": true
+ "version": "1.100.0",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.100.0.tgz",
+ "integrity": "sha512-4uNyvzHoraXEeCamR3+fzcBlh7Afs4Ifjs4epINyUX/jvdk0uzLnwiDY35UKDKnkCHP5Nu3dljl2H8lR6s+rQw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@types/which": {
"version": "2.0.1",
@@ -1622,28 +2019,33 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz",
- "integrity": "sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==",
- "dev": true,
- "dependencies": {
- "@typescript-eslint/experimental-utils": "3.10.1",
- "debug": "^4.1.1",
- "functional-red-black-tree": "^1.0.1",
- "regexpp": "^3.0.0",
- "semver": "^7.3.2",
- "tsutils": "^3.17.1"
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^3.0.0",
- "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -1652,9 +2054,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
@@ -1668,50 +2070,88 @@
}
}
},
- "node_modules/@typescript-eslint/experimental-utils": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz",
- "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==",
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"dependencies": {
- "@types/json-schema": "^7.0.3",
- "@typescript-eslint/types": "3.10.1",
- "@typescript-eslint/typescript-estree": "3.10.1",
- "eslint-scope": "^5.0.0",
- "eslint-utils": "^2.0.0"
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "*"
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
}
},
- "node_modules/@typescript-eslint/parser": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.1.tgz",
- "integrity": "sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==",
+ "node_modules/@typescript-eslint/parser/node_modules/debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"dependencies": {
- "@types/eslint-visitor-keys": "^1.0.0",
- "@typescript-eslint/experimental-utils": "3.10.1",
- "@typescript-eslint/types": "3.10.1",
- "@typescript-eslint/typescript-estree": "3.10.1",
- "eslint-visitor-keys": "^1.1.0"
+ "ms": "2.1.2"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -1719,13 +2159,30 @@
}
}
},
+ "node_modules/@typescript-eslint/type-utils/node_modules/debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@typescript-eslint/types": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz",
- "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true,
"engines": {
- "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -1733,22 +2190,22 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz",
- "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "3.10.1",
- "@typescript-eslint/visitor-keys": "3.10.1",
- "debug": "^4.1.1",
- "glob": "^7.1.6",
- "is-glob": "^4.0.1",
- "lodash": "^4.17.15",
- "semver": "^7.3.2",
- "tsutils": "^3.17.1"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -1760,10 +2217,19 @@
}
}
},
+ "node_modules/@typescript-eslint/typescript-estree/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==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
@@ -1777,28 +2243,76 @@
}
}
},
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz",
- "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==",
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
"dev": true,
"dependencies": {
- "eslint-visitor-keys": "^1.1.0"
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "semver": "^7.5.4"
},
"engines": {
- "node": "^8.10.0 || ^10.13.0 || >=11.10.1"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
}
},
- "node_modules/@ungap/promise-all-settled": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
- "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+ "node_modules/@typescript-eslint/utils/node_modules/@types/semver": {
+ "version": "7.5.8",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+ "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
"dev": true
},
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/@vscode/extension-telemetry": {
"version": "0.8.4",
"resolved": "https://registry.npmjs.org/@vscode/extension-telemetry/-/extension-telemetry-0.8.4.tgz",
@@ -1813,92 +2327,35 @@
"vscode": "^1.75.0"
}
},
- "node_modules/@vscode/jupyter-lsp-middleware": {
- "version": "0.2.50",
- "resolved": "https://registry.npmjs.org/@vscode/jupyter-lsp-middleware/-/jupyter-lsp-middleware-0.2.50.tgz",
- "integrity": "sha512-oOEpRZOJdKjByRMkUDVdGlQDiEO4/Mjr88u5zqktaS/4h0NtX8Hk6+HNQwENp4ur3Dpu47gD8wOTCrkOWzbHlA==",
+ "node_modules/@vscode/test-electron": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz",
+ "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==",
+ "dev": true,
"dependencies": {
- "@vscode/lsp-notebook-concat": "^0.1.16",
- "fast-myers-diff": "^3.0.1",
- "sha.js": "^2.4.11",
- "vscode-languageclient": "^8.0.2-next.4",
- "vscode-languageserver-protocol": "^3.17.2-next.5",
- "vscode-uri": "^3.0.2"
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "^5.0.0",
+ "jszip": "^3.10.1",
+ "semver": "^7.5.2"
},
"engines": {
- "vscode": "^1.67.0-insider"
- }
- },
- "node_modules/@vscode/jupyter-lsp-middleware/node_modules/vscode-jsonrpc": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz",
- "integrity": "sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw==",
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@vscode/jupyter-lsp-middleware/node_modules/vscode-languageclient": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0.tgz",
- "integrity": "sha512-GL4QdbYUF/XxQlAsvYWZRV3V34kOkpRlvV60/72ghHfsYFnS/v2MANZ9P6sHmxFcZKOse8O+L9G7Czg0NUWing==",
- "dependencies": {
- "minimatch": "^5.1.0",
- "semver": "^7.3.7",
- "vscode-languageserver-protocol": "3.17.3"
- },
- "engines": {
- "vscode": "^1.67.0"
- }
- },
- "node_modules/@vscode/jupyter-lsp-middleware/node_modules/vscode-languageserver-protocol": {
- "version": "3.17.3",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz",
- "integrity": "sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA==",
- "dependencies": {
- "vscode-jsonrpc": "8.1.0",
- "vscode-languageserver-types": "3.17.3"
- }
- },
- "node_modules/@vscode/jupyter-lsp-middleware/node_modules/vscode-languageserver-types": {
- "version": "3.17.3",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz",
- "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA=="
- },
- "node_modules/@vscode/lsp-notebook-concat": {
- "version": "0.1.16",
- "resolved": "https://registry.npmjs.org/@vscode/lsp-notebook-concat/-/lsp-notebook-concat-0.1.16.tgz",
- "integrity": "sha512-jN2ut22GR/xelxHx2W9U+uZoylHGCezsNmsMYn20LgVHTcJMGL+4bL5PJeh63yo6P5XjAPtoeeymvp5EafJV+w==",
- "dependencies": {
- "object-hash": "^3.0.0",
- "vscode-languageserver-protocol": "^3.17.2-next.5",
- "vscode-uri": "^3.0.2"
- }
- },
- "node_modules/@vscode/test-electron": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz",
- "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==",
- "dev": true,
- "dependencies": {
- "http-proxy-agent": "^4.0.1",
- "https-proxy-agent": "^5.0.0",
- "jszip": "^3.10.1",
- "semver": "^7.5.2"
- },
- "engines": {
- "node": ">=16"
+ "node": ">=16"
}
},
"node_modules/@vscode/vsce": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.19.0.tgz",
- "integrity": "sha512-dAlILxC5ggOutcvJY24jxz913wimGiUrHaPkk16Gm9/PGFbz1YezWtrXsTKUtJws4fIlpX2UIlVlVESWq8lkfQ==",
+ "version": "2.27.0",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.27.0.tgz",
+ "integrity": "sha512-FFUMBVSyyjjJpWszwqk7d4U3YllY8FdWslbUDMRki1x4ZjA3Z0hmRMfypWrjP9sptbSR9nyPFU4uqjhy2qRB/w==",
"dev": true,
"dependencies": {
- "azure-devops-node-api": "^11.0.1",
+ "@azure/identity": "^4.1.0",
+ "@vscode/vsce-sign": "^2.0.0",
+ "azure-devops-node-api": "^12.5.0",
"chalk": "^2.4.2",
"cheerio": "^1.0.0-rc.9",
- "commander": "^6.1.0",
+ "cockatiel": "^3.1.2",
+ "commander": "^6.2.1",
+ "form-data": "^4.0.0",
"glob": "^7.0.6",
"hosted-git-info": "^4.0.2",
"jsonc-parser": "^3.2.0",
@@ -1908,7 +2365,7 @@
"minimatch": "^3.0.3",
"parse-semver": "^1.1.1",
"read": "^1.0.7",
- "semver": "^5.1.0",
+ "semver": "^7.5.2",
"tmp": "^0.2.1",
"typed-rest-client": "^1.8.4",
"url-join": "^4.0.1",
@@ -1920,12 +2377,147 @@
"vsce": "vsce"
},
"engines": {
- "node": ">= 14"
+ "node": ">= 16"
},
"optionalDependencies": {
"keytar": "^7.7.0"
}
},
+ "node_modules/@vscode/vsce-sign": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.4.tgz",
+ "integrity": "sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optionalDependencies": {
+ "@vscode/vsce-sign-alpine-arm64": "2.0.2",
+ "@vscode/vsce-sign-alpine-x64": "2.0.2",
+ "@vscode/vsce-sign-darwin-arm64": "2.0.2",
+ "@vscode/vsce-sign-darwin-x64": "2.0.2",
+ "@vscode/vsce-sign-linux-arm": "2.0.2",
+ "@vscode/vsce-sign-linux-arm64": "2.0.2",
+ "@vscode/vsce-sign-linux-x64": "2.0.2",
+ "@vscode/vsce-sign-win32-arm64": "2.0.2",
+ "@vscode/vsce-sign-win32-x64": "2.0.2"
+ }
+ },
+ "node_modules/@vscode/vsce-sign-alpine-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz",
+ "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "alpine"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-alpine-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz",
+ "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "alpine"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-darwin-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz",
+ "integrity": "sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-darwin-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz",
+ "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-linux-arm": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz",
+ "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-linux-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz",
+ "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-linux-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz",
+ "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-win32-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz",
+ "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@vscode/vsce-sign-win32-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz",
+ "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@vscode/vsce/node_modules/commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
@@ -1948,10 +2540,11 @@
}
},
"node_modules/@vscode/vsce/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -1959,170 +2552,149 @@
"node": "*"
}
},
- "node_modules/@vscode/vsce/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/@vscode/vsce/node_modules/tmp": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
- "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
- "dev": true,
- "dependencies": {
- "rimraf": "^3.0.0"
- },
- "engines": {
- "node": ">=8.17.0"
- }
- },
"node_modules/@webassemblyjs/ast": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
- "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/helper-numbers": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
}
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
- "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "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
},
"node_modules/@webassemblyjs/helper-api-error": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
- "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "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
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
- "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
"dev": true
},
"node_modules/@webassemblyjs/helper-numbers": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
- "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"dev": true,
"dependencies": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
- "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
"dev": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
- "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
- "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"dev": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
},
"node_modules/@webassemblyjs/leb128": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
- "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"dev": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/utf8": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
- "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
"dev": true
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
- "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/helper-wasm-section": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-opt": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
- "@webassemblyjs/wast-printer": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
- "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
- "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
- "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
- "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"dev": true,
"dependencies": {
- "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
}
},
@@ -2175,9 +2747,9 @@
"dev": true
},
"node_modules/acorn": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
- "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"bin": {
"acorn": "bin/acorn"
},
@@ -2193,11 +2765,24 @@
"acorn": "^8"
}
},
+ "node_modules/acorn-import-phases": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
+ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "peerDependencies": {
+ "acorn": "^8.14.0"
+ }
+ },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true,
+ "license": "MIT",
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
@@ -2252,10 +2837,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.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -2267,6 +2853,46 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ajv-formats/node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
"node_modules/ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
@@ -2288,18 +2914,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/ansi-gray": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
- "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
- "dev": true,
- "dependencies": {
- "ansi-wrap": "0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -2331,25 +2945,16 @@
}
},
"node_modules/anymatch": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
- "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
- "dev": true,
- "dependencies": {
- "micromatch": "^3.1.4",
- "normalize-path": "^2.1.1"
- }
- },
- "node_modules/anymatch/node_modules/normalize-path": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
"dependencies": {
- "remove-trailing-separator": "^1.0.1"
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 8"
}
},
"node_modules/append-buffer": {
@@ -2438,8 +3043,9 @@
"node_modules/archive-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
- "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
+ "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"file-type": "^4.2.0"
},
@@ -2450,8 +3056,9 @@
"node_modules/archive-type/node_modules/file-type": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
- "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
+ "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -2486,67 +3093,51 @@
"node": ">=0.10.0"
}
},
- "node_modules/arr-filter": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
- "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
- "dev": true,
- "dependencies": {
- "make-iterator": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/arr-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
- "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
"dev": true,
"dependencies": {
- "make-iterator": "^1.0.0"
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/arr-union": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
- "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
- "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/array-includes": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
- "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==",
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1",
- "get-intrinsic": "^1.1.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
},
"engines": {
@@ -2556,108 +3147,72 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array-initial": {
+ "node_modules/array-slice": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
- "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
"dev": true,
- "dependencies": {
- "array-slice": "^1.0.0",
- "is-number": "^4.0.0"
- },
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/array-initial/node_modules/is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "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": ">=0.10.0"
+ "node": ">=8"
}
},
- "node_modules/array-last": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
- "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
+ "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
"dev": true,
"dependencies": {
- "is-number": "^4.0.0"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array-last/node_modules/is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+ "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
"dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/array-slice": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
- "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/array-sort": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
- "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
- "dev": true,
- "dependencies": {
- "default-compare": "^1.0.0",
- "get-value": "^2.0.6",
- "kind-of": "^5.0.2"
+ "node": ">= 0.4"
},
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/array-sort/node_modules/kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "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/array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array.prototype.flat": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz",
- "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==",
+ "node_modules/array.prototype.flatmap": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+ "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0"
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -2666,15 +3221,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array.prototype.flatmap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz",
- "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==",
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.0",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0"
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
+ "is-shared-array-buffer": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -2684,15 +3244,15 @@
}
},
"node_modules/asn1.js": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
- "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0",
- "safer-buffer": "^2.1.0"
+ "minimalistic-assert": "^1.0.0"
}
},
"node_modules/assert": {
@@ -2744,15 +3304,6 @@
"integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
"dev": true
},
- "node_modules/astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/async": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
@@ -2760,26 +3311,19 @@
"dev": true
},
"node_modules/async-done": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
- "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz",
+ "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==",
"dev": true,
"dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.2",
- "process-nextick-args": "^2.0.0",
- "stream-exhaust": "^1.0.1"
+ "end-of-stream": "^1.4.4",
+ "once": "^1.4.0",
+ "stream-exhaust": "^1.0.2"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
- "node_modules/async-each": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
- "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
- "dev": true
- },
"node_modules/async-hook-jl": {
"version": "1.7.6",
"resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz",
@@ -2812,15 +3356,15 @@
}
},
"node_modules/async-settle": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
- "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz",
+ "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==",
"dev": true,
"dependencies": {
- "async-done": "^1.2.2"
+ "async-done": "^2.0.0"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/asynckit": {
@@ -2828,23 +3372,14 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
- "node_modules/atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
- "dev": true,
- "bin": {
- "atob": "bin/atob.js"
- },
- "engines": {
- "node": ">= 4.5.0"
- }
- },
"node_modules/available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -2861,16 +3396,6 @@
"node": ">=4"
}
},
- "node_modules/axios": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
- "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
- "dependencies": {
- "follow-redirects": "^1.15.0",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
"node_modules/axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@@ -2878,15 +3403,21 @@
"dev": true
},
"node_modules/azure-devops-node-api": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.0.1.tgz",
- "integrity": "sha512-YMdjAw9l5p/6leiyIloxj3k7VIvYThKjvqgiQn88r3nhT93ENwsoDS3A83CyJ4uTWzCZ5f5jCi6c27rTU5Pz+A==",
+ "version": "12.5.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz",
+ "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==",
"dev": true,
"dependencies": {
"tunnel": "0.0.6",
"typed-rest-client": "^1.8.4"
}
},
+ "node_modules/b4a": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz",
+ "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==",
+ "dev": true
+ },
"node_modules/babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -2912,97 +3443,42 @@
"dev": true
},
"node_modules/bach": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
- "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
- "dev": true,
- "dependencies": {
- "arr-filter": "^1.1.1",
- "arr-flatten": "^1.0.1",
- "arr-map": "^2.0.0",
- "array-each": "^1.0.0",
- "array-initial": "^1.0.0",
- "array-last": "^1.1.1",
- "async-done": "^1.2.2",
- "async-settle": "^1.0.0",
- "now-and-later": "^2.0.0"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "node_modules/base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
- "dev": true,
- "dependencies": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/base/node_modules/define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz",
+ "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==",
"dev": true,
"dependencies": {
- "is-descriptor": "^1.0.0"
+ "async-done": "^2.0.0",
+ "async-settle": "^2.0.0",
+ "now-and-later": "^3.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=10.13.0"
}
},
- "node_modules/base/node_modules/is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "node_modules/bach/node_modules/now-and-later": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz",
+ "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==",
"dev": true,
"dependencies": {
- "kind-of": "^6.0.0"
+ "once": "^1.4.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 10.13.0"
}
},
- "node_modules/base/node_modules/is-data-descriptor": {
+ "node_modules/balanced-match": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
- "node_modules/base/node_modules/is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "node_modules/bare-events": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz",
+ "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==",
"dev": true,
- "dependencies": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
+ "optional": true
},
"node_modules/base64-js": {
"version": "1.5.1",
@@ -3024,6 +3500,15 @@
}
]
},
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.19",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
+ "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
+ "dev": true,
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
"node_modules/bent": {
"version": "7.3.12",
"resolved": "https://registry.npmjs.org/bent/-/bent-7.3.12.tgz",
@@ -3065,31 +3550,23 @@
"node": ">=8"
}
},
- "node_modules/bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "dev": true,
- "optional": true,
- "dependencies": {
- "file-uri-to-path": "1.0.0"
- }
- },
"node_modules/bl": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
"integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"readable-stream": "^2.3.5",
"safe-buffer": "^5.1.1"
}
},
"node_modules/bn.js": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
- "dev": true
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/boolbase": {
"version": "1.0.0",
@@ -3098,45 +3575,24 @@
"dev": true
},
"node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
+ "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
- "dev": true,
- "dependencies": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/braces/node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
- "is-extendable": "^0.1.0"
+ "fill-range": "^7.1.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/brorand": {
@@ -3189,60 +3645,75 @@
}
},
"node_modules/browserify-rsa": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
- "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
+ "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "bn.js": "^5.0.0",
- "randombytes": "^2.0.1"
+ "bn.js": "^5.2.1",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
}
},
"node_modules/browserify-rsa/node_modules/bn.js": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz",
+ "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/browserify-rsa/node_modules/safe-buffer": {
"version": "5.2.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
- "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
- "dev": true
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
},
"node_modules/browserify-sign": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz",
- "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==",
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz",
+ "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "bn.js": "^5.2.1",
- "browserify-rsa": "^4.1.0",
+ "bn.js": "^5.2.2",
+ "browserify-rsa": "^4.1.1",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
- "elliptic": "^6.5.4",
+ "elliptic": "^6.6.1",
"inherits": "^2.0.4",
- "parse-asn1": "^5.1.6",
- "readable-stream": "^3.6.2",
+ "parse-asn1": "^5.1.9",
+ "readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1"
},
"engines": {
- "node": ">= 4"
+ "node": ">= 0.10"
}
},
"node_modules/browserify-sign/node_modules/bn.js": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
- "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
- "dev": true
- },
- "node_modules/browserify-sign/node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz",
+ "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==",
"dev": true,
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
+ "license": "MIT"
},
"node_modules/browserify-sign/node_modules/safe-buffer": {
"version": "5.2.1",
@@ -3274,9 +3745,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.21.9",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
- "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
"dev": true,
"funding": [
{
@@ -3293,10 +3764,11 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001503",
- "electron-to-chromium": "^1.4.431",
- "node-releases": "^2.0.12",
- "update-browserslist-db": "^1.0.11"
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
},
"bin": {
"browserslist": "cli.js"
@@ -3334,6 +3806,7 @@
"resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
"integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer-alloc-unsafe": "^1.1.0",
"buffer-fill": "^1.0.0"
@@ -3343,7 +3816,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
"integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
},
"node_modules/buffer-crc32": {
"version": "0.2.13",
@@ -3354,11 +3828,18 @@
"node": "*"
}
},
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "dev": true
+ },
"node_modules/buffer-fill": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
- "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
- "dev": true
+ "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/buffer-from": {
"version": "1.1.1",
@@ -3384,31 +3865,12 @@
"integrity": "sha512-i4uu6M4zuMUiyfZN4RU2+i9+peJh//pXhd9x1oSe1LBkZ3LEbCoygu8W0bXTukU1Jme2txKuotpCZRaC3FLxcQ==",
"dev": true
},
- "node_modules/cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "dev": true,
- "dependencies": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/cacheable-request": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
"integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"clone-response": "1.0.2",
"get-stream": "3.0.0",
@@ -3419,11 +3881,22 @@
"responselike": "1.0.2"
}
},
+ "node_modules/cacheable-request/node_modules/get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/cacheable-request/node_modules/lowercase-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
- "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+ "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -3444,33 +3917,79 @@
}
},
"node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
- "dev": true,
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
"engines": {
- "node": ">=6"
+ "node": ">= 0.4"
}
},
- "node_modules/caniuse-lite": {
- "version": "1.0.30001512",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz",
- "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==",
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"dev": true,
- "funding": [
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001768",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001768.tgz",
+ "integrity": "sha512-qY3aDRZC5nWPgHUgIB84WL+nySuo19wk0VJpp/XI9T34lrvkyhRvNVOFJOp2kxClQhiFBu+TaUSudf6oa3vkSA==",
+ "dev": true,
+ "funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
@@ -3813,43 +4332,6 @@
"fsevents": "~2.3.2"
}
},
- "node_modules/chokidar/node_modules/anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/chokidar/node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/chokidar/node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/chokidar/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -3862,27 +4344,6 @@
"node": ">= 6"
}
},
- "node_modules/chokidar/node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/chokidar/node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
"node_modules/chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
@@ -3903,15 +4364,41 @@
}
},
"node_modules/cipher-base": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
- "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz",
+ "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.10"
}
},
+ "node_modules/cipher-base/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/circular-json": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
@@ -3924,33 +4411,6 @@
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
"integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="
},
- "node_modules/class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "dev": true,
- "dependencies": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/class-utils/node_modules/define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "dependencies": {
- "is-descriptor": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -3961,35 +4421,14 @@
}
},
"node_modules/cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==",
- "dev": true,
- "dependencies": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- }
- },
- "node_modules/cliui/node_modules/ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/cliui/node_modules/strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"dependencies": {
- "ansi-regex": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
}
},
"node_modules/clone": {
@@ -4027,8 +4466,9 @@
"node_modules/clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mimic-response": "^1.0.0"
}
@@ -4071,52 +4511,13 @@
"semver": "bin/semver"
}
},
- "node_modules/code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/collection-map": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
- "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
- "dev": true,
- "dependencies": {
- "arr-map": "^2.0.2",
- "for-own": "^1.0.0",
- "make-iterator": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/collection-map/node_modules/for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "dependencies": {
- "for-in": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "node_modules/cockatiel": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.1.3.tgz",
+ "integrity": "sha512-xC759TpZ69d7HhfDp8m2WkRwEUiCkxY8Ee2OQH/3H6zmy2D/5Sm+zSTbPRa+V2QyjDtpMvjOIAOVjA2gp6N1kQ==",
"dev": true,
- "dependencies": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=16"
}
},
"node_modules/color-convert": {
@@ -4134,15 +4535,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
- "node_modules/color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "dev": true,
- "bin": {
- "color-support": "bin.js"
- }
- },
"node_modules/colorette": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz",
@@ -4178,38 +4570,11 @@
"integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==",
"dev": true
},
- "node_modules/component-emitter": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
- "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
- "dev": true
- },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
- "node_modules/concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "dev": true,
- "engines": [
- "node >= 0.8"
- ],
- "dependencies": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
- }
- },
- "node_modules/confusing-browser-globals": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
- "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
- "dev": true
- },
"node_modules/console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
@@ -4223,17 +4588,39 @@
"dev": true
},
"node_modules/content-disposition": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
- "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "safe-buffer": "5.1.2"
+ "safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
}
},
+ "node_modules/content-disposition/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/continuation-local-storage": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz",
@@ -4249,23 +4636,17 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
- "node_modules/copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/copy-props": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz",
- "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz",
+ "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==",
"dev": true,
"dependencies": {
- "each-props": "^1.3.2",
+ "each-props": "^3.0.0",
"is-plain-object": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
}
},
"node_modules/copy-props/node_modules/is-plain-object": {
@@ -4314,11 +4695,16 @@
}
},
"node_modules/core-js-pure": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.4.tgz",
- "integrity": "sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA==",
+ "version": "3.42.0",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.42.0.tgz",
+ "integrity": "sha512-007bM04u91fF4kMgwom2I5cQxAFIy8jVulgr9eozILl/SZE53QOqnW/+vviC+wQWLv+AunBG+8Q0TLoeSsSxRQ==",
"dev": true,
- "hasInstallScript": true
+ "hasInstallScript": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
},
"node_modules/core-util-is": {
"version": "1.0.2",
@@ -4327,13 +4713,14 @@
"dev": true
},
"node_modules/create-ecdh": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
- "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bn.js": "^4.1.0",
- "elliptic": "^6.0.0"
+ "elliptic": "^6.5.3"
}
},
"node_modules/create-hash": {
@@ -4369,35 +4756,99 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
- "node_modules/cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
"dev": true,
"dependencies": {
- "nice-try": "^1.0.4",
- "path-key": "^2.0.1",
- "semver": "^5.5.0",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
+ "cross-spawn": "^7.0.1"
},
- "engines": {
- "node": ">=4.8"
- }
- },
- "node_modules/cross-spawn/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
"bin": {
- "semver": "bin/semver"
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
}
},
- "node_modules/cross-spawn/node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "node_modules/cross-env/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cross-env/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cross-env/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cross-env/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+ "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"dependencies": {
"isexe": "^2.0.0"
@@ -4416,35 +4867,30 @@
}
},
"node_modules/crypto-browserify": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
- "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
+ "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "browserify-cipher": "^1.0.0",
- "browserify-sign": "^4.0.0",
- "create-ecdh": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.0",
- "diffie-hellman": "^5.0.0",
- "inherits": "^2.0.1",
- "pbkdf2": "^3.0.3",
- "public-encrypt": "^4.0.0",
- "randombytes": "^2.0.0",
- "randomfill": "^1.0.3"
+ "browserify-cipher": "^1.0.1",
+ "browserify-sign": "^4.2.3",
+ "create-ecdh": "^4.0.4",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "diffie-hellman": "^5.0.3",
+ "hash-base": "~3.0.4",
+ "inherits": "^2.0.4",
+ "pbkdf2": "^3.1.2",
+ "public-encrypt": "^4.0.3",
+ "randombytes": "^2.1.0",
+ "randomfill": "^1.0.4"
},
"engines": {
- "node": "*"
- }
- },
- "node_modules/d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
- "dev": true,
- "dependencies": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/damerau-levenshtein": {
@@ -4453,6 +4899,57 @@
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
"dev": true
},
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -4482,6 +4979,7 @@
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
"integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10"
}
@@ -4491,6 +4989,7 @@
"resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz",
"integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"decompress-tar": "^4.0.0",
"decompress-tarbz2": "^4.0.0",
@@ -4508,8 +5007,9 @@
"node_modules/decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
- "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mimic-response": "^1.0.0"
},
@@ -4522,6 +5022,7 @@
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
"integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"file-type": "^5.2.0",
"is-stream": "^1.1.0",
@@ -4534,8 +5035,9 @@
"node_modules/decompress-tar/node_modules/file-type": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
- "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -4545,6 +5047,7 @@
"resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
"integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"decompress-tar": "^4.1.0",
"file-type": "^6.1.0",
@@ -4561,6 +5064,7 @@
"resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
"integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -4570,6 +5074,7 @@
"resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
"integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"decompress-tar": "^4.1.1",
"file-type": "^5.2.0",
@@ -4582,8 +5087,9 @@
"node_modules/decompress-targz/node_modules/file-type": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
- "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -4591,8 +5097,9 @@
"node_modules/decompress-unzip": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
- "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+ "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"file-type": "^3.8.0",
"get-stream": "^2.2.0",
@@ -4606,8 +5113,9 @@
"node_modules/decompress-unzip/node_modules/file-type": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
- "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
+ "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -4615,8 +5123,9 @@
"node_modules/decompress-unzip/node_modules/get-stream": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
- "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+ "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"object-assign": "^4.0.1",
"pinkie-promise": "^2.0.0"
@@ -4628,8 +5137,9 @@
"node_modules/decompress-unzip/node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -4639,6 +5149,7 @@
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
"integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"pify": "^3.0.0"
},
@@ -4649,8 +5160,9 @@
"node_modules/decompress/node_modules/make-dir/node_modules/pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -4658,8 +5170,9 @@
"node_modules/decompress/node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -4692,27 +5205,6 @@
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
- "node_modules/default-compare": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
- "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^5.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/default-compare/node_modules/kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/default-require-extensions": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
@@ -4734,76 +5226,47 @@
"node": ">=8"
}
},
- "node_modules/default-resolution": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
- "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/define-properties": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
- "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"dependencies": {
- "object-keys": "^1.0.12"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
- }
- },
- "node_modules/define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
- "dev": true,
- "dependencies": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
},
- "engines": {
- "node": ">=0.10.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/define-property/node_modules/is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "node_modules/define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
"dev": true,
- "dependencies": {
- "kind-of": "^6.0.0"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
- "node_modules/define-property/node_modules/is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
"dependencies": {
- "kind-of": "^6.0.0"
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/define-property/node_modules/is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "dependencies": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
+ "node": ">= 0.4"
},
- "engines": {
- "node": ">=0.10.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/del": {
@@ -4849,7 +5312,7 @@
"node_modules/detect-file": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
- "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -4882,10 +5345,11 @@
}
},
"node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
+ "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -4940,6 +5404,7 @@
"resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz",
"integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"archive-type": "^4.0.0",
"content-disposition": "^0.5.2",
@@ -4957,23 +5422,12 @@
"node": ">=10"
}
},
- "node_modules/download/node_modules/get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "dependencies": {
- "pump": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/download/node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"pify": "^4.0.1",
"semver": "^5.6.0"
@@ -4982,25 +5436,30 @@
"node": ">=6"
}
},
- "node_modules/download/node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/download/node_modules/semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
+ "license": "ISC",
"bin": {
"semver": "bin/semver"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -5008,10 +5467,11 @@
"dev": true
},
"node_modules/duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
- "dev": true
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
+ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==",
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/duplexify": {
"version": "3.7.1",
@@ -5026,26 +5486,55 @@
}
},
"node_modules/each-props": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
- "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz",
+ "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==",
"dev": true,
"dependencies": {
- "is-plain-object": "^2.0.1",
+ "is-plain-object": "^5.0.0",
"object.defaults": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/each-props/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.450",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz",
- "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==",
+ "version": "1.5.286",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
+ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
"dev": true
},
"node_modules/elliptic": {
- "version": "6.5.4",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
- "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+ "version": "6.6.1",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
+ "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
@@ -5056,12 +5545,6 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
- "node_modules/elliptic/node_modules/bn.js": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
- "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
- "dev": true
- },
"node_modules/emitter-listener": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz",
@@ -5086,52 +5569,31 @@
}
},
"node_modules/end-of-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
- "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/enhanced-resolve": {
- "version": "5.12.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
- "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
+ "version": "5.19.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
+ "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
+ "tapable": "^2.3.0"
},
"engines": {
"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.1.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
- "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+ "node_modules/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
"dev": true,
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
@@ -5149,41 +5611,58 @@
"node": ">=4"
}
},
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
"node_modules/es-abstract": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz",
- "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.2",
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.1.1",
- "get-symbol-description": "^1.0.0",
- "has": "^1.0.3",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
- "is-callable": "^1.2.4",
- "is-negative-zero": "^2.0.2",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.1",
+ "is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
+ "is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
- "object-inspect": "^1.12.0",
+ "object-inspect": "^1.13.1",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.2",
- "string.prototype.trimend": "^1.0.4",
- "string.prototype.trimstart": "^1.0.4",
- "unbox-primitive": "^1.0.1"
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.2",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.15"
},
"engines": {
"node": ">= 0.4"
@@ -5192,12 +5671,64 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.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==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-module-lexer": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
- "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+ "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
"dev": true
},
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+ "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.0"
+ }
+ },
"node_modules/es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
@@ -5215,72 +5746,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/es5-ext": {
- "version": "0.10.53",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
- "dev": true,
- "dependencies": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.3",
- "next-tick": "~1.0.0"
- }
- },
- "node_modules/es5-ext/node_modules/next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
- "dev": true
- },
"node_modules/es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"dev": true
},
- "node_modules/es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "dev": true,
- "dependencies": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
"node_modules/es6-object-assign": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=",
"dev": true
},
- "node_modules/es6-symbol": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
- "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
- "dev": true,
- "dependencies": {
- "d": "^1.0.1",
- "ext": "^1.1.2"
- }
- },
- "node_modules/es6-weak-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
- "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
- "dev": true,
- "dependencies": {
- "d": "1",
- "es5-ext": "^0.10.46",
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.1"
- }
- },
"node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
"engines": {
"node": ">=6"
@@ -5296,101 +5777,62 @@
}
},
"node_modules/eslint": {
- "version": "7.32.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
- "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@babel/code-frame": "7.12.11",
- "@eslint/eslintrc": "^0.4.3",
- "@humanwhocodes/config-array": "^0.5.0",
- "ajv": "^6.10.0",
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
- "debug": "^4.0.1",
+ "debug": "^4.3.2",
"doctrine": "^3.0.0",
- "enquirer": "^2.3.5",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^5.1.1",
- "eslint-utils": "^2.1.0",
- "eslint-visitor-keys": "^2.0.0",
- "espree": "^7.3.1",
- "esquery": "^1.4.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
- "functional-red-black-tree": "^1.0.1",
- "glob-parent": "^5.1.2",
- "globals": "^13.6.0",
- "ignore": "^4.0.6",
- "import-fresh": "^3.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
- "js-yaml": "^3.13.1",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
- "optionator": "^0.9.1",
- "progress": "^2.0.0",
- "regexpp": "^3.1.0",
- "semver": "^7.2.1",
- "strip-ansi": "^6.0.0",
- "strip-json-comments": "^3.1.0",
- "table": "^6.0.9",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
},
"bin": {
"eslint": "bin/eslint.js"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint-config-airbnb": {
- "version": "18.2.1",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz",
- "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==",
- "dev": true,
- "dependencies": {
- "eslint-config-airbnb-base": "^14.2.1",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.2"
- },
- "engines": {
- "node": ">= 6"
- },
- "peerDependencies": {
- "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
- "eslint-plugin-import": "^2.22.1",
- "eslint-plugin-jsx-a11y": "^6.4.1",
- "eslint-plugin-react": "^7.21.5",
- "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0"
- }
- },
- "node_modules/eslint-config-airbnb-base": {
- "version": "14.2.1",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz",
- "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==",
- "dev": true,
- "dependencies": {
- "confusing-browser-globals": "^1.0.10",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.2"
- },
- "engines": {
- "node": ">= 6"
- },
- "peerDependencies": {
- "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0",
- "eslint-plugin-import": "^2.22.1"
- }
- },
"node_modules/eslint-config-prettier": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
@@ -5404,13 +5846,14 @@
}
},
"node_modules/eslint-import-resolver-node": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
- "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
"dev": true,
"dependencies": {
"debug": "^3.2.7",
- "resolve": "^1.20.0"
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
}
},
"node_modules/eslint-import-resolver-node/node_modules/debug": {
@@ -5423,16 +5866,21 @@
}
},
"node_modules/eslint-module-utils": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
- "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "debug": "^3.2.7",
- "find-up": "^2.1.0"
+ "debug": "^3.2.7"
},
"engines": {
"node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
}
},
"node_modules/eslint-module-utils/node_modules/debug": {
@@ -5440,100 +5888,60 @@
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ms": "^2.1.1"
}
},
- "node_modules/eslint-module-utils/node_modules/find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
- "dev": true,
- "dependencies": {
- "locate-path": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
- "dev": true,
- "dependencies": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "dependencies": {
- "p-try": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
- "dev": true,
- "dependencies": {
- "p-limit": "^1.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/eslint-plugin-import": {
- "version": "2.25.4",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz",
- "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "array-includes": "^3.1.4",
- "array.prototype.flat": "^1.2.5",
- "debug": "^2.6.9",
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlastindex": "^1.2.5",
+ "array.prototype.flat": "^1.3.2",
+ "array.prototype.flatmap": "^1.3.2",
+ "debug": "^3.2.7",
"doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.6",
- "eslint-module-utils": "^2.7.2",
- "has": "^1.0.3",
- "is-core-module": "^2.8.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.0",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
- "minimatch": "^3.0.4",
- "object.values": "^1.1.5",
- "resolve": "^1.20.0",
- "tsconfig-paths": "^3.12.0"
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.0",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
+ "tsconfig-paths": "^3.15.0"
},
"engines": {
"node": ">=4"
},
"peerDependencies": {
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
}
},
"node_modules/eslint-plugin-import/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -5541,6 +5949,15 @@
"node": "*"
}
},
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
"node_modules/eslint-plugin-jsx-a11y": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz",
@@ -5587,10 +6004,11 @@
"dev": true
},
"node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -5598,6 +6016,16 @@
"node": "*"
}
},
+ "node_modules/eslint-plugin-no-only-tests": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz",
+ "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=5.0.0"
+ }
+ },
"node_modules/eslint-plugin-react": {
"version": "7.29.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz",
@@ -5648,10 +6076,11 @@
}
},
"node_modules/eslint-plugin-react/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -5694,28 +6123,17 @@
"node": ">=8.0.0"
}
},
- "node_modules/eslint-utils": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
- "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
- "dependencies": {
- "eslint-visitor-keys": "^1.1.0"
- },
+ "license": "Apache-2.0",
"engines": {
- "node": ">=6"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
- "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
- "dev": true,
- "engines": {
- "node": ">=4"
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/ansi-styles": {
@@ -5734,6 +6152,13 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/eslint/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
"node_modules/eslint/node_modules/chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
@@ -5769,10 +6194,11 @@
"dev": true
},
"node_modules/eslint/node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -5823,32 +6249,69 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/eslint/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==",
+ "node_modules/eslint/node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/eslint/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
+ "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/eslint/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==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "is-glob": "^4.0.1"
+ "is-glob": "^4.0.3"
},
"engines": {
- "node": ">= 6"
+ "node": ">=10.13.0"
}
},
"node_modules/eslint/node_modules/globals": {
- "version": "13.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
- "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"type-fest": "^0.20.2"
},
@@ -5868,20 +6331,40 @@
"node": ">=8"
}
},
- "node_modules/eslint/node_modules/ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "node_modules/eslint/node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/eslint/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
"engines": {
- "node": ">= 4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -5889,6 +6372,38 @@
"node": "*"
}
},
+ "node_modules/eslint/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/eslint/node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
@@ -5898,15 +6413,6 @@
"node": ">=8"
}
},
- "node_modules/eslint/node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true,
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/eslint/node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -5945,6 +6451,7 @@
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
"dev": true,
+ "license": "(MIT OR CC0-1.0)",
"engines": {
"node": ">=10"
},
@@ -5953,36 +6460,29 @@
}
},
"node_modules/espree": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
- "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "acorn": "^7.4.0",
- "acorn-jsx": "^5.3.1",
- "eslint-visitor-keys": "^1.3.0"
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/espree/node_modules/acorn": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
- "dev": true,
- "bin": {
- "acorn": "bin/acorn"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
- "engines": {
- "node": ">=0.4.0"
+ "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.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"estraverse": "^5.1.0"
},
@@ -5995,6 +6495,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"
}
@@ -6081,10 +6582,11 @@
}
},
"node_modules/execa/node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -6148,48 +6650,6 @@
"node": ">=8"
}
},
- "node_modules/expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "dependencies": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/expand-brackets/node_modules/define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "dependencies": {
- "is-descriptor": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/expand-brackets/node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "dependencies": {
- "is-extendable": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -6203,7 +6663,7 @@
"node_modules/expand-tilde": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
- "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
"dev": true,
"dependencies": {
"homedir-polyfill": "^1.0.1"
@@ -6228,20 +6688,12 @@
"webpack": "^5.0.0"
}
},
- "node_modules/ext": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
- "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
- "dev": true,
- "dependencies": {
- "type": "^2.5.0"
- }
- },
"node_modules/ext-list": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
"integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"mime-db": "^1.28.0"
},
@@ -6254,6 +6706,7 @@
"resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
"integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"ext-list": "^2.0.0",
"sort-keys-length": "^1.0.0"
@@ -6262,12 +6715,6 @@
"node": ">=4"
}
},
- "node_modules/ext/node_modules/type": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz",
- "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==",
- "dev": true
- },
"node_modules/extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -6299,108 +6746,18 @@
"node": ">=0.10.0"
}
},
- "node_modules/extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "dependencies": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/extglob/node_modules/define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "dependencies": {
- "is-descriptor": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/extglob/node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "dependencies": {
- "is-extendable": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/extglob/node_modules/is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/extglob/node_modules/is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/extglob/node_modules/is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "dependencies": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fancy-log": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
- "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
- "dev": true,
- "dependencies": {
- "ansi-gray": "^0.1.1",
- "color-support": "^1.1.3",
- "parse-node-version": "^1.0.0",
- "time-stamp": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
+ "node_modules/fast-fifo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+ "dev": true
+ },
"node_modules/fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -6417,30 +6774,6 @@
"node": ">=8.6.0"
}
},
- "node_modules/fast-glob/node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fast-glob/node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"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",
@@ -6453,40 +6786,6 @@
"node": ">= 6"
}
},
- "node_modules/fast-glob/node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/fast-glob/node_modules/micromatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
- "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.1",
- "picomatch": "^2.2.3"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/fast-glob/node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
"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",
@@ -6499,10 +6798,21 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
- "node_modules/fast-myers-diff": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fast-myers-diff/-/fast-myers-diff-3.0.1.tgz",
- "integrity": "sha512-e8p26utONwDXeSDkDqu4jaR3l3r6ZgQO2GWB178ePZxCfFoRPNTJVZylUEHHG6uZeRikL1zCc2sl4sIAs9c0UQ=="
+ "node_modules/fast-uri": {
+ "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": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ]
},
"node_modules/fastest-levenshtein": {
"version": "1.0.12",
@@ -6545,22 +6855,17 @@
"resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz",
"integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
- "node_modules/file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "dev": true,
- "optional": true
- },
"node_modules/filename-reserved-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
- "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
+ "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -6570,6 +6875,7 @@
"resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz",
"integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"filename-reserved-regex": "^2.0.0",
"strip-outer": "^1.0.0",
@@ -6580,30 +6886,15 @@
}
},
"node_modules/fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
- "dev": true,
- "dependencies": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/fill-range/node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
- "is-extendable": "^0.1.0"
+ "to-regex-range": "^5.0.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/filter-obj": {
@@ -6645,53 +6936,53 @@
"node": ">=8"
}
},
- "node_modules/find-up/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/findup-sync": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
- "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
"dev": true,
"dependencies": {
"detect-file": "^1.0.0",
- "is-glob": "^4.0.0",
- "micromatch": "^3.0.4",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
"resolve-dir": "^1.0.1"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/fined": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
- "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz",
+ "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==",
"dev": true,
"dependencies": {
"expand-tilde": "^2.0.2",
- "is-plain-object": "^2.0.3",
+ "is-plain-object": "^5.0.0",
"object.defaults": "^1.1.0",
- "object.pick": "^1.2.0",
- "parse-filepath": "^1.0.1"
+ "object.pick": "^1.3.0",
+ "parse-filepath": "^1.0.2"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/fined/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
}
},
"node_modules/flagged-respawn": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
- "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz",
+ "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==",
"dev": true,
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/flat": {
@@ -6717,9 +7008,9 @@
}
},
"node_modules/flatted": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz",
- "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
"dev": true
},
"node_modules/flush-write-stream": {
@@ -6732,39 +7023,42 @@
"readable-stream": "^2.3.6"
}
},
- "node_modules/follow-redirects": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
- "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
+ "node_modules/for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
"engines": {
- "node": ">=4.0"
+ "node": ">= 0.4"
},
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/foreach": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
- "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
- "dev": true
+ "node_modules/for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "dev": true,
+ "dependencies": {
+ "for-in": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
},
"node_modules/foreground-child": {
"version": "2.0.0",
@@ -6780,10 +7074,11 @@
}
},
"node_modules/foreground-child/node_modules/cross-spawn": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
- "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -6824,35 +7119,26 @@
}
},
"node_modules/form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
- "node_modules/fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "dev": true,
- "dependencies": {
- "map-cache": "^0.2.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
- "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"inherits": "^2.0.1",
"readable-stream": "^2.0.0"
@@ -6871,16 +7157,16 @@
"dev": true
},
"node_modules/fs-extra": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
- "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=14.14"
}
},
"node_modules/fs-extra/node_modules/jsonfile": {
@@ -6944,15 +7230,39 @@
}
},
"node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "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/function.prototype.name": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
@@ -6964,10 +7274,13 @@
}
},
"node_modules/get-caller-file": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
- "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
- "dev": true
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
},
"node_modules/get-func-name": {
"version": "2.0.2",
@@ -6979,14 +7292,24 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
- "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
- "dev": true,
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1"
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7013,23 +7336,52 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
"engines": {
- "node": ">=4"
+ "node": ">=6"
+ }
+ },
+ "node_modules/get-stream/node_modules/pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
}
},
"node_modules/get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
@@ -7038,15 +7390,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -7123,104 +7466,23 @@
"dev": true
},
"node_modules/glob-watcher": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz",
- "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==",
- "dev": true,
- "dependencies": {
- "anymatch": "^2.0.0",
- "async-done": "^1.2.0",
- "chokidar": "^2.0.0",
- "is-negated-glob": "^1.0.0",
- "just-debounce": "^1.0.0",
- "normalize-path": "^3.0.0",
- "object.defaults": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/glob-watcher/node_modules/binary-extensions": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
- "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/glob-watcher/node_modules/chokidar": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
- "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
- "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies",
- "dev": true,
- "dependencies": {
- "anymatch": "^2.0.0",
- "async-each": "^1.0.1",
- "braces": "^2.3.2",
- "glob-parent": "^3.1.0",
- "inherits": "^2.0.3",
- "is-binary-path": "^1.0.0",
- "is-glob": "^4.0.0",
- "normalize-path": "^3.0.0",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.2.1",
- "upath": "^1.1.1"
- },
- "optionalDependencies": {
- "fsevents": "^1.2.7"
- }
- },
- "node_modules/glob-watcher/node_modules/fsevents": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
- "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
- "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "dependencies": {
- "bindings": "^1.5.0",
- "nan": "^2.12.1"
- },
- "engines": {
- "node": ">= 4.0"
- }
- },
- "node_modules/glob-watcher/node_modules/is-binary-path": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/glob-watcher/node_modules/readdirp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
- "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz",
+ "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==",
"dev": true,
"dependencies": {
- "graceful-fs": "^4.1.11",
- "micromatch": "^3.1.10",
- "readable-stream": "^2.0.2"
+ "async-done": "^2.0.0",
+ "chokidar": "^3.5.3"
},
"engines": {
- "node": ">=0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/glob/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -7245,7 +7507,7 @@
"node_modules/global-prefix": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
- "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
"dev": true,
"dependencies": {
"expand-tilde": "^2.0.2",
@@ -7279,6 +7541,22 @@
"node": ">=4"
}
},
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -7300,15 +7578,27 @@
}
},
"node_modules/glogg": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
- "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz",
+ "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==",
"dev": true,
"dependencies": {
- "sparkles": "^1.0.0"
+ "sparkles": "^2.1.0"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/got": {
@@ -7316,6 +7606,7 @@
"resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
"integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@sindresorhus/is": "^0.7.0",
"cacheable-request": "^2.1.1",
@@ -7339,129 +7630,176 @@
"node": ">=4"
}
},
+ "node_modules/got/node_modules/get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/got/node_modules/pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/graceful-fs": {
- "version": "4.2.9",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
- "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
},
- "node_modules/graceful-readlink": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
- "node_modules/growl": {
- "version": "1.10.5",
- "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
- "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
- "dev": true,
- "engines": {
- "node": ">=4.x"
- }
- },
"node_modules/gulp": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
- "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz",
+ "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==",
"dev": true,
"dependencies": {
- "glob-watcher": "^5.0.3",
- "gulp-cli": "^2.2.0",
- "undertaker": "^1.2.1",
- "vinyl-fs": "^3.0.0"
+ "glob-watcher": "^6.0.0",
+ "gulp-cli": "^3.0.0",
+ "undertaker": "^2.0.0",
+ "vinyl-fs": "^4.0.0"
},
"bin": {
"gulp": "bin/gulp.js"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">=10.13.0"
}
},
"node_modules/gulp-cli": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz",
- "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==",
- "dev": true,
- "dependencies": {
- "ansi-colors": "^1.0.1",
- "archy": "^1.0.0",
- "array-sort": "^1.0.0",
- "color-support": "^1.1.3",
- "concat-stream": "^1.6.0",
- "copy-props": "^2.0.1",
- "fancy-log": "^1.3.2",
- "gulplog": "^1.0.0",
- "interpret": "^1.4.0",
- "isobject": "^3.0.1",
- "liftoff": "^3.1.0",
- "matchdep": "^2.0.0",
- "mute-stdout": "^1.0.0",
- "pretty-hrtime": "^1.0.0",
- "replace-homedir": "^1.0.0",
- "semver-greatest-satisfied-range": "^1.1.0",
- "v8flags": "^3.2.0",
- "yargs": "^7.1.0"
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz",
+ "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==",
+ "dev": true,
+ "dependencies": {
+ "@gulpjs/messages": "^1.1.0",
+ "chalk": "^4.1.2",
+ "copy-props": "^4.0.0",
+ "gulplog": "^2.2.0",
+ "interpret": "^3.1.1",
+ "liftoff": "^5.0.0",
+ "mute-stdout": "^2.0.0",
+ "replace-homedir": "^2.0.0",
+ "semver-greatest-satisfied-range": "^2.0.0",
+ "string-width": "^4.2.3",
+ "v8flags": "^4.0.0",
+ "yargs": "^16.2.0"
},
"bin": {
"gulp": "bin/gulp.js"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">=10.13.0"
}
},
- "node_modules/gulp-cli/node_modules/camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
+ "node_modules/gulp-cli/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/gulp-cli/node_modules/y18n": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
- "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
- "dev": true
- },
- "node_modules/gulp-cli/node_modules/yargs": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz",
- "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
- "dev": true,
+ "node_modules/gulp-cli/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
"dependencies": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^5.0.1"
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/gulp-cli/node_modules/yargs-parser": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz",
- "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
+ "node_modules/gulp-cli/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/gulp-cli/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/gulp-cli/node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"dependencies": {
- "camelcase": "^3.0.0",
- "object.assign": "^4.1.0"
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/gulp-typescript": {
@@ -7512,16 +7850,187 @@
"readable-stream": "2 || 3"
}
},
+ "node_modules/gulp/node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/gulp/node_modules/fs-mkdirp-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz",
+ "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.8",
+ "streamx": "^2.12.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/glob-stream": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz",
+ "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==",
+ "dev": true,
+ "dependencies": {
+ "@gulpjs/to-absolute-glob": "^4.0.0",
+ "anymatch": "^3.1.3",
+ "fastq": "^1.13.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "is-negated-glob": "^1.0.0",
+ "normalize-path": "^3.0.0",
+ "streamx": "^2.12.5"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/lead": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz",
+ "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/now-and-later": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz",
+ "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/gulp/node_modules/resolve-options": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz",
+ "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==",
+ "dev": true,
+ "dependencies": {
+ "value-or-function": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/to-through": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz",
+ "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==",
+ "dev": true,
+ "dependencies": {
+ "streamx": "^2.12.5"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/value-or-function": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz",
+ "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "dependencies": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/vinyl-fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz",
+ "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==",
+ "dev": true,
+ "dependencies": {
+ "fs-mkdirp-stream": "^2.0.1",
+ "glob-stream": "^8.0.0",
+ "graceful-fs": "^4.2.11",
+ "iconv-lite": "^0.6.3",
+ "is-valid-glob": "^1.0.0",
+ "lead": "^4.0.0",
+ "normalize-path": "3.0.0",
+ "resolve-options": "^2.0.0",
+ "stream-composer": "^1.0.2",
+ "streamx": "^2.14.0",
+ "to-through": "^3.0.0",
+ "value-or-function": "^4.0.0",
+ "vinyl": "^3.0.0",
+ "vinyl-sourcemap": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/gulp/node_modules/vinyl-sourcemap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz",
+ "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==",
+ "dev": true,
+ "dependencies": {
+ "convert-source-map": "^2.0.0",
+ "graceful-fs": "^4.2.10",
+ "now-and-later": "^3.0.0",
+ "streamx": "^2.12.5",
+ "vinyl": "^3.0.0",
+ "vinyl-contents": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/gulplog": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
- "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz",
+ "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==",
"dev": true,
"dependencies": {
- "glogg": "^1.0.0"
+ "glogg": "^2.2.0"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/gzip-size": {
@@ -7543,6 +8052,7 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
@@ -7551,9 +8061,9 @@
}
},
"node_modules/has-bigints": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
- "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7568,20 +8078,45 @@
"node": ">=4"
}
},
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/has-symbol-support-x": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
"integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "dev": true,
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -7594,6 +8129,7 @@
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
"integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-symbol-support-x": "^1.4.1"
},
@@ -7602,12 +8138,11 @@
}
},
"node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
- "dev": true,
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dependencies": {
- "has-symbols": "^1.0.2"
+ "has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -7616,45 +8151,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
- "dev": true,
- "dependencies": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "dev": true,
- "dependencies": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/has-values/node_modules/kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "dev": true,
- "dependencies": {
- "is-buffer": "^1.1.5"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/hash-base": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
@@ -7672,6 +8168,7 @@
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
"dependencies": {
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.1"
@@ -7699,6 +8196,17 @@
"node": ">=8"
}
},
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -7731,12 +8239,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true
- },
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -7747,7 +8249,8 @@
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
"integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
- "dev": true
+ "dev": true,
+ "license": "BSD-2-Clause"
},
"node_modules/http-proxy-agent": {
"version": "4.0.1",
@@ -7855,9 +8358,9 @@
]
},
"node_modules/ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -7870,10 +8373,11 @@
"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==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@@ -7890,6 +8394,7 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -7963,13 +8468,13 @@
"dev": true
},
"node_modules/internal-slot": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
- "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+ "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.0",
- "has": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.0",
"side-channel": "^1.0.4"
},
"engines": {
@@ -7977,19 +8482,20 @@
}
},
"node_modules/interpret": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
- "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
"dev": true,
"engines": {
- "node": ">= 0.10"
+ "node": ">=10.13.0"
}
},
"node_modules/into-stream": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
- "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
+ "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"from2": "^2.1.1",
"p-is-promise": "^1.1.0"
@@ -7999,18 +8505,9 @@
}
},
"node_modules/inversify": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.0.5.tgz",
- "integrity": "sha512-60QsfPz8NAU/GZqXu8hJ+BhNf/C/c+Hp0eDc6XMIJTxBiP36AQyyQKpBkOVTLWBFDQWYVHpbbEuIsHu9dLuJDA=="
- },
- "node_modules/invert-kv": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
- "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.2.tgz",
+ "integrity": "sha512-i9m8j/7YIv4mDuYXUAcrpKPSaju/CIly9AHK5jvCBeoiM/2KEsuCQTTP+rzSWWpLYWRukdXFSl6ZTk2/uumbiA=="
},
"node_modules/is-absolute": {
"version": "1.0.0",
@@ -8025,38 +8522,30 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "node_modules/is-arguments": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+ "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
"dev": true,
"dependencies": {
- "kind-of": "^3.0.2"
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-accessor-descriptor/node_modules/kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "dependencies": {
- "is-buffer": "^1.1.5"
+ "node": ">= 0.4"
},
- "engines": {
- "node": ">=0.10.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-arguments": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
- "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "node_modules/is-array-buffer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "get-intrinsic": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@@ -8065,17 +8554,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
- },
"node_modules/is-bigint": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
- "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
"dev": true,
+ "dependencies": {
+ "has-bigints": "^1.0.1"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -8092,6 +8578,22 @@
"node": ">=8"
}
},
+ "node_modules/is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -8099,9 +8601,9 @@
"dev": true
},
"node_modules/is-callable": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
- "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -8111,38 +8613,33 @@
}
},
"node_modules/is-core-module": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
- "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+ "license": "MIT",
"dependencies": {
- "has": "^1.0.3"
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "node_modules/is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
"dev": true,
"dependencies": {
- "kind-of": "^3.0.2"
+ "is-typed-array": "^1.1.13"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-data-descriptor/node_modules/kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "dependencies": {
- "is-buffer": "^1.1.5"
+ "node": ">= 0.4"
},
- "engines": {
- "node": ">=0.10.0"
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-date-object": {
@@ -8160,36 +8657,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true,
- "dependencies": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
+ "bin": {
+ "is-docker": "cli.js"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-descriptor/node_modules/kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-extglob": {
@@ -8202,15 +8682,12 @@
}
},
"node_modules/is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
- "dependencies": {
- "number-is-nan": "^1.0.0"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/is-generator-function": {
@@ -8259,8 +8736,9 @@
"node_modules/is-natural-number": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
- "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=",
- "dev": true
+ "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/is-negated-glob": {
"version": "1.0.0",
@@ -8272,9 +8750,9 @@
}
},
"node_modules/is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true,
"engines": {
"node": ">= 0.4"
@@ -8284,34 +8762,38 @@
}
},
"node_modules/is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
- "dependencies": {
- "kind-of": "^3.0.2"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=0.12.0"
}
},
- "node_modules/is-number/node_modules/kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "node_modules/is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
"dev": true,
"dependencies": {
- "is-buffer": "^1.1.5"
+ "has-tostringtag": "^1.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-object": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
- "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
- "dev": true
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/is-path-cwd": {
"version": "2.2.0",
@@ -8334,8 +8816,9 @@
"node_modules/is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -8381,19 +8864,26 @@
}
},
"node_modules/is-retry-allowed": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
- "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-shared-array-buffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
- "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
"dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -8401,8 +8891,9 @@
"node_modules/is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -8438,16 +8929,13 @@
}
},
"node_modules/is-typed-array": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz",
- "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "es-abstract": "^1.18.5",
- "foreach": "^2.0.5",
- "has-tostringtag": "^1.0.0"
+ "which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
@@ -8522,6 +9010,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -8605,10 +9105,11 @@
}
},
"node_modules/istanbul-lib-processinfo/node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -8660,6 +9161,15 @@
"node": ">=8"
}
},
+ "node_modules/istanbul-lib-processinfo/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/istanbul-lib-report": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
@@ -8744,6 +9254,7 @@
"resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
"integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"has-to-string-tag-x": "^1.2.0",
"is-object": "^1.0.1"
@@ -8752,6 +9263,22 @@
"node": ">= 4"
}
},
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
"node_modules/jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -8797,9 +9324,9 @@
"dev": true
},
"node_modules/js-yaml": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
- "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true,
"dependencies": {
"argparse": "^1.0.7",
@@ -8837,8 +9364,9 @@
"node_modules/json-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
- "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
- "dev": true
+ "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
@@ -8875,6 +9403,49 @@
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "dev": true,
+ "dependencies": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/jsonwebtoken/node_modules/jwa": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
+ "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "dev": true,
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jsonwebtoken/node_modules/jws": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz",
+ "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==",
+ "dev": true,
+ "dependencies": {
+ "jwa": "^1.4.2",
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/jsx-ast-utils": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz",
@@ -8900,18 +9471,33 @@
"setimmediate": "^1.0.5"
}
},
- "node_modules/just-debounce": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
- "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
- "dev": true
- },
"node_modules/just-extend": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
- "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
+ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
"dev": true
},
+ "node_modules/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "dev": true,
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
+ "dev": true,
+ "dependencies": {
+ "jwa": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/keytar": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -8929,6 +9515,7 @@
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
"integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"json-buffer": "3.0.0"
}
@@ -8958,16 +9545,12 @@
}
},
"node_modules/last-run": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
- "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz",
+ "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==",
"dev": true,
- "dependencies": {
- "default-resolution": "^2.0.0",
- "es6-weak-map": "^2.0.1"
- },
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/lazystream": {
@@ -8982,18 +9565,6 @@
"node": ">= 0.6.3"
}
},
- "node_modules/lcid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==",
- "dev": true,
- "dependencies": {
- "invert-kv": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/lead": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
@@ -9038,22 +9609,30 @@
}
},
"node_modules/liftoff": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
- "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz",
+ "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==",
"dev": true,
"dependencies": {
- "extend": "^3.0.0",
- "findup-sync": "^3.0.0",
- "fined": "^1.0.1",
- "flagged-respawn": "^1.0.0",
- "is-plain-object": "^2.0.4",
- "object.map": "^1.0.0",
- "rechoir": "^0.6.2",
- "resolve": "^1.1.7"
+ "extend": "^3.0.2",
+ "findup-sync": "^5.0.0",
+ "fined": "^2.0.0",
+ "flagged-respawn": "^2.0.0",
+ "is-plain-object": "^5.0.0",
+ "rechoir": "^0.8.0",
+ "resolve": "^1.20.0"
},
"engines": {
- "node": ">= 0.8"
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/liftoff/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
}
},
"node_modules/linkify-it": {
@@ -9065,38 +9644,17 @@
"uc.micro": "^1.0.1"
}
},
- "node_modules/load-json-file": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
- "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^2.2.0",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "strip-bom": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/load-json-file/node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/loader-runner": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
- "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz",
+ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
"dev": true,
"engines": {
"node": ">=6.11.5"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
"node_modules/loader-utils": {
@@ -9126,15 +9684,9 @@
}
},
"node_modules/lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "node_modules/lodash._reinterpolate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
- "dev": true
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="
},
"node_modules/lodash.flattendeep": {
"version": "4.4.0",
@@ -9145,44 +9697,55 @@
"node_modules/lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"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==",
+ "node_modules/lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
"dev": true
},
- "node_modules/lodash.some": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
- "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=",
+ "node_modules/lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"dev": true
},
- "node_modules/lodash.template": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
- "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
- "dev": true,
- "dependencies": {
- "lodash._reinterpolate": "^3.0.0",
- "lodash.templatesettings": "^4.0.0"
- }
+ "node_modules/lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "dev": true
},
- "node_modules/lodash.templatesettings": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
- "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
- "dev": true,
- "dependencies": {
- "lodash._reinterpolate": "^3.0.0"
- }
+ "node_modules/lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "dev": true
},
- "node_modules/lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "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/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"dev": true
},
"node_modules/log-symbols": {
@@ -9297,6 +9860,7 @@
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -9342,35 +9906,11 @@
"integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
"dev": true
},
- "node_modules/make-iterator": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
- "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
"dev": true,
- "dependencies": {
- "object-visit": "^1.0.0"
- },
"engines": {
"node": ">=0.10.0"
}
@@ -9397,46 +9937,13 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
- "node_modules/matchdep": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
- "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
- "dev": true,
- "dependencies": {
- "findup-sync": "^2.0.0",
- "micromatch": "^3.0.4",
- "resolve": "^1.4.0",
- "stack-trace": "0.0.10"
- },
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/matchdep/node_modules/findup-sync": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
- "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
- "dev": true,
- "dependencies": {
- "detect-file": "^1.0.0",
- "is-glob": "^3.1.0",
- "micromatch": "^3.0.4",
- "resolve-dir": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/matchdep/node_modules/is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.0"
- },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
"node_modules/md5": {
@@ -9482,27 +9989,16 @@
}
},
"node_modules/micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"dependencies": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8.6"
}
},
"node_modules/miller-rabin": {
@@ -9563,6 +10059,7 @@
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -9570,7 +10067,8 @@
"node_modules/minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
},
"node_modules/minimalistic-crypto-utils": {
"version": "1.0.1",
@@ -9579,9 +10077,9 @@
"dev": true
},
"node_modules/minimatch": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
- "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz",
+ "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
@@ -9590,9 +10088,9 @@
}
},
"node_modules/minimatch/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "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==",
"dependencies": {
"balanced-match": "^1.0.0"
}
@@ -9603,29 +10101,14 @@
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
- "node_modules/mixin-deep": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
- "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
- "dev": true,
- "dependencies": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/mixin-deep/node_modules/is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
- "dependencies": {
- "is-plain-object": "^2.0.4"
- },
+ "license": "ISC",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/mkdirp": {
@@ -9648,46 +10131,40 @@
"optional": true
},
"node_modules/mocha": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
- "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
- "dev": true,
- "dependencies": {
- "@ungap/promise-all-settled": "1.1.2",
- "ansi-colors": "4.1.1",
- "browser-stdout": "1.3.1",
- "chokidar": "3.5.3",
- "debug": "4.3.3",
- "diff": "5.0.0",
- "escape-string-regexp": "4.0.0",
- "find-up": "5.0.0",
- "glob": "7.2.0",
- "growl": "1.10.5",
- "he": "1.2.0",
- "js-yaml": "4.1.0",
- "log-symbols": "4.1.0",
- "minimatch": "4.2.1",
- "ms": "2.1.3",
- "nanoid": "3.3.1",
- "serialize-javascript": "6.0.0",
- "strip-json-comments": "3.1.1",
- "supports-color": "8.1.1",
- "which": "2.0.2",
- "workerpool": "6.2.0",
- "yargs": "16.2.0",
- "yargs-parser": "20.2.4",
- "yargs-unparser": "2.0.0"
+ "version": "11.7.5",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz",
+ "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^4.0.1",
+ "debug": "^4.3.5",
+ "diff": "^7.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^10.4.5",
+ "he": "^1.2.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^9.0.5",
+ "ms": "^2.1.3",
+ "picocolors": "^1.1.1",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^9.2.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1",
+ "yargs-unparser": "^2.0.0"
},
"bin": {
"_mocha": "bin/_mocha",
- "mocha": "bin/mocha"
+ "mocha": "bin/mocha.js"
},
"engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/mochajs"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/mocha-junit-reporter": {
@@ -9739,72 +10216,75 @@
}
}
},
- "node_modules/mocha/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==",
+ "node_modules/mocha/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/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==",
"dev": true,
- "engines": {
- "node": ">=6"
+ "dependencies": {
+ "balanced-match": "^1.0.0"
}
},
- "node_modules/mocha/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==",
+ "node_modules/mocha/node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "color-convert": "^2.0.1"
+ "readdirp": "^4.0.1"
},
"engines": {
- "node": ">=8"
+ "node": ">= 14.16.0"
},
"funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ "url": "https://paulmillr.com/funding/"
}
},
- "node_modules/mocha/node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
"node_modules/mocha/node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
+ "strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
- "node_modules/mocha/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==",
+ "node_modules/mocha/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "color-name": "~1.1.4"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">= 8"
}
},
- "node_modules/mocha/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/mocha/node_modules/debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -9815,17 +10295,12 @@
}
}
},
- "node_modules/mocha/node_modules/debug/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
"node_modules/mocha/node_modules/diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -9858,13 +10333,43 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/mocha/node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "node_modules/mocha/node_modules/foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
"engines": {
- "node": "6.* || 8.* || >= 10.*"
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/mocha/node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/has-flag": {
@@ -9876,19 +10381,10 @@
"node": ">=8"
}
},
- "node_modules/mocha/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/mocha/node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"dependencies": {
"argparse": "^2.0.1"
@@ -9913,15 +10409,19 @@
}
},
"node_modules/mocha/node_modules/minimatch": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
- "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
+ "license": "ISC",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "brace-expansion": "^2.0.2"
},
"engines": {
- "node": ">=10"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/ms": {
@@ -9930,18 +10430,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "node_modules/mocha/node_modules/nanoid": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
- "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
- "dev": true,
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
"node_modules/mocha/node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -9972,59 +10460,79 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/mocha/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "node_modules/mocha/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=8"
}
},
- "node_modules/mocha/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "node_modules/mocha/node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
+ "license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
}
},
- "node_modules/mocha/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "node_modules/mocha/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-flag": "^4.0.0"
+ "shebang-regex": "^3.0.0"
},
"engines": {
- "node": ">=10"
- },
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mocha/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
"funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/mocha/node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "node_modules/mocha/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"dev": true,
"dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
+ "has-flag": "^4.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/mocha/node_modules/y18n": {
@@ -10032,26 +10540,38 @@
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
+ "license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/mocha/node_modules/yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "cliui": "^7.0.2",
+ "cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "string-width": "^4.2.0",
+ "string-width": "^4.2.3",
"y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
+ "yargs-parser": "^21.1.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=12"
+ }
+ },
+ "node_modules/mocha/node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
}
},
"node_modules/module-details-from-path": {
@@ -10074,12 +10594,12 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/mute-stdout": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
- "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz",
+ "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==",
"dev": true,
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/mute-stream": {
@@ -10093,39 +10613,23 @@
"resolved": "https://registry.npmjs.org/named-js-regexp/-/named-js-regexp-1.3.5.tgz",
"integrity": "sha512-XO0DPujDP9IWpkt690iWLreKztb/VB811DGl5N3z7BfhkMJuiVZXOi6YN/fEB9qkvtMVTgSZDW8pzdVt8vj/FA=="
},
- "node_modules/nan": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
- "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
- "dev": true,
- "optional": true
- },
"node_modules/nanoid": {
- "version": "2.1.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz",
- "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==",
- "dev": true
- },
- "node_modules/nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true,
- "dependencies": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
},
"engines": {
- "node": ">=0.10.0"
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/napi-build-utils": {
@@ -10154,16 +10658,16 @@
"dev": true
},
"node_modules/nise": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz",
- "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz",
+ "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==",
"dev": true,
"dependencies": {
- "@sinonjs/commons": "^1.8.3",
- "@sinonjs/fake-timers": ">=5",
- "@sinonjs/text-encoding": "^0.7.1",
- "just-extend": "^4.0.2",
- "path-to-regexp": "^1.7.0"
+ "@sinonjs/commons": "^3.0.0",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/text-encoding": "^0.7.2",
+ "just-extend": "^6.2.0",
+ "path-to-regexp": "^6.2.1"
}
},
"node_modules/node-abi": {
@@ -10428,9 +10932,9 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.12",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz",
- "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==",
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
"dev": true
},
"node_modules/node-stream-zip": {
@@ -10445,27 +10949,6 @@
"url": "https://github.com/sponsors/antelle"
}
},
- "node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -10480,6 +10963,7 @@
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
"integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prepend-http": "^2.0.0",
"query-string": "^5.0.1",
@@ -10489,18 +10973,6 @@
"node": ">=4"
}
},
- "node_modules/normalize-url/node_modules/sort-keys": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
- "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
- "dev": true,
- "dependencies": {
- "is-plain-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/now-and-later": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
@@ -10546,15 +11018,6 @@
"url": "https://github.com/fb55/nth-check?sponsor=1"
}
},
- "node_modules/number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/nyc": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
@@ -10617,57 +11080,14 @@
"node": ">=0.10.0"
}
},
- "node_modules/object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "dev": true,
- "dependencies": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-copy/node_modules/define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
- "dependencies": {
- "is-descriptor": "^0.1.0"
- },
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-copy/node_modules/kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "dependencies": {
- "is-buffer": "^1.1.5"
+ "node": ">= 0.4"
},
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
- "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -10697,27 +11117,15 @@
"node": ">= 0.4"
}
},
- "node_modules/object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
- "dev": true,
- "dependencies": {
- "isobject": "^3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/object.assign": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
- "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.0",
- "define-properties": "^1.1.3",
- "has-symbols": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
},
"engines": {
@@ -10730,7 +11138,7 @@
"node_modules/object.defaults": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
- "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
"dev": true,
"dependencies": {
"array-each": "^1.0.1",
@@ -10742,18 +11150,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/object.defaults/node_modules/for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "dependencies": {
- "for-in": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/object.entries": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz",
@@ -10769,14 +11165,15 @@
}
},
"node_modules/object.fromentries": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz",
- "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -10785,6 +11182,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/object.hasown": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz",
@@ -10798,35 +11209,10 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/object.map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
- "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
- "dev": true,
- "dependencies": {
- "for-own": "^1.0.0",
- "make-iterator": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object.map/node_modules/for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "dependencies": {
- "for-in": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/object.pick": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
"dev": true,
"dependencies": {
"isobject": "^3.0.1"
@@ -10835,40 +11221,15 @@
"node": ">=0.10.0"
}
},
- "node_modules/object.reduce": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
- "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
- "dev": true,
- "dependencies": {
- "for-own": "^1.0.0",
- "make-iterator": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object.reduce/node_modules/for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "dependencies": {
- "for-in": "^1.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/object.values": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz",
- "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -10900,6 +11261,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "dependencies": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/opener": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
@@ -10941,31 +11319,12 @@
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
"dev": true
},
- "node_modules/os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==",
- "dev": true,
- "dependencies": {
- "lcid": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/p-cancelable": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
"integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -10975,6 +11334,7 @@
"resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
"integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-timeout": "^2.0.1"
},
@@ -10985,8 +11345,9 @@
"node_modules/p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -10994,8 +11355,9 @@
"node_modules/p-is-promise": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
- "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
+ "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -11047,6 +11409,7 @@
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
"integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"p-finally": "^1.0.0"
},
@@ -11078,6 +11441,13 @@
"node": ">=8"
}
},
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -11089,6 +11459,7 @@
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
},
@@ -11096,32 +11467,48 @@
"node": ">=6"
}
},
- "node_modules/parent-module/node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "node_modules/parse-asn1": {
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz",
+ "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==",
"dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "asn1.js": "^4.10.1",
+ "browserify-aes": "^1.2.0",
+ "evp_bytestokey": "^1.0.3",
+ "pbkdf2": "^3.1.5",
+ "safe-buffer": "^5.2.1"
+ },
"engines": {
- "node": ">=6"
+ "node": ">= 0.10"
}
},
- "node_modules/parse-asn1": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
- "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
- "dev": true,
- "dependencies": {
- "asn1.js": "^5.2.0",
- "browserify-aes": "^1.0.0",
- "evp_bytestokey": "^1.0.0",
- "pbkdf2": "^3.0.3",
- "safe-buffer": "^5.1.1"
- }
+ "node_modules/parse-asn1/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
},
"node_modules/parse-filepath": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
- "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
"dev": true,
"dependencies": {
"is-absolute": "^1.0.0",
@@ -11132,31 +11519,10 @@
"node": ">=0.8"
}
},
- "node_modules/parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
- "dev": true,
- "dependencies": {
- "error-ex": "^1.2.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/parse-node-version": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
- "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
"node_modules/parse-passwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
- "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -11195,15 +11561,6 @@
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
"dev": true
},
- "node_modules/pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/path-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
@@ -11217,12 +11574,13 @@
"dev": true
},
"node_modules/path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/path-is-absolute": {
@@ -11250,7 +11608,7 @@
"node_modules/path-root": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
- "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
"dev": true,
"dependencies": {
"path-root-regex": "^0.1.0"
@@ -11262,25 +11620,40 @@
"node_modules/path-root-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
- "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/path-to-regexp": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
- "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "isarray": "0.0.1"
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/path-to-regexp/node_modules/isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
+ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
"dev": true
},
"node_modules/path-type": {
@@ -11302,21 +11675,44 @@
}
},
"node_modules/pbkdf2": {
- "version": "3.0.17",
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
- "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz",
+ "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "create-hash": "^1.1.2",
- "create-hmac": "^1.1.4",
- "ripemd160": "^2.0.1",
- "safe-buffer": "^5.0.1",
- "sha.js": "^2.4.8"
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "ripemd160": "^2.0.3",
+ "safe-buffer": "^5.2.1",
+ "sha.js": "^2.4.12",
+ "to-buffer": "^1.2.1"
},
"engines": {
- "node": ">=0.12"
+ "node": ">= 0.10"
}
},
+ "node_modules/pbkdf2/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -11324,15 +11720,16 @@
"dev": true
},
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
},
"node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"dev": true,
"engines": {
"node": ">=8.6"
@@ -11346,6 +11743,7 @@
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -11353,8 +11751,9 @@
"node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -11362,8 +11761,9 @@
"node_modules/pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"pinkie": "^2.0.0"
},
@@ -11398,13 +11798,13 @@
"node": ">= 0.10"
}
},
- "node_modules/posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true,
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
"node_modules/postinstall-build": {
@@ -11467,8 +11867,9 @@
"node_modules/prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
- "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -11485,15 +11886,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/pretty-hrtime": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
- "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -11532,11 +11924,6 @@
"react-is": "^16.13.1"
}
},
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
- },
"node_modules/public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
@@ -11573,19 +11960,36 @@
}
},
"node_modules/punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
},
+ "node_modules/qs": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
+ "dev": true,
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/query-string": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
"integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"decode-uri-component": "^0.2.0",
"object-assign": "^4.1.0",
@@ -11634,6 +12038,12 @@
}
]
},
+ "node_modules/queue-tick": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
+ "dev": true
+ },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -11697,86 +12107,12 @@
"node": ">=0.8"
}
},
- "node_modules/read-pkg": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
- "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==",
- "dev": true,
- "dependencies": {
- "load-json-file": "^1.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
- "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==",
- "dev": true,
- "dependencies": {
- "find-up": "^1.0.0",
- "read-pkg": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/read-pkg-up/node_modules/find-up": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
- "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
- "dev": true,
- "dependencies": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/read-pkg-up/node_modules/path-exists": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
- "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
- "dev": true,
- "dependencies": {
- "pinkie-promise": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/read-pkg/node_modules/path-type": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
- "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/read-pkg/node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@@ -11809,49 +12145,33 @@
}
},
"node_modules/rechoir": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
- "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"dev": true,
"dependencies": {
- "resolve": "^1.1.6"
+ "resolve": "^1.20.0"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/reflect-metadata": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
- "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
- },
- "node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
- "dev": true
- },
- "node_modules/regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
- "dev": true,
- "dependencies": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
+ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
+ "license": "Apache-2.0"
},
"node_modules/regexp.prototype.flags": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
- "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
+ "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.6",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -11860,18 +12180,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/regexpp": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
- "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- }
- },
"node_modules/release-zalgo": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
@@ -11917,24 +12225,6 @@
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
"dev": true
},
- "node_modules/repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
- "dev": true,
- "engines": {
- "node": ">=0.10"
- }
- },
"node_modules/replace-ext": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
@@ -11945,17 +12235,12 @@
}
},
"node_modules/replace-homedir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
- "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz",
+ "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==",
"dev": true,
- "dependencies": {
- "homedir-polyfill": "^1.0.1",
- "is-absolute": "^1.0.0",
- "remove-trailing-separator": "^1.1.0"
- },
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/require-directory": {
@@ -12005,12 +12290,6 @@
}
}
},
- "node_modules/require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==",
- "dev": true
- },
"node_modules/resolve": {
"version": "1.22.4",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
@@ -12042,7 +12321,7 @@
"node_modules/resolve-dir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
- "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
"dev": true,
"dependencies": {
"expand-tilde": "^2.0.0",
@@ -12073,31 +12352,16 @@
"node": ">= 0.10"
}
},
- "node_modules/resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
- "deprecated": "https://github.com/lydell/resolve-url#deprecated",
- "dev": true
- },
"node_modules/responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
- "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"lowercase-keys": "^1.0.0"
}
},
- "node_modules/ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true,
- "engines": {
- "node": ">=0.12"
- }
- },
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -12109,15 +12373,14 @@
}
},
"node_modules/rewiremock": {
- "version": "3.14.3",
- "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.3.tgz",
- "integrity": "sha512-6BaUGfp7NtxBjisxcGN73nNiA2fS2AwhEk/9DMUqxfv5v0aDM1wpOYpj5GSArqsJi07YCfLhkD8C74LAN7+FkQ==",
+ "version": "3.14.6",
+ "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.6.tgz",
+ "integrity": "sha512-hjpS7iQUTVVh/IHV4GE1ypg4IzlgVc34gxZBarwwVrKfnjlyqHJuQdsia6Ac7m4f4k/zxxA3tX285MOstdysRQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"babel-runtime": "^6.26.0",
"compare-module-exports": "^2.1.0",
- "lodash.some": "^4.6.0",
- "lodash.template": "^4.4.0",
"node-libs-browser": "^2.1.0",
"path-parse": "^1.0.5",
"wipe-node-cache": "^2.1.2",
@@ -12140,25 +12403,66 @@
}
},
"node_modules/ripemd160": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
- "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz",
+ "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "hash-base": "^3.0.0",
- "inherits": "^2.0.1"
+ "hash-base": "^3.1.2",
+ "inherits": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 0.8"
}
},
- "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==",
+ "node_modules/ripemd160/node_modules/hash-base": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz",
+ "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==",
"dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
+ "license": "MIT",
+ "dependencies": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^2.3.8",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ripemd160/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/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"
@@ -12188,18 +12492,51 @@
"resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz",
"integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw=="
},
+ "node_modules/safe-array-concat": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-array-concat/node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
},
- "node_modules/safe-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "node_modules/safe-regex-test": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+ "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
"dev": true,
"dependencies": {
- "ret": "~0.1.10"
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.1.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safer-buffer": {
@@ -12213,9 +12550,9 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"node_modules/schema-utils": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
- "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.8",
@@ -12231,34 +12568,23 @@
}
},
"node_modules/seek-bzip": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
- "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+ "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "commander": "~2.8.1"
+ "commander": "^2.8.1"
},
"bin": {
"seek-bunzip": "bin/seek-bunzip",
"seek-table": "bin/seek-bzip-table"
}
},
- "node_modules/seek-bzip/node_modules/commander": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
- "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
- "dev": true,
- "dependencies": {
- "graceful-readlink": ">= 1.0.0"
- },
- "engines": {
- "node": ">= 0.6.x"
- }
- },
"node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -12270,22 +12596,23 @@
}
},
"node_modules/semver-greatest-satisfied-range": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
- "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz",
+ "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==",
"dev": true,
"dependencies": {
- "sver-compat": "^1.5.0"
+ "sver": "^1.8.3"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
"randombytes": "^2.1.0"
}
@@ -12296,31 +12623,36 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"dev": true
},
- "node_modules/set-value": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
- "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"dependencies": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
- "node_modules/set-value/node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
"dev": true,
"dependencies": {
- "is-extendable": "^0.1.0"
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
"node_modules/setimmediate": {
@@ -12330,17 +12662,45 @@
"dev": true
},
"node_modules/sha.js": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
- "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "version": "2.4.12",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
+ "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
+ "dev": true,
"dependencies": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.0"
},
"bin": {
"sha.js": "bin.js"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/sha.js/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
"node_modules/shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -12380,23 +12740,82 @@
"integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="
},
"node_modules/shortid": {
- "version": "2.2.16",
- "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz",
- "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==",
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.17.tgz",
+ "integrity": "sha512-GpbM3gLF1UUXZvQw6MCyulHkWbRseNO4cyBEZresZRorwl1+SLu1ZdqgVtuwqz8mB6RpwPkm541mYSqrKyJSaA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "nanoid": "^2.1.0"
+ "nanoid": "^3.3.8"
}
},
"node_modules/side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -12485,17 +12904,17 @@
}
},
"node_modules/sinon": {
- "version": "13.0.1",
- "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
- "integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz",
+ "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==",
"dev": true,
"dependencies": {
- "@sinonjs/commons": "^1.8.3",
- "@sinonjs/fake-timers": "^9.0.0",
- "@sinonjs/samsam": "^6.1.1",
- "diff": "^5.0.0",
- "nise": "^5.1.1",
- "supports-color": "^7.2.0"
+ "@sinonjs/commons": "^3.0.1",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/samsam": "^8.0.0",
+ "diff": "^5.2.0",
+ "nise": "^6.0.0",
+ "supports-color": "^7"
},
"funding": {
"type": "opencollective",
@@ -12503,10 +12922,11 @@
}
},
"node_modules/sinon/node_modules/diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz",
+ "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -12517,260 +12937,63 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/sinon/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/sirv": {
- "version": "1.0.19",
- "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz",
- "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==",
- "dev": true,
- "dependencies": {
- "@polka/url": "^1.0.0-next.20",
- "mrmime": "^1.0.0",
- "totalist": "^1.0.0"
- },
- "engines": {
- "node": ">= 10"
- }
- },
- "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/slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/slice-ansi?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/slice-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "dev": true,
- "dependencies": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "dev": true,
- "dependencies": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-node/node_modules/define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "dependencies": {
- "is-descriptor": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-node/node_modules/is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^6.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-node/node_modules/is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "dependencies": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
- "dev": true,
- "dependencies": {
- "kind-of": "^3.2.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/snapdragon-util/node_modules/kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "dependencies": {
- "is-buffer": "^1.1.5"
- },
- "engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
- "node_modules/snapdragon/node_modules/define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "node_modules/sinon/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": {
- "is-descriptor": "^0.1.0"
+ "has-flag": "^4.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
- "node_modules/snapdragon/node_modules/extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "node_modules/sirv": {
+ "version": "1.0.19",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz",
+ "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==",
"dev": true,
"dependencies": {
- "is-extendable": "^0.1.0"
+ "@polka/url": "^1.0.0-next.20",
+ "mrmime": "^1.0.0",
+ "totalist": "^1.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 10"
}
},
- "node_modules/snapdragon/node_modules/source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "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": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/sort-keys": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
- "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+ "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-plain-obj": "^1.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=4"
}
},
"node_modules/sort-keys-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
- "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
+ "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"sort-keys": "^1.0.0"
},
@@ -12778,6 +13001,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/sort-keys-length/node_modules/sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -12787,20 +13023,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/source-map-resolve": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
- "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
- "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
- "dev": true,
- "dependencies": {
- "atob": "^2.1.1",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
- }
- },
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
@@ -12811,20 +13033,13 @@
"source-map": "^0.6.0"
}
},
- "node_modules/source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
- "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
- "dev": true
- },
"node_modules/sparkles": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
- "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz",
+ "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==",
"dev": true,
"engines": {
- "node": ">= 0.10"
+ "node": ">= 10.13.0"
}
},
"node_modules/spawn-wrap": {
@@ -12844,50 +13059,6 @@
"node": ">=8"
}
},
- "node_modules/spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
- "dev": true
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.13",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
- "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
- "dev": true
- },
- "node_modules/split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "dev": true,
- "dependencies": {
- "extend-shallow": "^3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -12907,29 +13078,14 @@
"node": "*"
}
},
- "node_modules/static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "dev": true,
- "dependencies": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/static-extend/node_modules/define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "node_modules/stoppable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
+ "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
"dev": true,
- "dependencies": {
- "is-descriptor": "^0.1.0"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=4",
+ "npm": ">=6"
}
},
"node_modules/stream-browserify": {
@@ -12942,6 +13098,15 @@
"readable-stream": "^2.0.2"
}
},
+ "node_modules/stream-composer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
+ "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==",
+ "dev": true,
+ "dependencies": {
+ "streamx": "^2.13.2"
+ }
+ },
"node_modules/stream-exhaust": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
@@ -12967,11 +13132,26 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true
},
+ "node_modules/streamx": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz",
+ "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==",
+ "dev": true,
+ "dependencies": {
+ "fast-fifo": "^1.3.2",
+ "queue-tick": "^1.0.1",
+ "text-decoder": "^1.1.0"
+ },
+ "optionalDependencies": {
+ "bare-events": "^2.2.0"
+ }
+ },
"node_modules/strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
- "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+ "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -13006,38 +13186,33 @@
]
},
"node_modules/string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"dependencies": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
},
"engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/string-width/node_modules/ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
- "node_modules/string-width/node_modules/strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "ansi-regex": "^2.0.0"
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/string.prototype.matchall": {
@@ -13059,27 +13234,50 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/string.prototype.trimend": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
- "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
- "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -13097,16 +13295,18 @@
"node": ">=8"
}
},
- "node_modules/strip-bom": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
- "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "is-utf8": "^0.2.0"
+ "ansi-regex": "^5.0.1"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
}
},
"node_modules/strip-dirs": {
@@ -13114,6 +13314,7 @@
"resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
"integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"is-natural-number": "^4.0.1"
}
@@ -13144,6 +13345,7 @@
"resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
"integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"escape-string-regexp": "^1.0.2"
},
@@ -13179,90 +13381,42 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/sver-compat": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
- "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
- "dev": true,
- "dependencies": {
- "es6-iterator": "^2.0.1",
- "es6-symbol": "^3.1.1"
- }
- },
- "node_modules/table": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz",
- "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==",
- "dev": true,
- "dependencies": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/table/node_modules/ajv": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz",
- "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==",
+ "node_modules/sver": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz",
+ "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==",
"dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/table/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
+ "optionalDependencies": {
+ "semver": "^6.3.0"
}
},
- "node_modules/table/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
- "node_modules/table/node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "node_modules/sver/node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
+ "optional": true,
+ "bin": {
+ "semver": "bin/semver.js"
}
},
"node_modules/tapable": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
- "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
"dev": true,
"engines": {
"node": ">=6"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
}
},
"node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
+ "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"dev": true,
"optional": true,
"dependencies": {
@@ -13332,6 +13486,7 @@
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
"integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"bl": "^1.0.0",
"buffer-alloc": "^1.2.0",
@@ -13346,21 +13501,27 @@
}
},
"node_modules/tas-client": {
- "version": "0.1.73",
- "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.1.73.tgz",
- "integrity": "sha512-UDdUF9kV2hYdlv+7AgqP2kXarVSUhjK7tg1BUflIRGEgND0/QoNpN64rcEuhEcM8AIbW65yrCopJWqRhLZ3m8w==",
+ "version": "0.2.33",
+ "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.2.33.tgz",
+ "integrity": "sha512-V+uqV66BOQnWxvI6HjDnE4VkInmYZUQ4dgB7gzaDyFyFSK1i1nF/j7DpS9UbQAgV9NaF1XpcyuavnM1qOeiEIg=="
+ },
+ "node_modules/teex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+ "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+ "dev": true,
"dependencies": {
- "axios": "^1.6.1"
+ "streamx": "^2.12.5"
}
},
"node_modules/terser": {
- "version": "5.14.2",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
- "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
+ "version": "5.46.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
+ "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
"dev": true,
"dependencies": {
- "@jridgewell/source-map": "^0.3.2",
- "acorn": "^8.5.0",
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
@@ -13372,16 +13533,16 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz",
- "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==",
+ "version": "5.3.17",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.17.tgz",
+ "integrity": "sha512-YR7PtUp6GMU91BgSJmlaX/rS2lGDbAF7D+Wtq7hRO+MiljNmodYvqslzCFiYVAgW+Qoaaia/QUIP4lGXufjdZw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.0",
- "source-map": "^0.6.1",
- "terser": "^5.7.2"
+ "schema-utils": "^4.3.0",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -13405,6 +13566,60 @@
}
}
},
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/test-exclude": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -13420,10 +13635,11 @@
}
},
"node_modules/test-exclude/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
+ "license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -13431,6 +13647,15 @@
"node": "*"
}
},
+ "node_modules/text-decoder": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz",
+ "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==",
+ "dev": true,
+ "dependencies": {
+ "b4a": "^1.6.4"
+ }
+ },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -13440,8 +13665,9 @@
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
- "dev": true
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/through2": {
"version": "2.0.5",
@@ -13463,20 +13689,12 @@
"xtend": "~4.0.0"
}
},
- "node_modules/time-stamp": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
- "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/timed-out": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+ "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -13494,14 +13712,12 @@
}
},
"node_modules/tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
- "dependencies": {
- "os-tmpdir": "~1.0.2"
- },
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
+ "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
+ "license": "MIT",
"engines": {
- "node": ">=0.6.0"
+ "node": ">=14.14"
}
},
"node_modules/to-absolute-glob": {
@@ -13524,70 +13740,58 @@
"dev": true
},
"node_modules/to-buffer": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
- "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
- "dev": true
- },
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
+ "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "kind-of": "^3.0.2"
+ "isarray": "^2.0.5",
+ "safe-buffer": "^5.2.1",
+ "typed-array-buffer": "^1.0.3"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 0.4"
}
},
- "node_modules/to-object-path/node_modules/kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "node_modules/to-buffer/node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true,
- "dependencies": {
- "is-buffer": "^1.1.5"
- },
- "engines": {
- "node": ">=0.10.0"
- }
+ "license": "MIT"
},
- "node_modules/to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "node_modules/to-buffer/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
- "dependencies": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
},
"node_modules/to-regex-range": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"dependencies": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
+ "is-number": "^7.0.0"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8.0"
}
},
"node_modules/to-through": {
@@ -13614,8 +13818,9 @@
"node_modules/trim-repeated": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
- "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+ "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"escape-string-regexp": "^1.0.2"
},
@@ -13623,6 +13828,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/ts-loader": {
"version": "9.2.8",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz",
@@ -13657,18 +13874,6 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/ts-loader/node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ts-loader/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -13703,18 +13908,6 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "node_modules/ts-loader/node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/ts-loader/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -13724,28 +13917,6 @@
"node": ">=8"
}
},
- "node_modules/ts-loader/node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/ts-loader/node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
"node_modules/ts-loader/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -13758,18 +13929,6 @@
"node": ">=8"
}
},
- "node_modules/ts-loader/node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
"node_modules/ts-mockito": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/ts-mockito/-/ts-mockito-2.6.1.tgz",
@@ -13823,13 +13982,13 @@
}
},
"node_modules/tsconfig-paths": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
- "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
"dev": true,
"dependencies": {
"@types/json5": "^0.0.29",
- "json5": "^1.0.1",
+ "json5": "^1.0.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
@@ -13941,21 +14100,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
- "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/tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -13984,12 +14128,6 @@
"node": "*"
}
},
- "node_modules/type": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz",
- "integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw==",
- "dev": true
- },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -14020,38 +14158,90 @@
"node": ">=8"
}
},
- "node_modules/typed-rest-client": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.5.tgz",
- "integrity": "sha512-952/Aegu3lTqUAI1anbDLbewojnF/gh8at9iy1CIrfS1h/+MtNjB1Y9z6ZF5n2kZd+97em56lZ9uu7Zz3y/pwg==",
- "deprecated": "1.8.5 contains changes that are not compatible with Node 6",
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "qs": "^6.9.1",
- "tunnel": "0.0.6",
- "underscore": "^1.12.1"
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
- "node_modules/typed-rest-client/node_modules/qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
"dev": true,
"dependencies": {
- "side-channel": "^1.0.4"
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
},
"engines": {
- "node": ">=0.6"
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
- "dev": true
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+ "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-rest-client": {
+ "version": "1.8.11",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
+ "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==",
+ "dev": true,
+ "dependencies": {
+ "qs": "^6.9.1",
+ "tunnel": "0.0.6",
+ "underscore": "^1.12.1"
+ }
},
"node_modules/typedarray-to-buffer": {
"version": "3.1.5",
@@ -14078,16 +14268,16 @@
}
},
"node_modules/typescript": {
- "version": "4.5.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
- "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
- "node": ">=4.2.0"
+ "node": ">=14.17"
}
},
"node_modules/uc.micro": {
@@ -14102,14 +14292,14 @@
"integrity": "sha512-mliiCSrsE29aNBI7O9W5gGv6WmA9kBR8PtTt6Apaxns076IRdYrrtFhXHEWMj5CSum3U7cv7/pi4xmi4XsIOqg=="
},
"node_modules/unbox-primitive": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
- "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
"dev": true,
"dependencies": {
- "function-bind": "^1.1.1",
- "has-bigints": "^1.0.1",
- "has-symbols": "^1.0.2",
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
"which-boxed-primitive": "^1.0.2"
},
"funding": {
@@ -14117,10 +14307,11 @@
}
},
"node_modules/unbzip2-stream": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz",
- "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer": "^5.2.1",
"through": "^2.3.8"
@@ -14136,143 +14327,73 @@
}
},
"node_modules/underscore": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
- "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
+ "version": "1.13.6",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
"dev": true
},
"node_modules/undertaker": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz",
- "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz",
+ "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==",
"dev": true,
"dependencies": {
- "arr-flatten": "^1.0.1",
- "arr-map": "^2.0.0",
- "bach": "^1.0.0",
- "collection-map": "^1.0.0",
- "es6-weak-map": "^2.0.1",
- "last-run": "^1.1.0",
- "object.defaults": "^1.0.0",
- "object.reduce": "^1.0.0",
- "undertaker-registry": "^1.0.0"
+ "bach": "^2.0.1",
+ "fast-levenshtein": "^3.0.0",
+ "last-run": "^2.0.0",
+ "undertaker-registry": "^2.0.0"
},
"engines": {
- "node": ">= 0.10"
+ "node": ">=10.13.0"
}
},
"node_modules/undertaker-registry": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
- "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
- "dev": true,
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/unicode": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/unicode/-/unicode-14.0.0.tgz",
- "integrity": "sha512-BjinxTXkbm9Jomp/YBTMGusr4fxIG67fNGShHIRAL16Ur2GJTq2xvLi+sxuiJmInCmwqqev2BCFKyvbfp/yAkg==",
- "engines": {
- "node": ">= 0.8.x"
- }
- },
- "node_modules/union-value": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
- "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
- "dev": true,
- "dependencies": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^2.0.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/unique-stream": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
- "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
- "dev": true,
- "dependencies": {
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "through2-filter": "^3.0.0"
- }
- },
- "node_modules/unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "dev": true,
- "dependencies": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/unset-value/node_modules/has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz",
+ "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==",
"dev": true,
- "dependencies": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
"engines": {
- "node": ">=0.10.0"
+ "node": ">= 10.13.0"
}
},
- "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "node_modules/undertaker/node_modules/fast-levenshtein": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
+ "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
"dev": true,
"dependencies": {
- "isarray": "1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/unset-value/node_modules/has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
+ "fastest-levenshtein": "^1.0.7"
}
},
- "node_modules/untildify": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
- "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unicode": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/unicode/-/unicode-14.0.0.tgz",
+ "integrity": "sha512-BjinxTXkbm9Jomp/YBTMGusr4fxIG67fNGShHIRAL16Ur2GJTq2xvLi+sxuiJmInCmwqqev2BCFKyvbfp/yAkg==",
"engines": {
- "node": ">=8"
+ "node": ">= 0.8.x"
}
},
- "node_modules/upath": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
- "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "node_modules/unique-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+ "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
"dev": true,
- "engines": {
- "node": ">=4",
- "yarn": "*"
+ "dependencies": {
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "through2-filter": "^3.0.0"
}
},
"node_modules/update-browserslist-db": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
- "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
"dev": true,
"funding": [
{
@@ -14289,8 +14410,8 @@
}
],
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -14308,13 +14429,6 @@
"punycode": "^2.1.0"
}
},
- "node_modules/urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
- "deprecated": "Please see https://github.com/lydell/urix#deprecated",
- "dev": true
- },
"node_modules/url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -14334,8 +14448,9 @@
"node_modules/url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
- "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"prepend-http": "^2.0.0"
},
@@ -14346,8 +14461,9 @@
"node_modules/url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
- "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
+ "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
@@ -14358,15 +14474,6 @@
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
"dev": true
},
- "node_modules/use": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
- "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/util": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
@@ -14389,19 +14496,18 @@
"dev": true
},
"node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
+ "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
"bin": {
- "uuid": "dist/bin/uuid"
+ "uuid": "dist-node/bin/uuid"
}
},
- "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/v8-compile-cache-lib": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz",
@@ -14409,25 +14515,12 @@
"dev": true
},
"node_modules/v8flags": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
- "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
+ "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==",
"dev": true,
- "dependencies": {
- "homedir-polyfill": "^1.0.1"
- },
"engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
+ "node": ">= 10.13.0"
}
},
"node_modules/value-or-function": {
@@ -14456,6 +14549,93 @@
"node": ">= 0.10"
}
},
+ "node_modules/vinyl-contents": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz",
+ "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==",
+ "dev": true,
+ "dependencies": {
+ "bl": "^5.0.0",
+ "vinyl": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dev": true,
+ "dependencies": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "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": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/vinyl-contents/node_modules/vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "dependencies": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/vinyl-fs": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
@@ -14527,60 +14707,78 @@
"deprecated": "This package has been renamed to @vscode/debugprotocol, please update to the new name"
},
"node_modules/vscode-jsonrpc": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
- "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
+ "version": "9.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.0-next.5.tgz",
+ "integrity": "sha512-Sl/8RAJtfF/2x/TPBVRuhzRAcqYR/QDjEjNqMcoKFfqsxfVUPzikupRDQYB77Gkbt1RrW43sSuZ5uLtNAcikQQ==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/vscode-languageclient": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
- "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
+ "version": "10.0.0-next.12",
+ "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-10.0.0-next.12.tgz",
+ "integrity": "sha512-q7cVYCcYiv+a+fJYCbjMMScOGBnX162IBeUMFg31mvnN7RHKx5/CwKaCz+r+RciJrRXMqS8y8qpEVGgeIPnbxg==",
+ "dependencies": {
+ "minimatch": "^9.0.3",
+ "semver": "^7.6.0",
+ "vscode-languageserver-protocol": "3.17.6-next.10"
+ },
+ "engines": {
+ "vscode": "^1.91.0"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/vscode-languageclient/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "license": "ISC",
"dependencies": {
- "minimatch": "^5.1.0",
- "semver": "^7.3.7",
- "vscode-languageserver-protocol": "3.17.5"
+ "brace-expansion": "^2.0.2"
},
"engines": {
- "vscode": "^1.82.0"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/vscode-languageserver-protocol": {
- "version": "3.17.5",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
- "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
+ "version": "3.17.6-next.10",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.6-next.10.tgz",
+ "integrity": "sha512-KOrrWn4NVC5jnFC5N6y/fyNKtx8rVYr67lhL/Z0P4ZBAN27aBsCnLBWAMIkYyJ1K8EZaE5r7gqdxrS9JPB6LIg==",
"dependencies": {
- "vscode-jsonrpc": "8.2.0",
- "vscode-languageserver-types": "3.17.5"
+ "vscode-jsonrpc": "9.0.0-next.5",
+ "vscode-languageserver-types": "3.17.6-next.5"
}
},
"node_modules/vscode-languageserver-types": {
- "version": "3.17.5",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
- "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
+ "version": "3.17.6-next.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.6-next.5.tgz",
+ "integrity": "sha512-QFmf3Yl1tCgUQfA77N9Me/LXldJXkIVypQbty2rJ1DNHQkC+iwvm4Z2tXg9czSwlhvv0pD4pbF5mT7WhAglolw=="
},
"node_modules/vscode-tas-client": {
- "version": "0.1.75",
- "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.75.tgz",
- "integrity": "sha512-/+ALFWPI4U3obeRvLFSt39guT7P9bZQrkmcLoiS+2HtzJ/7iPKNt5Sj+XTiitGlPYVFGFc0plxX8AAp6Uxs0xQ==",
+ "version": "0.1.84",
+ "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.84.tgz",
+ "integrity": "sha512-rUTrUopV+70hvx1hW5ebdw1nd6djxubkLvVxjGdyD/r5v/wcVF41LIfiAtbm5qLZDtQdsMH1IaCuDoluoIa88w==",
"dependencies": {
- "tas-client": "0.1.73"
+ "tas-client": "0.2.33"
},
"engines": {
- "vscode": "^1.19.1"
+ "vscode": "^1.85.0"
}
},
- "node_modules/vscode-uri": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz",
- "integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ=="
- },
"node_modules/watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz",
+ "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==",
"dev": true,
"dependencies": {
"glob-to-regexp": "^0.4.1",
@@ -14591,35 +14789,36 @@
}
},
"node_modules/webpack": {
- "version": "5.76.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz",
- "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==",
- "dev": true,
- "dependencies": {
- "@types/eslint-scope": "^3.7.3",
- "@types/estree": "^0.0.51",
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/wasm-edit": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
- "acorn": "^8.7.1",
- "acorn-import-assertions": "^1.7.6",
- "browserslist": "^4.14.5",
+ "version": "5.105.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz",
+ "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==",
+ "dev": true,
+ "dependencies": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.8",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.15.0",
+ "acorn-import-phases": "^1.0.3",
+ "browserslist": "^4.28.1",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.10.0",
- "es-module-lexer": "^0.9.0",
+ "enhanced-resolve": "^5.19.0",
+ "es-module-lexer": "^2.0.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
- "loader-runner": "^4.2.0",
+ "loader-runner": "^4.3.1",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.1.0",
- "tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.1.3",
- "watchpack": "^2.4.0",
- "webpack-sources": "^3.2.3"
+ "schema-utils": "^4.3.3",
+ "tapable": "^2.3.0",
+ "terser-webpack-plugin": "^5.3.16",
+ "watchpack": "^2.5.1",
+ "webpack-sources": "^3.3.3"
},
"bin": {
"webpack": "bin/webpack.js"
@@ -14850,14 +15049,68 @@
}
},
"node_modules/webpack-sources": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
- "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"dev": true,
"engines": {
"node": ">=10.13.0"
}
},
+ "node_modules/webpack/node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/webpack/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/webpack/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "node_modules/webpack/node_modules/schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
+ "dependencies": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -14888,51 +15141,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/which-boxed-primitive/node_modules/is-boolean-object": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
- "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
- "dev": true,
- "dependencies": {
- "call-bind": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-boxed-primitive/node_modules/is-number-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
- "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
- "dev": true,
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==",
- "dev": true
- },
"node_modules/which-typed-array": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz",
- "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==",
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "es-abstract": "^1.18.5",
- "foreach": "^2.0.5",
- "has-tostringtag": "^1.0.0",
- "is-typed-array": "^1.1.7"
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -14988,45 +15210,117 @@
}
},
"node_modules/workerpool": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
- "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
- "dev": true
+ "version": "9.3.4",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz",
+ "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==",
+ "dev": true,
+ "license": "Apache-2.0"
},
"node_modules/wrap-ansi": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/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,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/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,
+ "license": "MIT",
"dependencies": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1"
+ "color-name": "~1.1.4"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=7.0.0"
}
},
- "node_modules/wrap-ansi/node_modules/ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "node_modules/wrap-ansi-cjs/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,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
"engines": {
- "node": ">=0.10.0"
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/wrap-ansi/node_modules/strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
- "ansi-regex": "^2.0.0"
+ "color-name": "~1.1.4"
},
"engines": {
- "node": ">=0.10.0"
+ "node": ">=7.0.0"
}
},
+ "node_modules/wrap-ansi/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -15045,9 +15339,9 @@
}
},
"node_modules/ws": {
- "version": "7.5.7",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
- "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"dev": true,
"engines": {
"node": ">=8.3.0"
@@ -15235,44 +15529,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "node_modules/yargs/node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/yargs/node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/yargs/node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
- "node_modules/yargs/node_modules/string-width": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
- "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/yargs/node_modules/which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
@@ -15396,6 +15658,48 @@
}
}
},
+ "@azure/core-client": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz",
+ "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==",
+ "dev": true,
+ "requires": {
+ "@azure/abort-controller": "^2.0.0",
+ "@azure/core-auth": "^1.4.0",
+ "@azure/core-rest-pipeline": "^1.9.1",
+ "@azure/core-tracing": "^1.0.0",
+ "@azure/core-util": "^1.6.1",
+ "@azure/logger": "^1.0.0",
+ "tslib": "^2.6.2"
+ },
+ "dependencies": {
+ "@azure/abort-controller": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "@azure/core-util": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz",
+ "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==",
+ "dev": true,
+ "requires": {
+ "@azure/abort-controller": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "dev": true
+ }
+ }
+ },
"@azure/core-rest-pipeline": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.1.tgz",
@@ -15440,6 +15744,11 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}
}
},
@@ -15474,6 +15783,57 @@
}
}
},
+ "@azure/identity": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.2.1.tgz",
+ "integrity": "sha512-U8hsyC9YPcEIzoaObJlRDvp7KiF0MGS7xcWbyJSVvXRkC/HXo1f0oYeBYmEvVgRfacw7GHf6D6yAoh9JHz6A5Q==",
+ "dev": true,
+ "requires": {
+ "@azure/abort-controller": "^1.0.0",
+ "@azure/core-auth": "^1.5.0",
+ "@azure/core-client": "^1.4.0",
+ "@azure/core-rest-pipeline": "^1.1.0",
+ "@azure/core-tracing": "^1.0.0",
+ "@azure/core-util": "^1.3.0",
+ "@azure/logger": "^1.0.0",
+ "@azure/msal-browser": "^3.11.1",
+ "@azure/msal-node": "^2.9.2",
+ "events": "^3.0.0",
+ "jws": "^4.0.0",
+ "open": "^8.0.0",
+ "stoppable": "^1.1.0",
+ "tslib": "^2.2.0"
+ },
+ "dependencies": {
+ "@azure/core-util": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz",
+ "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==",
+ "dev": true,
+ "requires": {
+ "@azure/abort-controller": "^2.0.0",
+ "tslib": "^2.6.2"
+ },
+ "dependencies": {
+ "@azure/abort-controller": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^2.6.2"
+ }
+ }
+ }
+ },
+ "tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "dev": true
+ }
+ }
+ },
"@azure/logger": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.4.tgz",
@@ -15489,6 +15849,46 @@
}
}
},
+ "@azure/msal-browser": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.14.0.tgz",
+ "integrity": "sha512-Un85LhOoecJ3HDTS3Uv3UWnXC9/43ZSO+Kc+anSqpZvcEt58SiO/3DuVCAe1A3I5UIBYJNMgTmZPGXQ0MVYrwA==",
+ "dev": true,
+ "requires": {
+ "@azure/msal-common": "14.10.0"
+ }
+ },
+ "@azure/msal-common": {
+ "version": "14.10.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.10.0.tgz",
+ "integrity": "sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA==",
+ "dev": true
+ },
+ "@azure/msal-node": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.9.2.tgz",
+ "integrity": "sha512-8tvi6Cos3m+0KmRbPjgkySXi+UQU/QiuVRFnrxIwt5xZlEEFa69O04RTaNESGgImyBBlYbo2mfE8/U8Bbdk1WQ==",
+ "dev": true,
+ "requires": {
+ "@azure/msal-common": "14.12.0",
+ "jsonwebtoken": "^9.0.0",
+ "uuid": "^8.3.0"
+ },
+ "dependencies": {
+ "@azure/msal-common": {
+ "version": "14.12.0",
+ "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.12.0.tgz",
+ "integrity": "sha512-IDDXmzfdwmDkv4SSmMEyAniJf6fDu3FJ7ncOjlxkDuT85uSnLEhZi3fGZpoR7T4XZpOMx9teM9GXBgrfJgyeBw==",
+ "dev": true
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true
+ }
+ }
+ },
"@azure/opentelemetry-instrumentation-azure-sdk": {
"version": "1.0.0-beta.5",
"resolved": "https://registry.npmjs.org/@azure/opentelemetry-instrumentation-azure-sdk/-/opentelemetry-instrumentation-azure-sdk-1.0.0-beta.5.tgz",
@@ -15510,12 +15910,14 @@
}
},
"@babel/code-frame": {
- "version": "7.12.11",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
- "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+ "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.10.4"
+ "@babel/helper-validator-identifier": "^7.27.1",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
}
},
"@babel/compat-data": {
@@ -15547,15 +15949,6 @@
"json5": "^2.2.2"
},
"dependencies": {
- "@babel/code-frame": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
- "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.22.5"
- }
- },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -15678,15 +16071,15 @@
}
},
"@babel/helper-string-parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
- "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"dev": true
},
"@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"dev": true
},
"@babel/helper-validator-option": {
@@ -15696,73 +16089,48 @@
"dev": true
},
"@babel/helpers": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz",
- "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz",
+ "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==",
"dev": true,
"requires": {
- "@babel/template": "^7.22.5",
- "@babel/traverse": "^7.22.6",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.27.1",
+ "@babel/types": "^7.27.1"
}
},
- "@babel/highlight": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
- "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
+ "@babel/parser": {
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
+ "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
+ "@babel/types": "^7.27.1"
}
},
- "@babel/parser": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
- "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
- "dev": true
- },
"@babel/runtime": {
- "version": "7.17.8",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
- "integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
- "dev": true,
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz",
+ "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==",
+ "dev": true
},
"@babel/runtime-corejs3": {
- "version": "7.10.5",
- "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.5.tgz",
- "integrity": "sha512-RMafpmrNB5E/bwdSphLr8a8++9TosnyJp98RZzI6VOx2R2CCMpsXXXRvmI700O9oEKpXdZat6oEK68/F0zjd4A==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.27.1.tgz",
+ "integrity": "sha512-909rVuj3phpjW6y0MCXAZ5iNeORePa6ldJvp2baWGcTjwqbBDDz6xoS5JHJ7lS88NlwLYj07ImL/8IUMtDZzTA==",
"dev": true,
"requires": {
- "core-js-pure": "^3.0.0",
- "regenerator-runtime": "^0.13.4"
+ "core-js-pure": "^3.30.2"
}
},
"@babel/template": {
- "version": "7.22.15",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
- "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "version": "7.27.2",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.22.13",
- "@babel/parser": "^7.22.15",
- "@babel/types": "^7.22.15"
- },
- "dependencies": {
- "@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
- }
- }
+ "@babel/code-frame": "^7.27.1",
+ "@babel/parser": "^7.27.2",
+ "@babel/types": "^7.27.1"
}
},
"@babel/traverse": {
@@ -15783,16 +16151,6 @@
"globals": "^11.1.0"
},
"dependencies": {
- "@babel/code-frame": {
- "version": "7.22.13",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
- "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
- "dev": true,
- "requires": {
- "@babel/highlight": "^7.22.13",
- "chalk": "^2.4.2"
- }
- },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -15805,14 +16163,13 @@
}
},
"@babel/types": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
- "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
+ "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
"dev": true,
"requires": {
- "@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.20",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.27.1"
}
},
"@cspotcode/source-map-consumer": {
@@ -15836,56 +16193,86 @@
"integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
"dev": true
},
+ "@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^3.3.0"
+ }
+ },
+ "@eslint-community/regexpp": {
+ "version": "4.11.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
+ "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
+ "dev": true
+ },
"@eslint/eslintrc": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
- "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
- "debug": "^4.1.1",
- "espree": "^7.3.0",
- "globals": "^13.9.0",
- "ignore": "^4.0.6",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
"import-fresh": "^3.2.1",
- "js-yaml": "^3.13.1",
- "minimatch": "^3.0.4",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
"strip-json-comments": "^3.1.1"
},
"dependencies": {
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
"debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
"requires": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
}
},
"globals": {
- "version": "13.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
- "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
}
},
- "ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
- "dev": true
+ "js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1"
+ }
},
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ },
"type-fest": {
"version": "0.20.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
@@ -15894,48 +16281,146 @@
}
}
},
+ "@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true
+ },
+ "@gulpjs/messages": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz",
+ "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==",
+ "dev": true
+ },
+ "@gulpjs/to-absolute-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz",
+ "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==",
+ "dev": true,
+ "requires": {
+ "is-negated-glob": "^1.0.0"
+ }
+ },
"@humanwhocodes/config-array": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
- "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
"dev": true,
"requires": {
- "@humanwhocodes/object-schema": "^1.2.0",
- "debug": "^4.1.1",
- "minimatch": "^3.0.4"
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
},
"dependencies": {
"debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.3"
+ }
+ },
+ "minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true
+ }
+ }
+ },
+ "@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
+ },
+ "@humanwhocodes/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "dev": true
+ },
+ "@iarna/toml": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-3.0.0.tgz",
+ "integrity": "sha512-td6ZUkz2oS3VeleBcN+m//Q6HlCFCPrnI0FZhrt/h4XqLEdOyYp2u21nd8MdsR+WJy5r9PTDaHTDDfhf4H4l6Q=="
+ },
+ "@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"requires": {
- "ms": "2.1.2"
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
}
},
- "minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
"dev": true,
"requires": {
- "brace-expansion": "^1.1.7"
+ "ansi-regex": "^6.0.1"
+ }
+ },
+ "wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
}
}
}
},
- "@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
- },
- "@iarna/toml": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
- "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
- },
"@istanbuljs/load-nyc-config": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
@@ -15964,14 +16449,14 @@
"dev": true
},
"@jridgewell/gen-mapping": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
- "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"requires": {
- "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/trace-mapping": "^0.3.24"
}
},
"@jridgewell/resolve-uri": {
@@ -15981,19 +16466,19 @@
"dev": true
},
"@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true
},
"@jridgewell/source-map": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
- "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
"requires": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"@jridgewell/sourcemap-codec": {
@@ -16003,13 +16488,13 @@
"dev": true
},
"@jridgewell/trace-mapping": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
- "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"requires": {
- "@jridgewell/resolve-uri": "3.1.0",
- "@jridgewell/sourcemap-codec": "1.4.14"
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"@microsoft/1ds-core-js": {
@@ -16275,12 +16760,25 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz",
"integrity": "sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw=="
},
+ "@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "optional": true
+ },
"@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
"integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==",
"dev": true
},
+ "@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true
+ },
"@sindresorhus/is": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@@ -16288,38 +16786,49 @@
"dev": true
},
"@sinonjs/commons": {
- "version": "1.8.3",
- "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
- "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
"dev": true,
"requires": {
"type-detect": "4.0.8"
}
},
"@sinonjs/fake-timers": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.1.tgz",
- "integrity": "sha512-Wp5vwlZ0lOqpSYGKqr53INws9HLkt6JDc/pDZcPf7bchQnrXJMXPns8CXx0hFikMSGSWfvtvvpb2gtMVfkWagA==",
+ "version": "11.2.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz",
+ "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==",
"dev": true,
"requires": {
- "@sinonjs/commons": "^1.7.0"
+ "@sinonjs/commons": "^3.0.0"
}
},
"@sinonjs/samsam": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz",
- "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz",
+ "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==",
"dev": true,
"requires": {
- "@sinonjs/commons": "^1.6.0",
+ "@sinonjs/commons": "^2.0.0",
"lodash.get": "^4.4.2",
"type-detect": "^4.0.8"
+ },
+ "dependencies": {
+ "@sinonjs/commons": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz",
+ "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ }
}
},
"@sinonjs/text-encoding": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
- "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz",
+ "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==",
"dev": true
},
"@tootallnate/once": {
@@ -16412,9 +16921,9 @@
}
},
"@types/eslint": {
- "version": "8.4.1",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.1.tgz",
- "integrity": "sha512-GE44+DNEyxxh2Kc6ro/VkIj+9ma0pO0bwv9+uHSyBrikYOHr8zYcdPvnBOp1aw8s+CjRvuSx7CyWqRrNFQ59mA==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true,
"requires": {
"@types/estree": "*",
@@ -16422,33 +16931,28 @@
}
},
"@types/eslint-scope": {
- "version": "3.7.3",
- "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz",
- "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==",
+ "version": "3.7.7",
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
"dev": true,
"requires": {
"@types/eslint": "*",
"@types/estree": "*"
}
},
- "@types/eslint-visitor-keys": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
- "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
- "dev": true
- },
"@types/estree": {
- "version": "0.0.51",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz",
- "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true
},
"@types/fs-extra": {
- "version": "9.0.13",
- "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
- "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "version": "11.0.4",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
+ "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
"dev": true,
"requires": {
+ "@types/jsonfile": "*",
"@types/node": "*"
}
},
@@ -16474,22 +16978,31 @@
},
"dependencies": {
"form-data": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
- "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz",
+ "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.35",
+ "safe-buffer": "^5.2.1"
}
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
}
}
},
"@types/json-schema": {
- "version": "7.0.9",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz",
- "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==",
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"@types/json5": {
@@ -16498,6 +17011,15 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true
},
+ "@types/jsonfile": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
+ "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/lodash": {
"version": "4.14.181",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.181.tgz",
@@ -16517,10 +17039,13 @@
"dev": true
},
"@types/node": {
- "version": "18.17.14",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.14.tgz",
- "integrity": "sha512-ZE/5aB73CyGqgQULkLG87N9GnyGe5TcQjv34pwS8tfBs1IkCh0ASM69mydb2znqd6v0eX+9Ytvk6oQRqu8T1Vw==",
- "dev": true
+ "version": "22.19.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz",
+ "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==",
+ "dev": true,
+ "requires": {
+ "undici-types": "~6.21.0"
+ }
},
"@types/semver": {
"version": "5.5.0",
@@ -16540,9 +17065,9 @@
"dev": true
},
"@types/sinon": {
- "version": "10.0.11",
- "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.11.tgz",
- "integrity": "sha512-dmZsHlBsKUtBpHriNjlK0ndlvEh8dcb9uV9Afsbt89QIyydpC7NcR+nWlAhASfy3GHnxTl4FX/aKE7XZUt/B4g==",
+ "version": "17.0.3",
+ "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz",
+ "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==",
"dev": true,
"requires": {
"@types/sinonjs__fake-timers": "*"
@@ -16573,9 +17098,9 @@
"dev": true
},
"@types/vscode": {
- "version": "1.81.0",
- "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.81.0.tgz",
- "integrity": "sha512-YIaCwpT+O2E7WOMq0eCgBEABE++SX3Yl/O02GoMIF2DO3qAtvw7m6BXFYsxnc6XyzwZgh6/s/UG78LSSombl2w==",
+ "version": "1.100.0",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.100.0.tgz",
+ "integrity": "sha512-4uNyvzHoraXEeCamR3+fzcBlh7Afs4Ifjs4epINyUX/jvdk0uzLnwiDY35UKDKnkCHP5Nu3dljl2H8lR6s+rQw==",
"dev": true
},
"@types/which": {
@@ -16600,23 +17125,52 @@
}
},
"@typescript-eslint/eslint-plugin": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz",
- "integrity": "sha512-PQg0emRtzZFWq6PxBcdxRH3QIQiyFO3WCVpRL3fgj5oQS3CDs3AeAKfv4DxNhzn8ITdNJGJ4D3Qw8eAJf3lXeQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "dev": true,
+ "requires": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ }
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"requires": {
- "@typescript-eslint/experimental-utils": "3.10.1",
- "debug": "^4.1.1",
- "functional-red-black-tree": "^1.0.1",
- "regexpp": "^3.0.0",
- "semver": "^7.3.2",
- "tsutils": "^3.17.1"
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4"
},
"dependencies": {
"debug": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"requires": {
"ms": "2.1.2"
@@ -16624,78 +17178,127 @@
}
}
},
- "@typescript-eslint/experimental-utils": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz",
- "integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==",
+ "@typescript-eslint/scope-manager": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
"dev": true,
"requires": {
- "@types/json-schema": "^7.0.3",
- "@typescript-eslint/types": "3.10.1",
- "@typescript-eslint/typescript-estree": "3.10.1",
- "eslint-scope": "^5.0.0",
- "eslint-utils": "^2.0.0"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
}
},
- "@typescript-eslint/parser": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.10.1.tgz",
- "integrity": "sha512-Ug1RcWcrJP02hmtaXVS3axPPTTPnZjupqhgj+NnZ6BCkwSImWk/283347+x9wN+lqOdK9Eo3vsyiyDHgsmiEJw==",
+ "@typescript-eslint/type-utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
"dev": true,
"requires": {
- "@types/eslint-visitor-keys": "^1.0.0",
- "@typescript-eslint/experimental-utils": "3.10.1",
- "@typescript-eslint/types": "3.10.1",
- "@typescript-eslint/typescript-estree": "3.10.1",
- "eslint-visitor-keys": "^1.1.0"
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ }
}
},
"@typescript-eslint/types": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz",
- "integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz",
- "integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "3.10.1",
- "@typescript-eslint/visitor-keys": "3.10.1",
- "debug": "^4.1.1",
- "glob": "^7.1.6",
- "is-glob": "^4.0.1",
- "lodash": "^4.17.15",
- "semver": "^7.3.2",
- "tsutils": "^3.17.1"
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
"debug": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
- "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
+ "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
+ },
+ "minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ }
+ }
+ },
+ "@typescript-eslint/utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "dev": true,
+ "requires": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "semver": "^7.5.4"
+ },
+ "dependencies": {
+ "@types/semver": {
+ "version": "7.5.8",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+ "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
+ "dev": true
}
}
},
"@typescript-eslint/visitor-keys": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz",
- "integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==",
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
"dev": true,
"requires": {
- "eslint-visitor-keys": "^1.1.0"
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
}
},
- "@ungap/promise-all-settled": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
- "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
+ "@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
"dev": true
},
"@vscode/extension-telemetry": {
@@ -16709,60 +17312,6 @@
"applicationinsights": "^2.7.1"
}
},
- "@vscode/jupyter-lsp-middleware": {
- "version": "0.2.50",
- "resolved": "https://registry.npmjs.org/@vscode/jupyter-lsp-middleware/-/jupyter-lsp-middleware-0.2.50.tgz",
- "integrity": "sha512-oOEpRZOJdKjByRMkUDVdGlQDiEO4/Mjr88u5zqktaS/4h0NtX8Hk6+HNQwENp4ur3Dpu47gD8wOTCrkOWzbHlA==",
- "requires": {
- "@vscode/lsp-notebook-concat": "^0.1.16",
- "fast-myers-diff": "^3.0.1",
- "sha.js": "^2.4.11",
- "vscode-languageclient": "^8.0.2-next.4",
- "vscode-languageserver-protocol": "^3.17.2-next.5",
- "vscode-uri": "^3.0.2"
- },
- "dependencies": {
- "vscode-jsonrpc": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz",
- "integrity": "sha512-6TDy/abTQk+zDGYazgbIPc+4JoXdwC8NHU9Pbn4UJP1fehUyZmM4RHp5IthX7A6L5KS30PRui+j+tbbMMMafdw=="
- },
- "vscode-languageclient": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.1.0.tgz",
- "integrity": "sha512-GL4QdbYUF/XxQlAsvYWZRV3V34kOkpRlvV60/72ghHfsYFnS/v2MANZ9P6sHmxFcZKOse8O+L9G7Czg0NUWing==",
- "requires": {
- "minimatch": "^5.1.0",
- "semver": "^7.3.7",
- "vscode-languageserver-protocol": "3.17.3"
- }
- },
- "vscode-languageserver-protocol": {
- "version": "3.17.3",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.3.tgz",
- "integrity": "sha512-924/h0AqsMtA5yK22GgMtCYiMdCOtWTSGgUOkgEDX+wk2b0x4sAfLiO4NxBxqbiVtz7K7/1/RgVrVI0NClZwqA==",
- "requires": {
- "vscode-jsonrpc": "8.1.0",
- "vscode-languageserver-types": "3.17.3"
- }
- },
- "vscode-languageserver-types": {
- "version": "3.17.3",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.3.tgz",
- "integrity": "sha512-SYU4z1dL0PyIMd4Vj8YOqFvHu7Hz/enbWtpfnVbJHU4Nd1YNYx8u0ennumc6h48GQNeOLxmwySmnADouT/AuZA=="
- }
- }
- },
- "@vscode/lsp-notebook-concat": {
- "version": "0.1.16",
- "resolved": "https://registry.npmjs.org/@vscode/lsp-notebook-concat/-/lsp-notebook-concat-0.1.16.tgz",
- "integrity": "sha512-jN2ut22GR/xelxHx2W9U+uZoylHGCezsNmsMYn20LgVHTcJMGL+4bL5PJeh63yo6P5XjAPtoeeymvp5EafJV+w==",
- "requires": {
- "object-hash": "^3.0.0",
- "vscode-languageserver-protocol": "^3.17.2-next.5",
- "vscode-uri": "^3.0.2"
- }
- },
"@vscode/test-electron": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz",
@@ -16776,15 +17325,19 @@
}
},
"@vscode/vsce": {
- "version": "2.19.0",
- "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.19.0.tgz",
- "integrity": "sha512-dAlILxC5ggOutcvJY24jxz913wimGiUrHaPkk16Gm9/PGFbz1YezWtrXsTKUtJws4fIlpX2UIlVlVESWq8lkfQ==",
+ "version": "2.27.0",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.27.0.tgz",
+ "integrity": "sha512-FFUMBVSyyjjJpWszwqk7d4U3YllY8FdWslbUDMRki1x4ZjA3Z0hmRMfypWrjP9sptbSR9nyPFU4uqjhy2qRB/w==",
"dev": true,
"requires": {
- "azure-devops-node-api": "^11.0.1",
+ "@azure/identity": "^4.1.0",
+ "@vscode/vsce-sign": "^2.0.0",
+ "azure-devops-node-api": "^12.5.0",
"chalk": "^2.4.2",
"cheerio": "^1.0.0-rc.9",
- "commander": "^6.1.0",
+ "cockatiel": "^3.1.2",
+ "commander": "^6.2.1",
+ "form-data": "^4.0.0",
"glob": "^7.0.6",
"hosted-git-info": "^4.0.2",
"jsonc-parser": "^3.2.0",
@@ -16795,7 +17348,7 @@
"minimatch": "^3.0.3",
"parse-semver": "^1.1.1",
"read": "^1.0.7",
- "semver": "^5.1.0",
+ "semver": "^7.5.2",
"tmp": "^0.2.1",
"typed-rest-client": "^1.8.4",
"url-join": "^4.0.1",
@@ -16820,174 +17373,239 @@
}
},
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
- },
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
- },
- "tmp": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
- "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
- "dev": true,
- "requires": {
- "rimraf": "^3.0.0"
- }
}
}
},
+ "@vscode/vsce-sign": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.4.tgz",
+ "integrity": "sha512-0uL32egStKYfy60IqnynAChMTbL0oqpqk0Ew0YHiIb+fayuGZWADuIPHWUcY1GCnAA+VgchOPDMxnc2R3XGWEA==",
+ "dev": true,
+ "requires": {
+ "@vscode/vsce-sign-alpine-arm64": "2.0.2",
+ "@vscode/vsce-sign-alpine-x64": "2.0.2",
+ "@vscode/vsce-sign-darwin-arm64": "2.0.2",
+ "@vscode/vsce-sign-darwin-x64": "2.0.2",
+ "@vscode/vsce-sign-linux-arm": "2.0.2",
+ "@vscode/vsce-sign-linux-arm64": "2.0.2",
+ "@vscode/vsce-sign-linux-x64": "2.0.2",
+ "@vscode/vsce-sign-win32-arm64": "2.0.2",
+ "@vscode/vsce-sign-win32-x64": "2.0.2"
+ }
+ },
+ "@vscode/vsce-sign-alpine-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz",
+ "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-alpine-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz",
+ "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-darwin-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz",
+ "integrity": "sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-darwin-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz",
+ "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-linux-arm": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz",
+ "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-linux-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz",
+ "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-linux-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz",
+ "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-win32-arm64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz",
+ "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@vscode/vsce-sign-win32-x64": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz",
+ "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==",
+ "dev": true,
+ "optional": true
+ },
"@webassemblyjs/ast": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
- "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"dev": true,
"requires": {
- "@webassemblyjs/helper-numbers": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1"
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
}
},
"@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz",
- "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==",
+ "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
},
"@webassemblyjs/helper-api-error": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz",
- "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==",
+ "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
},
"@webassemblyjs/helper-buffer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz",
- "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
"dev": true
},
"@webassemblyjs/helper-numbers": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz",
- "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"dev": true,
"requires": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
"@xtuc/long": "4.2.2"
}
},
"@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz",
- "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
"dev": true
},
"@webassemblyjs/helper-wasm-section": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz",
- "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
}
},
"@webassemblyjs/ieee754": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz",
- "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"dev": true,
"requires": {
"@xtuc/ieee754": "^1.2.0"
}
},
"@webassemblyjs/leb128": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz",
- "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"dev": true,
"requires": {
"@xtuc/long": "4.2.2"
}
},
"@webassemblyjs/utf8": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz",
- "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
"dev": true
},
"@webassemblyjs/wasm-edit": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz",
- "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/helper-wasm-section": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-opt": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
- "@webassemblyjs/wast-printer": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
}
},
"@webassemblyjs/wasm-gen": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz",
- "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"@webassemblyjs/wasm-opt": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz",
- "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-buffer": "1.11.1",
- "@webassemblyjs/wasm-gen": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
}
},
"@webassemblyjs/wasm-parser": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz",
- "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/helper-api-error": "1.11.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.1",
- "@webassemblyjs/ieee754": "1.11.1",
- "@webassemblyjs/leb128": "1.11.1",
- "@webassemblyjs/utf8": "1.11.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"@webassemblyjs/wast-printer": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz",
- "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"dev": true,
"requires": {
- "@webassemblyjs/ast": "1.11.1",
+ "@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
}
},
@@ -17027,9 +17645,9 @@
"dev": true
},
"acorn": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
- "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw=="
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="
},
"acorn-import-assertions": {
"version": "1.9.0",
@@ -17037,6 +17655,13 @@
"integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
"requires": {}
},
+ "acorn-import-phases": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
+ "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
+ "dev": true,
+ "requires": {}
+ },
"acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -17079,9 +17704,9 @@
}
},
"ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@@ -17090,6 +17715,35 @@
"uri-js": "^4.2.2"
}
},
+ "ajv-formats": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
+ "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+ "dev": true,
+ "requires": {
+ "ajv": "^8.0.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ }
+ }
+ },
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
@@ -17106,15 +17760,6 @@
"ansi-wrap": "^0.1.0"
}
},
- "ansi-gray": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
- "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
- "dev": true,
- "requires": {
- "ansi-wrap": "0.1.0"
- }
- },
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -17137,24 +17782,13 @@
"dev": true
},
"anymatch": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
- "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"dev": true,
- "requires": {
- "micromatch": "^3.1.4",
- "normalize-path": "^2.1.1"
- },
- "dependencies": {
- "normalize-path": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
- "dev": true,
- "requires": {
- "remove-trailing-separator": "^1.0.1"
- }
- }
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
}
},
"append-buffer": {
@@ -17211,7 +17845,7 @@
"archive-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
- "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
+ "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==",
"dev": true,
"requires": {
"file-type": "^4.2.0"
@@ -17220,7 +17854,7 @@
"file-type": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
- "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
+ "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==",
"dev": true
}
}
@@ -17252,159 +17886,117 @@
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
"dev": true
},
- "arr-filter": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
- "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
- "dev": true,
- "requires": {
- "make-iterator": "^1.0.0"
- }
- },
- "arr-flatten": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
- "dev": true
- },
- "arr-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
- "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
- "dev": true,
- "requires": {
- "make-iterator": "^1.0.0"
- }
- },
"arr-union": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true
},
+ "array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
+ }
+ },
"array-each": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
- "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==",
"dev": true
},
"array-includes": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz",
- "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==",
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1",
- "get-intrinsic": "^1.1.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
}
},
- "array-initial": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
- "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
- "dev": true,
- "requires": {
- "array-slice": "^1.0.0",
- "is-number": "^4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
- "dev": true
- }
- }
- },
- "array-last": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
- "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
- "dev": true,
- "requires": {
- "is-number": "^4.0.0"
- },
- "dependencies": {
- "is-number": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
- "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
- "dev": true
- }
- }
- },
"array-slice": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
"integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
"dev": true
},
- "array-sort": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
- "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
- "dev": true,
- "requires": {
- "default-compare": "^1.0.0",
- "get-value": "^2.0.6",
- "kind-of": "^5.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
"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
},
- "array-unique": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
- "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
- "dev": true
+ "array.prototype.findlastindex": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
+ "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ }
},
"array.prototype.flat": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz",
- "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+ "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0"
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
}
},
"array.prototype.flatmap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz",
- "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+ "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
"dev": true,
"requires": {
- "call-bind": "^1.0.0",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0"
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ }
+ },
+ "arraybuffer.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+ "dev": true,
+ "requires": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
+ "is-shared-array-buffer": "^1.0.2"
}
},
"asn1.js": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
- "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"dev": true,
"requires": {
"bn.js": "^4.0.0",
"inherits": "^2.0.1",
- "minimalistic-assert": "^1.0.0",
- "safer-buffer": "^2.1.0"
+ "minimalistic-assert": "^1.0.0"
}
},
"assert": {
@@ -17452,12 +18044,6 @@
"integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
"dev": true
},
- "astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "dev": true
- },
"async": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
@@ -17465,23 +18051,16 @@
"dev": true
},
"async-done": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
- "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz",
+ "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==",
"dev": true,
"requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.2",
- "process-nextick-args": "^2.0.0",
- "stream-exhaust": "^1.0.1"
+ "end-of-stream": "^1.4.4",
+ "once": "^1.4.0",
+ "stream-exhaust": "^1.0.2"
}
},
- "async-each": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
- "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
- "dev": true
- },
"async-hook-jl": {
"version": "1.7.6",
"resolved": "https://registry.npmjs.org/async-hook-jl/-/async-hook-jl-1.7.6.tgz",
@@ -17507,12 +18086,12 @@
}
},
"async-settle": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
- "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz",
+ "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==",
"dev": true,
"requires": {
- "async-done": "^1.2.2"
+ "async-done": "^2.0.0"
}
},
"asynckit": {
@@ -17520,17 +18099,14 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
- "atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
- "dev": true
- },
"available-typed-arrays": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
- "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
- "dev": true
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "requires": {
+ "possible-typed-array-names": "^1.0.0"
+ }
},
"axe-core": {
"version": "4.4.1",
@@ -17538,16 +18114,6 @@
"integrity": "sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw==",
"dev": true
},
- "axios": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
- "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
- "requires": {
- "follow-redirects": "^1.15.0",
- "form-data": "^4.0.0",
- "proxy-from-env": "^1.1.0"
- }
- },
"axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
@@ -17555,15 +18121,21 @@
"dev": true
},
"azure-devops-node-api": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.0.1.tgz",
- "integrity": "sha512-YMdjAw9l5p/6leiyIloxj3k7VIvYThKjvqgiQn88r3nhT93ENwsoDS3A83CyJ4uTWzCZ5f5jCi6c27rTU5Pz+A==",
+ "version": "12.5.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz",
+ "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==",
"dev": true,
"requires": {
"tunnel": "0.0.6",
"typed-rest-client": "^1.8.4"
}
},
+ "b4a": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz",
+ "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==",
+ "dev": true
+ },
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -17589,20 +18161,25 @@
}
},
"bach": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
- "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz",
+ "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==",
"dev": true,
"requires": {
- "arr-filter": "^1.1.1",
- "arr-flatten": "^1.0.1",
- "arr-map": "^2.0.0",
- "array-each": "^1.0.0",
- "array-initial": "^1.0.0",
- "array-last": "^1.1.1",
- "async-done": "^1.2.2",
- "async-settle": "^1.0.0",
- "now-and-later": "^2.0.0"
+ "async-done": "^2.0.0",
+ "async-settle": "^2.0.0",
+ "now-and-later": "^3.0.0"
+ },
+ "dependencies": {
+ "now-and-later": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz",
+ "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ }
}
},
"balanced-match": {
@@ -17610,60 +18187,12 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
- "base": {
- "version": "0.11.2",
- "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
- "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "bare-events": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.3.1.tgz",
+ "integrity": "sha512-sJnSOTVESURZ61XgEleqmP255T6zTYwHPwE4r6SssIh0U9/uDvfpdoJYpVUerJJZH2fueO+CdT8ZT+OC/7aZDA==",
"dev": true,
- "requires": {
- "cache-base": "^1.0.1",
- "class-utils": "^0.3.5",
- "component-emitter": "^1.2.1",
- "define-property": "^1.0.0",
- "isobject": "^3.0.1",
- "mixin-deep": "^1.2.0",
- "pascalcase": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
+ "optional": true
},
"base64-js": {
"version": "1.5.1",
@@ -17671,6 +18200,12 @@
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true
},
+ "baseline-browser-mapping": {
+ "version": "2.9.19",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
+ "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
+ "dev": true
+ },
"bent": {
"version": "7.3.12",
"resolved": "https://registry.npmjs.org/bent/-/bent-7.3.12.tgz",
@@ -17702,16 +18237,6 @@
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
},
- "bindings": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
- "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
- "dev": true,
- "optional": true,
- "requires": {
- "file-uri-to-path": "1.0.0"
- }
- },
"bl": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
@@ -17723,9 +18248,9 @@
}
},
"bn.js": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+ "version": "4.12.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz",
+ "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==",
"dev": true
},
"boolbase": {
@@ -17735,41 +18260,21 @@
"dev": true
},
"brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
+ "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
- "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"requires": {
- "arr-flatten": "^1.1.0",
- "array-unique": "^0.3.2",
- "extend-shallow": "^2.0.1",
- "fill-range": "^4.0.0",
- "isobject": "^3.0.1",
- "repeat-element": "^1.1.2",
- "snapdragon": "^0.8.1",
- "snapdragon-node": "^2.0.1",
- "split-string": "^3.0.2",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "fill-range": "^7.1.1"
}
},
"brorand": {
@@ -17822,57 +18327,53 @@
}
},
"browserify-rsa": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
- "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
+ "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
"dev": true,
"requires": {
- "bn.js": "^5.0.0",
- "randombytes": "^2.0.1"
+ "bn.js": "^5.2.1",
+ "randombytes": "^2.1.0",
+ "safe-buffer": "^5.2.1"
},
"dependencies": {
"bn.js": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz",
+ "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==",
+ "dev": true
+ },
+ "safe-buffer": {
"version": "5.2.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
- "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
}
}
},
"browserify-sign": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz",
- "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==",
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz",
+ "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==",
"dev": true,
"requires": {
- "bn.js": "^5.2.1",
- "browserify-rsa": "^4.1.0",
+ "bn.js": "^5.2.2",
+ "browserify-rsa": "^4.1.1",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
- "elliptic": "^6.5.4",
+ "elliptic": "^6.6.1",
"inherits": "^2.0.4",
- "parse-asn1": "^5.1.6",
- "readable-stream": "^3.6.2",
+ "parse-asn1": "^5.1.9",
+ "readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1"
},
"dependencies": {
"bn.js": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
- "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz",
+ "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==",
"dev": true
},
- "readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dev": true,
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -17891,15 +18392,16 @@
}
},
"browserslist": {
- "version": "4.21.9",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
- "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
+ "version": "4.28.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
+ "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001503",
- "electron-to-chromium": "^1.4.431",
- "node-releases": "^2.0.12",
- "update-browserslist-db": "^1.0.11"
+ "baseline-browser-mapping": "^2.9.0",
+ "caniuse-lite": "^1.0.30001759",
+ "electron-to-chromium": "^1.5.263",
+ "node-releases": "^2.0.27",
+ "update-browserslist-db": "^1.2.0"
}
},
"buffer": {
@@ -17934,10 +18436,16 @@
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true
},
+ "buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "dev": true
+ },
"buffer-fill": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
- "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+ "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==",
"dev": true
},
"buffer-from": {
@@ -17964,23 +18472,6 @@
"integrity": "sha512-i4uu6M4zuMUiyfZN4RU2+i9+peJh//pXhd9x1oSe1LBkZ3LEbCoygu8W0bXTukU1Jme2txKuotpCZRaC3FLxcQ==",
"dev": true
},
- "cache-base": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
- "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
- "dev": true,
- "requires": {
- "collection-visit": "^1.0.0",
- "component-emitter": "^1.2.1",
- "get-value": "^2.0.6",
- "has-value": "^1.0.0",
- "isobject": "^3.0.1",
- "set-value": "^2.0.0",
- "to-object-path": "^0.3.0",
- "union-value": "^1.0.0",
- "unset-value": "^1.0.0"
- }
- },
"cacheable-request": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
@@ -17996,10 +18487,16 @@
"responselike": "1.0.2"
},
"dependencies": {
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+ "dev": true
+ },
"lowercase-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
- "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+ "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==",
"dev": true
}
}
@@ -18017,15 +18514,42 @@
}
},
"call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "requires": {
+ "call-bind-apply-helpers": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.2"
+ }
+ },
+ "call-bind-apply-helpers": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "requires": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ }
+ },
+ "call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"dev": true,
"requires": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
}
},
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
@@ -18033,9 +18557,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001512",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz",
- "integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==",
+ "version": "1.0.30001768",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001768.tgz",
+ "integrity": "sha512-qY3aDRZC5nWPgHUgIB84WL+nySuo19wk0VJpp/XI9T34lrvkyhRvNVOFJOp2kxClQhiFBu+TaUSudf6oa3vkSA==",
"dev": true
},
"caseless": {
@@ -18274,34 +18798,6 @@
"readdirp": "~3.6.0"
},
"dependencies": {
- "anymatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
- "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
- "dev": true,
- "requires": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- }
- },
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -18310,21 +18806,6 @@
"requires": {
"is-glob": "^4.0.1"
}
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
}
}
},
@@ -18345,13 +18826,22 @@
}
},
"cipher-base": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
- "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz",
+ "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==",
"dev": true,
"requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
}
},
"circular-json": {
@@ -18362,31 +18852,8 @@
},
"cjs-module-lexer": {
"version": "1.2.3",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
- "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="
- },
- "class-utils": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
- "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "define-property": "^0.2.5",
- "isobject": "^3.0.0",
- "static-extend": "^0.1.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
- }
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz",
+ "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ=="
},
"clean-stack": {
"version": "2.2.0",
@@ -18395,31 +18862,14 @@
"dev": true
},
"cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==",
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
- "dev": true
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- }
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
}
},
"clone": {
@@ -18448,7 +18898,7 @@
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
"dev": true,
"requires": {
"mimic-response": "^1.0.0"
@@ -18488,44 +18938,12 @@
}
}
},
- "code-point-at": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
- "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
+ "cockatiel": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.1.3.tgz",
+ "integrity": "sha512-xC759TpZ69d7HhfDp8m2WkRwEUiCkxY8Ee2OQH/3H6zmy2D/5Sm+zSTbPRa+V2QyjDtpMvjOIAOVjA2gp6N1kQ==",
"dev": true
},
- "collection-map": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
- "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
- "dev": true,
- "requires": {
- "arr-map": "^2.0.2",
- "for-own": "^1.0.0",
- "make-iterator": "^1.0.0"
- },
- "dependencies": {
- "for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "requires": {
- "for-in": "^1.0.1"
- }
- }
- }
- },
- "collection-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
- "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
- "dev": true,
- "requires": {
- "map-visit": "^1.0.0",
- "object-visit": "^1.0.0"
- }
- },
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@@ -18541,12 +18959,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
- "color-support": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
- "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
- "dev": true
- },
"colorette": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz",
@@ -18579,35 +18991,11 @@
"integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==",
"dev": true
},
- "component-emitter": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
- "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
- "dev": true
- },
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
- "concat-stream": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
- "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^2.2.2",
- "typedarray": "^0.0.6"
- }
- },
- "confusing-browser-globals": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz",
- "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==",
- "dev": true
- },
"console-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
@@ -18621,12 +19009,20 @@
"dev": true
},
"content-disposition": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
- "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dev": true,
"requires": {
- "safe-buffer": "5.1.2"
+ "safe-buffer": "5.2.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
}
},
"continuation-local-storage": {
@@ -18644,19 +19040,13 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
- "copy-descriptor": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
- "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
- "dev": true
- },
"copy-props": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz",
- "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz",
+ "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==",
"dev": true,
"requires": {
- "each-props": "^1.3.2",
+ "each-props": "^3.0.0",
"is-plain-object": "^5.0.0"
},
"dependencies": {
@@ -18694,9 +19084,9 @@
}
},
"core-js-pure": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.4.tgz",
- "integrity": "sha512-uJ4Z7iPNwiu1foygbcZYJsJs1jiXrTTCvxfLDXNhI/I+NHbSIEyr548y4fcsCEyWY0XgfAG/qqaunJ1SThHenA==",
+ "version": "3.42.0",
+ "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.42.0.tgz",
+ "integrity": "sha512-007bM04u91fF4kMgwom2I5cQxAFIy8jVulgr9eozILl/SZE53QOqnW/+vviC+wQWLv+AunBG+8Q0TLoeSsSxRQ==",
"dev": true
},
"core-util-is": {
@@ -18706,13 +19096,13 @@
"dev": true
},
"create-ecdh": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
- "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
"dev": true,
"requires": {
"bn.js": "^4.1.0",
- "elliptic": "^6.0.0"
+ "elliptic": "^6.5.3"
}
},
"create-hash": {
@@ -18748,10 +19138,53 @@
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true
},
+ "cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.1"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ }
+ }
+ },
"cross-spawn": {
- "version": "6.0.5",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
- "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "version": "6.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
+ "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
@@ -18785,32 +19218,23 @@
"dev": true
},
"crypto-browserify": {
- "version": "3.12.0",
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
- "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
- "dev": true,
- "requires": {
- "browserify-cipher": "^1.0.0",
- "browserify-sign": "^4.0.0",
- "create-ecdh": "^4.0.0",
- "create-hash": "^1.1.0",
- "create-hmac": "^1.1.0",
- "diffie-hellman": "^5.0.0",
- "inherits": "^2.0.1",
- "pbkdf2": "^3.0.3",
- "public-encrypt": "^4.0.0",
- "randombytes": "^2.0.0",
- "randomfill": "^1.0.3"
- }
- },
- "d": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
- "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+ "version": "3.12.1",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
+ "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
"dev": true,
"requires": {
- "es5-ext": "^0.10.50",
- "type": "^1.0.1"
+ "browserify-cipher": "^1.0.1",
+ "browserify-sign": "^4.2.3",
+ "create-ecdh": "^4.0.4",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "diffie-hellman": "^5.0.3",
+ "hash-base": "~3.0.4",
+ "inherits": "^2.0.4",
+ "pbkdf2": "^3.1.2",
+ "public-encrypt": "^4.0.3",
+ "randombytes": "^2.1.0",
+ "randomfill": "^1.0.4"
}
},
"damerau-levenshtein": {
@@ -18819,6 +19243,39 @@
"integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
"dev": true
},
+ "data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ }
+ },
+ "data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ }
+ },
+ "data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ }
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -18876,7 +19333,7 @@
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
"dev": true
}
}
@@ -18884,7 +19341,7 @@
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true
}
}
@@ -18892,7 +19349,7 @@
"decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
- "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==",
"dev": true,
"requires": {
"mimic-response": "^1.0.0"
@@ -18912,7 +19369,7 @@
"file-type": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
- "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
"dev": true
}
}
@@ -18952,7 +19409,7 @@
"file-type": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
- "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
"dev": true
}
}
@@ -18960,7 +19417,7 @@
"decompress-unzip": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
- "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
+ "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==",
"dev": true,
"requires": {
"file-type": "^3.8.0",
@@ -18972,13 +19429,13 @@
"file-type": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
- "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
+ "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==",
"dev": true
},
"get-stream": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
- "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
+ "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==",
"dev": true,
"requires": {
"object-assign": "^4.0.1",
@@ -18988,7 +19445,7 @@
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
"dev": true
}
}
@@ -19015,23 +19472,6 @@
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
- "default-compare": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
- "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
- "dev": true,
- "requires": {
- "kind-of": "^5.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
"default-require-extensions": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
@@ -19049,60 +19489,32 @@
}
}
},
- "default-resolution": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
- "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
- "dev": true
- },
- "define-properties": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
- "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"requires": {
- "object-keys": "^1.0.12"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
}
},
- "define-property": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
- "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "define-lazy-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+ "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
"requires": {
- "is-descriptor": "^1.0.2",
- "isobject": "^3.0.1"
- },
- "dependencies": {
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
+ "define-data-property": "^1.0.1",
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
}
},
"del": {
@@ -19139,7 +19551,7 @@
"detect-file": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
- "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==",
"dev": true
},
"detect-libc": {
@@ -19164,9 +19576,9 @@
"requires": {}
},
"diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
+ "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
"dev": true
},
"diffie-hellman": {
@@ -19223,15 +19635,6 @@
"pify": "^4.0.1"
},
"dependencies": {
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "dev": true,
- "requires": {
- "pump": "^3.0.0"
- }
- },
"make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@@ -19242,16 +19645,6 @@
"semver": "^5.6.0"
}
},
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
@@ -19260,6 +19653,16 @@
}
}
},
+ "dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "requires": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ }
+ },
"duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
@@ -19267,9 +19670,9 @@
"dev": true
},
"duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
+ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==",
"dev": true
},
"duplexify": {
@@ -19285,25 +19688,48 @@
}
},
"each-props": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
- "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz",
+ "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==",
"dev": true,
"requires": {
- "is-plain-object": "^2.0.1",
+ "is-plain-object": "^5.0.0",
"object.defaults": "^1.1.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true
+ },
+ "ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
}
},
"electron-to-chromium": {
- "version": "1.4.450",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.450.tgz",
- "integrity": "sha512-BLG5HxSELlrMx7dJ2s+8SFlsCtJp37Zpk2VAxyC6CZtbc+9AJeZHfYHbrlSgdXp6saQ8StMqOTEDaBKgA7u1sw==",
+ "version": "1.5.286",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
+ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
"dev": true
},
"elliptic": {
- "version": "6.5.4",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
- "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+ "version": "6.6.1",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
+ "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
"dev": true,
"requires": {
"bn.js": "^4.11.9",
@@ -19313,14 +19739,6 @@
"inherits": "^2.0.4",
"minimalistic-assert": "^1.0.1",
"minimalistic-crypto-utils": "^1.0.1"
- },
- "dependencies": {
- "bn.js": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
- "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
- "dev": true
- }
}
},
"emitter-listener": {
@@ -19344,39 +19762,22 @@
"dev": true
},
"end-of-stream": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
- "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"enhanced-resolve": {
- "version": "5.12.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
- "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
+ "version": "5.19.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz",
+ "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
- }
- },
- "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,
- "requires": {
- "ansi-colors": "^4.1.1"
- },
- "dependencies": {
- "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
- }
+ "tapable": "^2.3.0"
}
},
"entities": {
@@ -19391,48 +19792,103 @@
"integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==",
"dev": true
},
- "error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
- "requires": {
- "is-arrayish": "^0.2.1"
- }
- },
"es-abstract": {
- "version": "1.19.2",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.2.tgz",
- "integrity": "sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==",
- "dev": true,
- "requires": {
- "call-bind": "^1.0.2",
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+ "dev": true,
+ "requires": {
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.1.1",
- "get-symbol-description": "^1.0.0",
- "has": "^1.0.3",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
- "is-callable": "^1.2.4",
- "is-negative-zero": "^2.0.2",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.1",
+ "is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
+ "is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
- "object-inspect": "^1.12.0",
+ "object-inspect": "^1.13.1",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.2",
- "string.prototype.trimend": "^1.0.4",
- "string.prototype.trimstart": "^1.0.4",
- "unbox-primitive": "^1.0.1"
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.2",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.15"
+ }
+ },
+ "es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
+ },
+ "es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
+ },
+ "es-module-lexer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz",
+ "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==",
+ "dev": true
+ },
+ "es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "requires": {
+ "es-errors": "^1.3.0"
}
},
- "es-module-lexer": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
- "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==",
- "dev": true
+ "es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "requires": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ }
+ },
+ "es-shim-unscopables": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+ "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+ "dev": true,
+ "requires": {
+ "hasown": "^2.0.0"
+ }
},
"es-to-primitive": {
"version": "1.2.1",
@@ -19445,74 +19901,22 @@
"is-symbol": "^1.0.2"
}
},
- "es5-ext": {
- "version": "0.10.53",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
- "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
- "dev": true,
- "requires": {
- "es6-iterator": "~2.0.3",
- "es6-symbol": "~3.1.3",
- "next-tick": "~1.0.0"
- },
- "dependencies": {
- "next-tick": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
- "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
- "dev": true
- }
- }
- },
"es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"dev": true
},
- "es6-iterator": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
- "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
- "dev": true,
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.35",
- "es6-symbol": "^3.1.1"
- }
- },
"es6-object-assign": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
"integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=",
"dev": true
},
- "es6-symbol": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
- "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
- "dev": true,
- "requires": {
- "d": "^1.0.1",
- "ext": "^1.1.2"
- }
- },
- "es6-weak-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
- "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
- "dev": true,
- "requires": {
- "d": "1",
- "es5-ext": "^0.10.46",
- "es6-iterator": "^2.0.3",
- "es6-symbol": "^3.1.1"
- }
- },
"escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true
},
"escape-string-regexp": {
@@ -19522,51 +19926,49 @@
"dev": true
},
"eslint": {
- "version": "7.32.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
- "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "7.12.11",
- "@eslint/eslintrc": "^0.4.3",
- "@humanwhocodes/config-array": "^0.5.0",
- "ajv": "^6.10.0",
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "dev": true,
+ "requires": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
- "debug": "^4.0.1",
+ "debug": "^4.3.2",
"doctrine": "^3.0.0",
- "enquirer": "^2.3.5",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^5.1.1",
- "eslint-utils": "^2.1.0",
- "eslint-visitor-keys": "^2.0.0",
- "espree": "^7.3.1",
- "esquery": "^1.4.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
- "functional-red-black-tree": "^1.0.1",
- "glob-parent": "^5.1.2",
- "globals": "^13.6.0",
- "ignore": "^4.0.6",
- "import-fresh": "^3.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
- "js-yaml": "^3.13.1",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash.merge": "^4.6.2",
- "minimatch": "^3.0.4",
+ "minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
- "optionator": "^0.9.1",
- "progress": "^2.0.0",
- "regexpp": "^3.1.0",
- "semver": "^7.2.1",
- "strip-ansi": "^6.0.0",
- "strip-json-comments": "^3.1.0",
- "table": "^6.0.9",
- "text-table": "^0.2.0",
- "v8-compile-cache": "^2.0.3"
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
},
"dependencies": {
"ansi-styles": {
@@ -19579,6 +19981,12 @@
"color-convert": "^2.0.1"
}
},
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
@@ -19605,9 +20013,9 @@
"dev": true
},
"cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
@@ -19639,25 +20047,45 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
- "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==",
+ "eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ }
+ },
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true
},
+ "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,
+ "requires": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
"glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"requires": {
- "is-glob": "^4.0.1"
+ "is-glob": "^4.0.3"
}
},
"globals": {
- "version": "13.12.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz",
- "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==",
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@@ -19669,33 +20097,57 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "ignore": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
- "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
- "dev": true
+ "js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^5.0.0"
+ }
},
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^3.0.2"
+ }
+ },
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
- "progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true
- },
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -19728,28 +20180,6 @@
}
}
},
- "eslint-config-airbnb": {
- "version": "18.2.1",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz",
- "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==",
- "dev": true,
- "requires": {
- "eslint-config-airbnb-base": "^14.2.1",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.2"
- }
- },
- "eslint-config-airbnb-base": {
- "version": "14.2.1",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz",
- "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==",
- "dev": true,
- "requires": {
- "confusing-browser-globals": "^1.0.10",
- "object.assign": "^4.1.2",
- "object.entries": "^1.1.2"
- }
- },
"eslint-config-prettier": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
@@ -19758,13 +20188,14 @@
"requires": {}
},
"eslint-import-resolver-node": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
- "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
"dev": true,
"requires": {
"debug": "^3.2.7",
- "resolve": "^1.20.0"
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
},
"dependencies": {
"debug": {
@@ -19779,13 +20210,12 @@
}
},
"eslint-module-utils": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
- "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
"dev": true,
"requires": {
- "debug": "^3.2.7",
- "find-up": "^2.1.0"
+ "debug": "^3.2.7"
},
"dependencies": {
"debug": {
@@ -19796,81 +20226,59 @@
"requires": {
"ms": "^2.1.1"
}
- },
- "find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
- "dev": true,
- "requires": {
- "locate-path": "^2.0.0"
- }
- },
- "locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
- "dev": true,
- "requires": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
- }
- },
- "p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "requires": {
- "p-try": "^1.0.0"
- }
- },
- "p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
- "dev": true,
- "requires": {
- "p-limit": "^1.1.0"
- }
- },
- "p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
- "dev": true
}
}
},
"eslint-plugin-import": {
- "version": "2.25.4",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz",
- "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==",
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
"requires": {
- "array-includes": "^3.1.4",
- "array.prototype.flat": "^1.2.5",
- "debug": "^2.6.9",
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlastindex": "^1.2.5",
+ "array.prototype.flat": "^1.3.2",
+ "array.prototype.flatmap": "^1.3.2",
+ "debug": "^3.2.7",
"doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.6",
- "eslint-module-utils": "^2.7.2",
- "has": "^1.0.3",
- "is-core-module": "^2.8.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.0",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.15.1",
"is-glob": "^4.0.3",
- "minimatch": "^3.0.4",
- "object.values": "^1.1.5",
- "resolve": "^1.20.0",
- "tsconfig-paths": "^3.12.0"
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.0",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
+ "tsconfig-paths": "^3.15.0"
},
"dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
+ },
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true
}
}
},
@@ -19911,9 +20319,9 @@
"dev": true
},
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
@@ -19921,6 +20329,12 @@
}
}
},
+ "eslint-plugin-no-only-tests": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.3.0.tgz",
+ "integrity": "sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==",
+ "dev": true
+ },
"eslint-plugin-react": {
"version": "7.29.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz",
@@ -19950,9 +20364,9 @@
"dev": true
},
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
@@ -19993,44 +20407,27 @@
"estraverse": "^4.1.1"
}
},
- "eslint-utils": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
- "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
- "dev": true,
- "requires": {
- "eslint-visitor-keys": "^1.1.0"
- }
- },
"eslint-visitor-keys": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
- "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true
},
"espree": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
- "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
"requires": {
- "acorn": "^7.4.0",
- "acorn-jsx": "^5.3.1",
- "eslint-visitor-keys": "^1.3.0"
- },
- "dependencies": {
- "acorn": {
- "version": "7.4.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
- "dev": true
- }
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
}
},
"esquery": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
- "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
@@ -20107,9 +20504,9 @@
},
"dependencies": {
"cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
@@ -20152,41 +20549,6 @@
}
}
},
- "expand-brackets": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
- "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
- "dev": true,
- "requires": {
- "debug": "^2.3.3",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "posix-character-classes": "^0.1.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
- }
- },
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
@@ -20197,7 +20559,7 @@
"expand-tilde": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
- "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
"dev": true,
"requires": {
"homedir-polyfill": "^1.0.1"
@@ -20210,23 +20572,6 @@
"dev": true,
"requires": {}
},
- "ext": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
- "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
- "dev": true,
- "requires": {
- "type": "^2.5.0"
- },
- "dependencies": {
- "type": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz",
- "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==",
- "dev": true
- }
- }
- },
"ext-list": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
@@ -20265,97 +20610,26 @@
"is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
- },
- "extglob": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
- "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
- "dev": true,
- "requires": {
- "array-unique": "^0.3.2",
- "define-property": "^1.0.0",
- "expand-brackets": "^2.1.4",
- "extend-shallow": "^2.0.1",
- "fragment-cache": "^0.2.1",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
"dev": true,
"requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
+ "is-plain-object": "^2.0.4"
}
}
}
},
- "fancy-log": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
- "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
- "dev": true,
- "requires": {
- "ansi-gray": "^0.1.1",
- "color-support": "^1.1.3",
- "parse-node-version": "^1.0.0",
- "time-stamp": "^1.0.0"
- }
- },
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
+ "fast-fifo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
+ "dev": true
+ },
"fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -20369,24 +20643,6 @@
"micromatch": "^4.0.4"
},
"dependencies": {
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
"glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@@ -20395,31 +20651,6 @@
"requires": {
"is-glob": "^4.0.1"
}
- },
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
- "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
- "dev": true,
- "requires": {
- "braces": "^3.0.1",
- "picomatch": "^2.2.3"
- }
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
}
}
},
@@ -20435,10 +20666,11 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
- "fast-myers-diff": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/fast-myers-diff/-/fast-myers-diff-3.0.1.tgz",
- "integrity": "sha512-e8p26utONwDXeSDkDqu4jaR3l3r6ZgQO2GWB178ePZxCfFoRPNTJVZylUEHHG6uZeRikL1zCc2sl4sIAs9c0UQ=="
+ "fast-uri": {
+ "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
},
"fastest-levenshtein": {
"version": "1.0.12",
@@ -20479,17 +20711,10 @@
"integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==",
"dev": true
},
- "file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
- "dev": true,
- "optional": true
- },
"filename-reserved-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
- "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
+ "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
"dev": true
},
"filenamify": {
@@ -20504,26 +20729,12 @@
}
},
"fill-range": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
- "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
- "extend-shallow": "^2.0.1",
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1",
- "to-regex-range": "^2.1.0"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "to-regex-range": "^5.0.1"
}
},
"filter-obj": {
@@ -20551,45 +20762,45 @@
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
- },
- "dependencies": {
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- }
}
},
"findup-sync": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
- "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
"dev": true,
"requires": {
"detect-file": "^1.0.0",
- "is-glob": "^4.0.0",
- "micromatch": "^3.0.4",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
"resolve-dir": "^1.0.1"
}
},
"fined": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
- "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz",
+ "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==",
"dev": true,
"requires": {
"expand-tilde": "^2.0.2",
- "is-plain-object": "^2.0.3",
+ "is-plain-object": "^5.0.0",
"object.defaults": "^1.1.0",
- "object.pick": "^1.2.0",
- "parse-filepath": "^1.0.1"
+ "object.pick": "^1.3.0",
+ "parse-filepath": "^1.0.2"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
}
},
"flagged-respawn": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
- "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz",
+ "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==",
"dev": true
},
"flat": {
@@ -20609,9 +20820,9 @@
}
},
"flatted": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz",
- "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==",
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
"dev": true
},
"flush-write-stream": {
@@ -20624,22 +20835,29 @@
"readable-stream": "^2.3.6"
}
},
- "follow-redirects": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
- "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
+ "for-each": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.2.7"
+ }
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
"dev": true
},
- "foreach": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
- "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
- "dev": true
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.1"
+ }
},
"foreground-child": {
"version": "2.0.0",
@@ -20652,9 +20870,9 @@
},
"dependencies": {
"cross-spawn": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
- "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
@@ -20686,28 +20904,21 @@
}
},
"form-data": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
- "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
"mime-types": "^2.1.12"
}
},
- "fragment-cache": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
- "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
- "dev": true,
- "requires": {
- "map-cache": "^0.2.2"
- }
- },
"from2": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
- "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
"dev": true,
"requires": {
"inherits": "^2.0.1",
@@ -20727,9 +20938,9 @@
"dev": true
},
"fs-extra": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz",
- "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==",
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -20784,14 +20995,26 @@
"optional": true
},
"function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
},
- "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=",
+ "function.prototype.name": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
+ }
+ },
+ "functions-have-names": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+ "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true
},
"gensync": {
@@ -20801,9 +21024,9 @@
"dev": true
},
"get-caller-file": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
- "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"get-func-name": {
@@ -20813,14 +21036,20 @@
"dev": true
},
"get-intrinsic": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
- "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
- "dev": true,
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"requires": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.1"
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
}
},
"get-package-type": {
@@ -20835,28 +21064,47 @@
"integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==",
"dev": true
},
+ "get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "requires": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ }
+ },
"get-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
- "dev": true
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+ "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
},
"get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
}
},
- "get-value": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
- "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
- "dev": true
- },
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
@@ -20878,9 +21126,9 @@
},
"dependencies": {
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -20933,77 +21181,13 @@
"dev": true
},
"glob-watcher": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz",
- "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz",
+ "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==",
"dev": true,
"requires": {
- "anymatch": "^2.0.0",
- "async-done": "^1.2.0",
- "chokidar": "^2.0.0",
- "is-negated-glob": "^1.0.0",
- "just-debounce": "^1.0.0",
- "normalize-path": "^3.0.0",
- "object.defaults": "^1.1.0"
- },
- "dependencies": {
- "binary-extensions": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
- "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
- "dev": true
- },
- "chokidar": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
- "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
- "dev": true,
- "requires": {
- "anymatch": "^2.0.0",
- "async-each": "^1.0.1",
- "braces": "^2.3.2",
- "fsevents": "^1.2.7",
- "glob-parent": "^3.1.0",
- "inherits": "^2.0.3",
- "is-binary-path": "^1.0.0",
- "is-glob": "^4.0.0",
- "normalize-path": "^3.0.0",
- "path-is-absolute": "^1.0.0",
- "readdirp": "^2.2.1",
- "upath": "^1.1.1"
- }
- },
- "fsevents": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
- "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
- "dev": true,
- "optional": true,
- "requires": {
- "bindings": "^1.5.0",
- "nan": "^2.12.1"
- }
- },
- "is-binary-path": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
- "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
- "dev": true,
- "requires": {
- "binary-extensions": "^1.0.0"
- }
- },
- "readdirp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
- "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.11",
- "micromatch": "^3.1.10",
- "readable-stream": "^2.0.2"
- }
- }
+ "async-done": "^2.0.0",
+ "chokidar": "^3.5.3"
}
},
"global-modules": {
@@ -21020,7 +21204,7 @@
"global-prefix": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
- "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
"dev": true,
"requires": {
"expand-tilde": "^2.0.2",
@@ -21047,6 +21231,16 @@
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
"dev": true
},
+ "globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ }
+ },
"globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -21062,14 +21256,19 @@
}
},
"glogg": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
- "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz",
+ "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==",
"dev": true,
"requires": {
- "sparkles": "^1.0.0"
+ "sparkles": "^2.1.0"
}
},
+ "gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
+ },
"got": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
@@ -21095,110 +21294,268 @@
"url-to-options": "^1.0.1"
},
"dependencies": {
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+ "dev": true
+ },
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
"dev": true
}
}
},
"graceful-fs": {
- "version": "4.2.9",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz",
- "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ=="
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
},
- "graceful-readlink": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
- "dev": true
- },
- "growl": {
- "version": "1.10.5",
- "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
- "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"gulp": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
- "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz",
+ "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==",
"dev": true,
"requires": {
- "glob-watcher": "^5.0.3",
- "gulp-cli": "^2.2.0",
- "undertaker": "^1.2.1",
- "vinyl-fs": "^3.0.0"
+ "glob-watcher": "^6.0.0",
+ "gulp-cli": "^3.0.0",
+ "undertaker": "^2.0.0",
+ "vinyl-fs": "^4.0.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "fs-mkdirp-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz",
+ "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.8",
+ "streamx": "^2.12.0"
+ }
+ },
+ "glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.3"
+ }
+ },
+ "glob-stream": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz",
+ "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==",
+ "dev": true,
+ "requires": {
+ "@gulpjs/to-absolute-glob": "^4.0.0",
+ "anymatch": "^3.1.3",
+ "fastq": "^1.13.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "is-negated-glob": "^1.0.0",
+ "normalize-path": "^3.0.0",
+ "streamx": "^2.12.5"
+ }
+ },
+ "lead": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz",
+ "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==",
+ "dev": true
+ },
+ "now-and-later": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz",
+ "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true
+ },
+ "resolve-options": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz",
+ "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==",
+ "dev": true,
+ "requires": {
+ "value-or-function": "^4.0.0"
+ }
+ },
+ "to-through": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz",
+ "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==",
+ "dev": true,
+ "requires": {
+ "streamx": "^2.12.5"
+ }
+ },
+ "value-or-function": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz",
+ "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ }
+ },
+ "vinyl-fs": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz",
+ "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==",
+ "dev": true,
+ "requires": {
+ "fs-mkdirp-stream": "^2.0.1",
+ "glob-stream": "^8.0.0",
+ "graceful-fs": "^4.2.11",
+ "iconv-lite": "^0.6.3",
+ "is-valid-glob": "^1.0.0",
+ "lead": "^4.0.0",
+ "normalize-path": "3.0.0",
+ "resolve-options": "^2.0.0",
+ "stream-composer": "^1.0.2",
+ "streamx": "^2.14.0",
+ "to-through": "^3.0.0",
+ "value-or-function": "^4.0.0",
+ "vinyl": "^3.0.0",
+ "vinyl-sourcemap": "^2.0.0"
+ }
+ },
+ "vinyl-sourcemap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz",
+ "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "^2.0.0",
+ "graceful-fs": "^4.2.10",
+ "now-and-later": "^3.0.0",
+ "streamx": "^2.12.5",
+ "vinyl": "^3.0.0",
+ "vinyl-contents": "^2.0.0"
+ }
+ }
}
- },
- "gulp-cli": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz",
- "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==",
- "dev": true,
- "requires": {
- "ansi-colors": "^1.0.1",
- "archy": "^1.0.0",
- "array-sort": "^1.0.0",
- "color-support": "^1.1.3",
- "concat-stream": "^1.6.0",
- "copy-props": "^2.0.1",
- "fancy-log": "^1.3.2",
- "gulplog": "^1.0.0",
- "interpret": "^1.4.0",
- "isobject": "^3.0.1",
- "liftoff": "^3.1.0",
- "matchdep": "^2.0.0",
- "mute-stdout": "^1.0.0",
- "pretty-hrtime": "^1.0.0",
- "replace-homedir": "^1.0.0",
- "semver-greatest-satisfied-range": "^1.1.0",
- "v8flags": "^3.2.0",
- "yargs": "^7.1.0"
+ },
+ "gulp-cli": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz",
+ "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==",
+ "dev": true,
+ "requires": {
+ "@gulpjs/messages": "^1.1.0",
+ "chalk": "^4.1.2",
+ "copy-props": "^4.0.0",
+ "gulplog": "^2.2.0",
+ "interpret": "^3.1.1",
+ "liftoff": "^5.0.0",
+ "mute-stdout": "^2.0.0",
+ "replace-homedir": "^2.0.0",
+ "semver-greatest-satisfied-range": "^2.0.0",
+ "string-width": "^4.2.3",
+ "v8flags": "^4.0.0",
+ "yargs": "^16.2.0"
},
"dependencies": {
- "camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==",
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "y18n": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz",
- "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==",
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "yargs": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz",
- "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
- "camelcase": "^3.0.0",
- "cliui": "^3.2.0",
- "decamelize": "^1.1.1",
- "get-caller-file": "^1.0.1",
- "os-locale": "^1.4.0",
- "read-pkg-up": "^1.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^1.0.1",
- "set-blocking": "^2.0.0",
- "string-width": "^1.0.2",
- "which-module": "^1.0.0",
- "y18n": "^3.2.1",
- "yargs-parser": "^5.0.1"
+ "has-flag": "^4.0.0"
}
},
- "yargs-parser": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz",
- "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"requires": {
- "camelcase": "^3.0.0",
- "object.assign": "^4.1.0"
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
}
}
}
@@ -21242,12 +21599,12 @@
}
},
"gulplog": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
- "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz",
+ "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==",
"dev": true,
"requires": {
- "glogg": "^1.0.0"
+ "glogg": "^2.2.0"
}
},
"gzip-size": {
@@ -21263,14 +21620,15 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"has-bigints": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
- "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+ "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
"dev": true
},
"has-flag": {
@@ -21279,6 +21637,21 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
+ "has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dev": true,
+ "requires": {
+ "es-define-property": "^1.0.0"
+ }
+ },
+ "has-proto": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "dev": true
+ },
"has-symbol-support-x": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
@@ -21286,10 +21659,9 @@
"dev": true
},
"has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "dev": true
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
},
"has-to-string-tag-x": {
"version": "1.4.1",
@@ -21301,44 +21673,11 @@
}
},
"has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
- "dev": true,
- "requires": {
- "has-symbols": "^1.0.2"
- }
- },
- "has-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
- "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.6",
- "has-values": "^1.0.0",
- "isobject": "^3.0.0"
- }
- },
- "has-values": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
- "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
- "dev": true,
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"requires": {
- "is-number": "^3.0.0",
- "kind-of": "^4.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "has-symbols": "^1.0.3"
}
},
"hash-base": {
@@ -21355,6 +21694,7 @@
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
"requires": {
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.1"
@@ -21378,6 +21718,14 @@
}
}
},
+ "hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "requires": {
+ "function-bind": "^1.1.2"
+ }
+ },
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -21404,12 +21752,6 @@
"parse-passwd": "^1.0.0"
}
},
- "hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true
- },
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -21490,9 +21832,9 @@
"dev": true
},
"ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true
},
"immediate": {
@@ -21502,9 +21844,9 @@
"dev": true
},
"import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
@@ -21573,26 +21915,26 @@
"dev": true
},
"internal-slot": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
- "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+ "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
"dev": true,
"requires": {
- "get-intrinsic": "^1.1.0",
- "has": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.0",
"side-channel": "^1.0.4"
}
},
"interpret": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
- "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz",
+ "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==",
"dev": true
},
"into-stream": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
- "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
+ "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==",
"dev": true,
"requires": {
"from2": "^2.1.1",
@@ -21600,15 +21942,9 @@
}
},
"inversify": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.0.5.tgz",
- "integrity": "sha512-60QsfPz8NAU/GZqXu8hJ+BhNf/C/c+Hp0eDc6XMIJTxBiP36AQyyQKpBkOVTLWBFDQWYVHpbbEuIsHu9dLuJDA=="
- },
- "invert-kv": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
- "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==",
- "dev": true
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/inversify/-/inversify-6.0.2.tgz",
+ "integrity": "sha512-i9m8j/7YIv4mDuYXUAcrpKPSaju/CIly9AHK5jvCBeoiM/2KEsuCQTTP+rzSWWpLYWRukdXFSl6ZTk2/uumbiA=="
},
"is-absolute": {
"version": "1.0.0",
@@ -21620,26 +21956,6 @@
"is-windows": "^1.0.1"
}
},
- "is-accessor-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
- "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
- "dev": true,
- "requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -21650,17 +21966,24 @@
"has-tostringtag": "^1.0.0"
}
},
- "is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
+ "is-array-buffer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1"
+ }
},
"is-bigint": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz",
- "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==",
- "dev": true
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+ "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "dev": true,
+ "requires": {
+ "has-bigints": "^1.0.1"
+ }
},
"is-binary-path": {
"version": "2.1.0",
@@ -21671,6 +21994,16 @@
"binary-extensions": "^2.0.0"
}
},
+ "is-boolean-object": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+ "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
@@ -21678,37 +22011,26 @@
"dev": true
},
"is-callable": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
- "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"dev": true
},
"is-core-module": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz",
- "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"requires": {
- "has": "^1.0.3"
+ "hasown": "^2.0.2"
}
},
- "is-data-descriptor": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
- "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
"dev": true,
"requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "is-typed-array": "^1.1.13"
}
},
"is-date-object": {
@@ -21720,29 +22042,10 @@
"has-tostringtag": "^1.0.0"
}
},
- "is-descriptor": {
- "version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
- "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^0.1.6",
- "is-data-descriptor": "^0.1.4",
- "kind-of": "^5.0.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
- "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
- "dev": true
- }
- }
- },
- "is-extendable": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true
},
"is-extglob": {
@@ -21752,13 +22055,10 @@
"dev": true
},
"is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
- "dev": true,
- "requires": {
- "number-is-nan": "^1.0.0"
- }
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
},
"is-generator-function": {
"version": "1.0.10",
@@ -21791,7 +22091,7 @@
"is-natural-number": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
- "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=",
+ "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==",
"dev": true
},
"is-negated-glob": {
@@ -21801,35 +22101,30 @@
"dev": true
},
"is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true
},
"is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-number-object": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+ "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
"dev": true,
"requires": {
- "kind-of": "^3.0.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
+ "has-tostringtag": "^1.0.0"
}
},
"is-object": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
- "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
"dev": true
},
"is-path-cwd": {
@@ -21847,7 +22142,7 @@
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
"dev": true
},
"is-plain-object": {
@@ -21879,21 +22174,24 @@
}
},
"is-retry-allowed": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
- "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
"dev": true
},
"is-shared-array-buffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
- "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
- "dev": true
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7"
+ }
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
"dev": true
},
"is-string": {
@@ -21915,16 +22213,12 @@
}
},
"is-typed-array": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz",
- "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"dev": true,
"requires": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "es-abstract": "^1.18.5",
- "foreach": "^2.0.5",
- "has-tostringtag": "^1.0.0"
+ "which-typed-array": "^1.1.16"
}
},
"is-typedarray": {
@@ -21975,6 +22269,15 @@
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
"dev": true
},
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -22042,9 +22345,9 @@
},
"dependencies": {
"cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
@@ -22081,6 +22384,12 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true
}
}
},
@@ -22154,6 +22463,16 @@
"is-object": "^1.0.1"
}
},
+ "jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "requires": {
+ "@isaacs/cliui": "^8.0.2",
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
"jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -22189,9 +22508,9 @@
"dev": true
},
"js-yaml": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
- "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
+ "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
@@ -22215,7 +22534,7 @@
"json-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
- "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==",
"dev": true
},
"json-parse-even-better-errors": {
@@ -22247,6 +22566,47 @@
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
+ "jsonwebtoken": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
+ "dev": true,
+ "requires": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^7.5.4"
+ },
+ "dependencies": {
+ "jwa": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
+ "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
+ "dev": true,
+ "requires": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "jws": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz",
+ "integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==",
+ "dev": true,
+ "requires": {
+ "jwa": "^1.4.2",
+ "safe-buffer": "^5.0.1"
+ }
+ }
+ }
+ },
"jsx-ast-utils": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz",
@@ -22263,24 +22623,39 @@
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
"dev": true,
"requires": {
- "lie": "~3.3.0",
- "pako": "~1.0.2",
- "readable-stream": "~2.3.6",
- "setimmediate": "^1.0.5"
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "just-extend": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz",
+ "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
+ "dev": true
+ },
+ "jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "dev": true,
+ "requires": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "jws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
+ "dev": true,
+ "requires": {
+ "jwa": "^2.0.1",
+ "safe-buffer": "^5.0.1"
}
},
- "just-debounce": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
- "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
- "dev": true
- },
- "just-extend": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz",
- "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==",
- "dev": true
- },
"keytar": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
@@ -22323,14 +22698,10 @@
}
},
"last-run": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
- "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
- "dev": true,
- "requires": {
- "default-resolution": "^2.0.0",
- "es6-weak-map": "^2.0.1"
- }
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz",
+ "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==",
+ "dev": true
},
"lazystream": {
"version": "1.0.0",
@@ -22341,15 +22712,6 @@
"readable-stream": "^2.0.5"
}
},
- "lcid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
- "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==",
- "dev": true,
- "requires": {
- "invert-kv": "^1.0.0"
- }
- },
"lead": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
@@ -22385,19 +22747,26 @@
}
},
"liftoff": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
- "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz",
+ "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==",
"dev": true,
"requires": {
- "extend": "^3.0.0",
- "findup-sync": "^3.0.0",
- "fined": "^1.0.1",
- "flagged-respawn": "^1.0.0",
- "is-plain-object": "^2.0.4",
- "object.map": "^1.0.0",
- "rechoir": "^0.6.2",
- "resolve": "^1.1.7"
+ "extend": "^3.0.2",
+ "findup-sync": "^5.0.0",
+ "fined": "^2.0.0",
+ "flagged-respawn": "^2.0.0",
+ "is-plain-object": "^5.0.0",
+ "rechoir": "^0.8.0",
+ "resolve": "^1.20.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
}
},
"linkify-it": {
@@ -22409,31 +22778,10 @@
"uc.micro": "^1.0.1"
}
},
- "load-json-file": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
- "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^2.2.0",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0",
- "strip-bom": "^2.0.0"
- },
- "dependencies": {
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true
- }
- }
- },
"loader-runner": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
- "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==",
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz",
+ "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==",
"dev": true
},
"loader-utils": {
@@ -22457,15 +22805,9 @@
}
},
"lodash": {
- "version": "4.17.21",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
- "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
- },
- "lodash._reinterpolate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
- "dev": true
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="
},
"lodash.flattendeep": {
"version": "4.4.0",
@@ -22476,44 +22818,55 @@
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
- "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"dev": true
},
- "lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
"dev": true
},
- "lodash.some": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
- "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=",
+ "lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"dev": true
},
- "lodash.template": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
- "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
- "dev": true,
- "requires": {
- "lodash._reinterpolate": "^3.0.0",
- "lodash.templatesettings": "^4.0.0"
- }
+ "lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
+ "dev": true
},
- "lodash.templatesettings": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
- "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
- "dev": true,
- "requires": {
- "lodash._reinterpolate": "^3.0.0"
- }
+ "lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
+ "dev": true
},
- "lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=",
+ "lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true
+ },
+ "lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "dev": true
+ },
+ "lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true
+ },
+ "lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"dev": true
},
"log-symbols": {
@@ -22632,30 +22985,12 @@
"integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
"dev": true
},
- "make-iterator": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
- "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.2"
- }
- },
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
"dev": true
},
- "map-visit": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
- "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
- "dev": true,
- "requires": {
- "object-visit": "^1.0.0"
- }
- },
"markdown-it": {
"version": "12.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
@@ -22677,40 +23012,10 @@
}
}
},
- "matchdep": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
- "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
- "dev": true,
- "requires": {
- "findup-sync": "^2.0.0",
- "micromatch": "^3.0.4",
- "resolve": "^1.4.0",
- "stack-trace": "0.0.10"
- },
- "dependencies": {
- "findup-sync": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
- "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
- "dev": true,
- "requires": {
- "detect-file": "^1.0.0",
- "is-glob": "^3.1.0",
- "micromatch": "^3.0.4",
- "resolve-dir": "^1.0.1"
- }
- },
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
- "dev": true,
- "requires": {
- "is-extglob": "^2.1.0"
- }
- }
- }
+ "math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
},
"md5": {
"version": "2.3.0",
@@ -22752,24 +23057,13 @@
"dev": true
},
"micromatch": {
- "version": "3.1.10",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
- "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "braces": "^2.3.1",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "extglob": "^2.0.4",
- "fragment-cache": "^0.2.1",
- "kind-of": "^6.0.2",
- "nanomatch": "^1.2.9",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.2"
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
}
},
"miller-rabin": {
@@ -22816,7 +23110,8 @@
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
},
"minimalistic-crypto-utils": {
"version": "1.0.1",
@@ -22825,17 +23120,17 @@
"dev": true
},
"minimatch": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz",
- "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==",
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz",
+ "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==",
"requires": {
"brace-expansion": "^2.0.1"
},
"dependencies": {
"brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "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==",
"requires": {
"balanced-match": "^1.0.0"
}
@@ -22848,26 +23143,11 @@
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"dev": true
},
- "mixin-deep": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
- "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
- "dev": true,
- "requires": {
- "for-in": "^1.0.2",
- "is-extendable": "^1.0.1"
- },
- "dependencies": {
- "is-extendable": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
- "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
- "dev": true,
- "requires": {
- "is-plain-object": "^2.0.4"
- }
- }
- }
+ "minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "dev": true
},
"mkdirp": {
"version": "0.5.5",
@@ -22886,105 +23166,93 @@
"optional": true
},
"mocha": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
- "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
- "dev": true,
- "requires": {
- "@ungap/promise-all-settled": "1.1.2",
- "ansi-colors": "4.1.1",
- "browser-stdout": "1.3.1",
- "chokidar": "3.5.3",
- "debug": "4.3.3",
- "diff": "5.0.0",
- "escape-string-regexp": "4.0.0",
- "find-up": "5.0.0",
- "glob": "7.2.0",
- "growl": "1.10.5",
- "he": "1.2.0",
- "js-yaml": "4.1.0",
- "log-symbols": "4.1.0",
- "minimatch": "4.2.1",
- "ms": "2.1.3",
- "nanoid": "3.3.1",
- "serialize-javascript": "6.0.0",
- "strip-json-comments": "3.1.1",
- "supports-color": "8.1.1",
- "which": "2.0.2",
- "workerpool": "6.2.0",
- "yargs": "16.2.0",
- "yargs-parser": "20.2.4",
- "yargs-unparser": "2.0.0"
+ "version": "11.7.5",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz",
+ "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==",
+ "dev": true,
+ "requires": {
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^4.0.1",
+ "debug": "^4.3.5",
+ "diff": "^7.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^10.4.5",
+ "he": "^1.2.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^9.0.5",
+ "ms": "^2.1.3",
+ "picocolors": "^1.1.1",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^9.2.0",
+ "yargs": "^17.7.2",
+ "yargs-parser": "^21.1.1",
+ "yargs-unparser": "^2.0.0"
},
"dependencies": {
- "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==",
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "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==",
"dev": true,
"requires": {
- "color-convert": "^2.0.1"
+ "balanced-match": "^1.0.0"
}
},
- "argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
+ "chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "requires": {
+ "readdirp": "^4.0.1"
+ }
},
"cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dev": true,
"requires": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
+ "strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
}
},
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"requires": {
- "color-name": "~1.1.4"
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
}
},
- "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
- },
"debug": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
- "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"dev": true,
"requires": {
- "ms": "2.1.2"
- },
- "dependencies": {
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- }
+ "ms": "^2.1.3"
}
},
"diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz",
+ "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==",
"dev": true
},
"escape-string-regexp": {
@@ -23003,11 +23271,29 @@
"path-exists": "^4.0.0"
}
},
- "get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true
+ "foreground-child": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ }
+ },
+ "glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "dev": true,
+ "requires": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ }
},
"has-flag": {
"version": "4.0.0",
@@ -23015,16 +23301,10 @@
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
"js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true,
"requires": {
"argparse": "^2.0.1"
@@ -23040,12 +23320,12 @@
}
},
"minimatch": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
- "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"requires": {
- "brace-expansion": "^1.1.7"
+ "brace-expansion": "^2.0.2"
}
},
"ms": {
@@ -23054,12 +23334,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "nanoid": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
- "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
- "dev": true
- },
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -23078,23 +23352,39 @@
"p-limit": "^3.0.2"
}
},
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
+ "shebang-regex": "^3.0.0"
}
},
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true
+ },
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -23104,17 +23394,6 @@
"has-flag": "^4.0.0"
}
},
- "wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -23122,19 +23401,25 @@
"dev": true
},
"yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"dev": true,
"requires": {
- "cliui": "^7.0.2",
+ "cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "string-width": "^4.2.0",
+ "string-width": "^4.2.3",
"y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
+ "yargs-parser": "^21.1.1"
}
+ },
+ "yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true
}
}
},
@@ -23189,9 +23474,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"mute-stdout": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
- "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz",
+ "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==",
"dev": true
},
"mute-stream": {
@@ -23205,38 +23490,12 @@
"resolved": "https://registry.npmjs.org/named-js-regexp/-/named-js-regexp-1.3.5.tgz",
"integrity": "sha512-XO0DPujDP9IWpkt690iWLreKztb/VB811DGl5N3z7BfhkMJuiVZXOi6YN/fEB9qkvtMVTgSZDW8pzdVt8vj/FA=="
},
- "nan": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
- "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
- "dev": true,
- "optional": true
- },
"nanoid": {
- "version": "2.1.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz",
- "integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
"dev": true
},
- "nanomatch": {
- "version": "1.2.13",
- "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
- "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
- "dev": true,
- "requires": {
- "arr-diff": "^4.0.0",
- "array-unique": "^0.3.2",
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "fragment-cache": "^0.2.1",
- "is-windows": "^1.0.2",
- "kind-of": "^6.0.2",
- "object.pick": "^1.3.0",
- "regex-not": "^1.0.0",
- "snapdragon": "^0.8.1",
- "to-regex": "^3.0.1"
- }
- },
"napi-build-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
@@ -23263,16 +23522,16 @@
"dev": true
},
"nise": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz",
- "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz",
+ "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==",
"dev": true,
"requires": {
- "@sinonjs/commons": "^1.8.3",
- "@sinonjs/fake-timers": ">=5",
- "@sinonjs/text-encoding": "^0.7.1",
- "just-extend": "^4.0.2",
- "path-to-regexp": "^1.7.0"
+ "@sinonjs/commons": "^3.0.0",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/text-encoding": "^0.7.2",
+ "just-extend": "^6.2.0",
+ "path-to-regexp": "^6.2.1"
}
},
"node-abi": {
@@ -23492,9 +23751,9 @@
}
},
"node-releases": {
- "version": "2.0.12",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz",
- "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==",
+ "version": "2.0.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz",
+ "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
"dev": true
},
"node-stream-zip": {
@@ -23502,26 +23761,6 @@
"resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.15.0.tgz",
"integrity": "sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw=="
},
- "normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "dev": true,
- "requires": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- },
- "dependencies": {
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
- }
- }
- },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -23537,17 +23776,6 @@
"prepend-http": "^2.0.0",
"query-string": "^5.0.1",
"sort-keys": "^2.0.0"
- },
- "dependencies": {
- "sort-keys": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
- "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
- "dev": true,
- "requires": {
- "is-plain-obj": "^1.0.0"
- }
- }
}
},
"now-and-later": {
@@ -23585,12 +23813,6 @@
"boolbase": "^1.0.0"
}
},
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
- "dev": true
- },
"nyc": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
@@ -23643,46 +23865,10 @@
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
"dev": true
},
- "object-copy": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
- "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
- "dev": true,
- "requires": {
- "copy-descriptor": "^0.1.0",
- "define-property": "^0.2.5",
- "kind-of": "^3.0.3"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
- "object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="
- },
"object-inspect": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz",
- "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==",
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true
},
"object-is": {
@@ -23701,48 +23887,28 @@
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
- "object-visit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
- "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
- "dev": true,
- "requires": {
- "isobject": "^3.0.0"
- }
- },
"object.assign": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
- "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
"requires": {
- "call-bind": "^1.0.0",
- "define-properties": "^1.1.3",
- "has-symbols": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
}
},
"object.defaults": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
- "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
"dev": true,
"requires": {
"array-each": "^1.0.1",
"array-slice": "^1.0.0",
"for-own": "^1.0.0",
"isobject": "^3.0.0"
- },
- "dependencies": {
- "for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "requires": {
- "for-in": "^1.0.1"
- }
- }
}
},
"object.entries": {
@@ -23757,14 +23923,26 @@
}
},
"object.fromentries": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz",
- "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
+ }
+ },
+ "object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
}
},
"object.hasown": {
@@ -23777,66 +23955,24 @@
"es-abstract": "^1.19.1"
}
},
- "object.map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
- "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
- "dev": true,
- "requires": {
- "for-own": "^1.0.0",
- "make-iterator": "^1.0.0"
- },
- "dependencies": {
- "for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "requires": {
- "for-in": "^1.0.1"
- }
- }
- }
- },
"object.pick": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
"dev": true,
"requires": {
"isobject": "^3.0.1"
}
},
- "object.reduce": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
- "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
- "dev": true,
- "requires": {
- "for-own": "^1.0.0",
- "make-iterator": "^1.0.0"
- },
- "dependencies": {
- "for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
- "dev": true,
- "requires": {
- "for-in": "^1.0.1"
- }
- }
- }
- },
"object.values": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz",
- "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
}
},
"once": {
@@ -23856,6 +23992,17 @@
"mimic-fn": "^2.1.0"
}
},
+ "open": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
+ "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+ "dev": true,
+ "requires": {
+ "define-lazy-prop": "^2.0.0",
+ "is-docker": "^2.1.1",
+ "is-wsl": "^2.2.0"
+ }
+ },
"opener": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
@@ -23891,20 +24038,6 @@
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
"dev": true
},
- "os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==",
- "dev": true,
- "requires": {
- "lcid": "^1.0.0"
- }
- },
- "os-tmpdir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
- },
"p-cancelable": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
@@ -23923,13 +24056,13 @@
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
- "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
"dev": true
},
"p-is-promise": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
- "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
+ "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==",
"dev": true
},
"p-limit": {
@@ -23986,6 +24119,12 @@
"release-zalgo": "^1.0.0"
}
},
+ "package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true
+ },
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -23999,33 +24138,33 @@
"dev": true,
"requires": {
"callsites": "^3.0.0"
- },
- "dependencies": {
- "callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true
- }
}
},
"parse-asn1": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
- "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+ "version": "5.1.9",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz",
+ "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==",
"dev": true,
"requires": {
- "asn1.js": "^5.2.0",
- "browserify-aes": "^1.0.0",
- "evp_bytestokey": "^1.0.0",
- "pbkdf2": "^3.0.3",
- "safe-buffer": "^5.1.1"
+ "asn1.js": "^4.10.1",
+ "browserify-aes": "^1.2.0",
+ "evp_bytestokey": "^1.0.3",
+ "pbkdf2": "^3.1.5",
+ "safe-buffer": "^5.2.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
}
},
"parse-filepath": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
- "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
"dev": true,
"requires": {
"is-absolute": "^1.0.0",
@@ -24033,25 +24172,10 @@
"path-root": "^0.1.1"
}
},
- "parse-json": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
- "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
- "dev": true,
- "requires": {
- "error-ex": "^1.2.0"
- }
- },
- "parse-node-version": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
- "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
- "dev": true
- },
"parse-passwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
- "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==",
"dev": true
},
"parse-semver": {
@@ -24088,12 +24212,6 @@
}
}
},
- "pascalcase": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
- "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
- "dev": true
- },
"path-browserify": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
@@ -24107,9 +24225,9 @@
"dev": true
},
"path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-is-absolute": {
@@ -24131,7 +24249,7 @@
"path-root": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
- "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
"dev": true,
"requires": {
"path-root-regex": "^0.1.0"
@@ -24140,26 +24258,33 @@
"path-root-regex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
- "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
"dev": true
},
- "path-to-regexp": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
- "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"requires": {
- "isarray": "0.0.1"
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true
}
}
},
+ "path-to-regexp": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz",
+ "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==",
+ "dev": true
+ },
"path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -24173,16 +24298,25 @@
"dev": true
},
"pbkdf2": {
- "version": "3.0.17",
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
- "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz",
+ "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==",
"dev": true,
"requires": {
- "create-hash": "^1.1.2",
- "create-hmac": "^1.1.4",
- "ripemd160": "^2.0.1",
- "safe-buffer": "^5.0.1",
- "sha.js": "^2.4.8"
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "ripemd160": "^2.0.3",
+ "safe-buffer": "^5.2.1",
+ "sha.js": "^2.4.12",
+ "to-buffer": "^1.2.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
}
},
"pend": {
@@ -24192,15 +24326,15 @@
"dev": true
},
"picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true
},
"picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
"dev": true
},
"pify": {
@@ -24212,13 +24346,13 @@
"pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
"dev": true
},
"pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
"dev": true,
"requires": {
"pinkie": "^2.0.0"
@@ -24245,10 +24379,10 @@
"extend-shallow": "^3.0.2"
}
},
- "posix-character-classes": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
- "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true
},
"postinstall-build": {
@@ -24300,7 +24434,7 @@
"prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
- "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
"dev": true
},
"prettier": {
@@ -24309,12 +24443,6 @@
"integrity": "sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg==",
"dev": true
},
- "pretty-hrtime": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
- "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
- "dev": true
- },
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -24347,11 +24475,6 @@
"react-is": "^16.13.1"
}
},
- "proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
- },
"public-encrypt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
@@ -24388,11 +24511,20 @@
}
},
"punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true
},
+ "qs": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.1.0"
+ }
+ },
"query-string": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
@@ -24422,6 +24554,12 @@
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true
},
+ "queue-tick": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
+ "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==",
+ "dev": true
+ },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -24463,86 +24601,25 @@
}
}
},
- "react-is": {
- "version": "16.13.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true
- },
- "read": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
- "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
- "dev": true,
- "requires": {
- "mute-stream": "~0.0.4"
- }
- },
- "read-pkg": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
- "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==",
- "dev": true,
- "requires": {
- "load-json-file": "^1.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^1.0.0"
- },
- "dependencies": {
- "path-type": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
- "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "pify": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true
- }
- }
- },
- "read-pkg-up": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
- "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==",
- "dev": true,
- "requires": {
- "find-up": "^1.0.0",
- "read-pkg": "^1.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
- "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
- "dev": true,
- "requires": {
- "path-exists": "^2.0.0",
- "pinkie-promise": "^2.0.0"
- }
- },
- "path-exists": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
- "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
- "dev": true,
- "requires": {
- "pinkie-promise": "^2.0.0"
- }
- }
- }
- },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true
+ },
+ "read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+ "dev": true,
+ "requires": {
+ "mute-stream": "~0.0.4"
+ }
+ },
"readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -24575,51 +24652,31 @@
}
},
"rechoir": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
- "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
"dev": true,
"requires": {
- "resolve": "^1.1.6"
+ "resolve": "^1.20.0"
}
},
"reflect-metadata": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
- "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
- },
- "regenerator-runtime": {
- "version": "0.13.9",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
- "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
- "dev": true
- },
- "regex-not": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
- "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.2",
- "safe-regex": "^1.1.0"
- }
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
+ "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="
},
"regexp.prototype.flags": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz",
- "integrity": "sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
+ "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.6",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.1"
}
},
- "regexpp": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
- "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
- "dev": true
- },
"release-zalgo": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
@@ -24656,18 +24713,6 @@
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
"dev": true
},
- "repeat-element": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
- "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
- "dev": true
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
- "dev": true
- },
"replace-ext": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
@@ -24675,15 +24720,10 @@
"dev": true
},
"replace-homedir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
- "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
- "dev": true,
- "requires": {
- "homedir-polyfill": "^1.0.1",
- "is-absolute": "^1.0.0",
- "remove-trailing-separator": "^1.1.0"
- }
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz",
+ "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==",
+ "dev": true
},
"require-directory": {
"version": "2.1.1",
@@ -24717,12 +24757,6 @@
}
}
},
- "require-main-filename": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
- "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==",
- "dev": true
- },
"resolve": {
"version": "1.22.4",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
@@ -24745,7 +24779,7 @@
"resolve-dir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
- "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
"dev": true,
"requires": {
"expand-tilde": "^2.0.0",
@@ -24767,27 +24801,15 @@
"value-or-function": "^3.0.0"
}
},
- "resolve-url": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
- "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
- "dev": true
- },
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
- "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==",
"dev": true,
"requires": {
"lowercase-keys": "^1.0.0"
}
},
- "ret": {
- "version": "0.1.15",
- "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
- },
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -24795,15 +24817,13 @@
"dev": true
},
"rewiremock": {
- "version": "3.14.3",
- "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.3.tgz",
- "integrity": "sha512-6BaUGfp7NtxBjisxcGN73nNiA2fS2AwhEk/9DMUqxfv5v0aDM1wpOYpj5GSArqsJi07YCfLhkD8C74LAN7+FkQ==",
+ "version": "3.14.6",
+ "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.6.tgz",
+ "integrity": "sha512-hjpS7iQUTVVh/IHV4GE1ypg4IzlgVc34gxZBarwwVrKfnjlyqHJuQdsia6Ac7m4f4k/zxxA3tX285MOstdysRQ==",
"dev": true,
"requires": {
"babel-runtime": "^6.26.0",
"compare-module-exports": "^2.1.0",
- "lodash.some": "^4.6.0",
- "lodash.template": "^4.4.0",
"node-libs-browser": "^2.1.0",
"path-parse": "^1.0.5",
"wipe-node-cache": "^2.1.2",
@@ -24820,13 +24840,33 @@
}
},
"ripemd160": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
- "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz",
+ "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==",
"dev": true,
"requires": {
- "hash-base": "^3.0.0",
- "inherits": "^2.0.1"
+ "hash-base": "^3.1.2",
+ "inherits": "^2.0.4"
+ },
+ "dependencies": {
+ "hash-base": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz",
+ "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^2.3.8",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
}
},
"run-parallel": {
@@ -24851,18 +24891,41 @@
"resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.7.tgz",
"integrity": "sha512-szN4fK+TqBPOFBcBcsR0g2cmTTUF/vaFEOZNuSdfU8/pGFnNmmn2u8SystYXG1QMrjOPBc6XTKHMVfENDf6hHw=="
},
+ "safe-array-concat": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ }
+ }
+ },
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
},
- "safe-regex": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
- "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "safe-regex-test": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+ "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
"dev": true,
"requires": {
- "ret": "~0.1.10"
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.1.4"
}
},
"safer-buffer": {
@@ -24876,9 +24939,9 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"schema-utils": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz",
- "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.8",
@@ -24887,46 +24950,35 @@
}
},
"seek-bzip": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
- "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+ "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
"dev": true,
"requires": {
- "commander": "~2.8.1"
- },
- "dependencies": {
- "commander": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
- "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
- "dev": true,
- "requires": {
- "graceful-readlink": ">= 1.0.0"
- }
- }
+ "commander": "^2.8.1"
}
},
"semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"semver-greatest-satisfied-range": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
- "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz",
+ "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==",
"dev": true,
"requires": {
- "sver-compat": "^1.5.0"
+ "sver": "^1.8.3"
}
},
"serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
"dev": true,
"requires": {
"randombytes": "^2.1.0"
@@ -24938,27 +24990,30 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"dev": true
},
- "set-value": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
- "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"requires": {
- "extend-shallow": "^2.0.1",
- "is-extendable": "^0.1.1",
- "is-plain-object": "^2.0.3",
- "split-string": "^3.0.1"
- },
- "dependencies": {
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- }
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ }
+ },
+ "set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "requires": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
}
},
"setimmediate": {
@@ -24968,12 +25023,22 @@
"dev": true
},
"sha.js": {
- "version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
- "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "version": "2.4.12",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
+ "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
+ "dev": true,
"requires": {
- "inherits": "^2.0.1",
- "safe-buffer": "^5.0.1"
+ "inherits": "^2.0.4",
+ "safe-buffer": "^5.2.1",
+ "to-buffer": "^1.2.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
+ }
}
},
"shallow-clone": {
@@ -25006,23 +25071,60 @@
"integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="
},
"shortid": {
- "version": "2.2.16",
- "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.16.tgz",
- "integrity": "sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==",
+ "version": "2.2.17",
+ "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.17.tgz",
+ "integrity": "sha512-GpbM3gLF1UUXZvQw6MCyulHkWbRseNO4cyBEZresZRorwl1+SLu1ZdqgVtuwqz8mB6RpwPkm541mYSqrKyJSaA==",
"dev": true,
"requires": {
- "nanoid": "^2.1.0"
+ "nanoid": "^3.3.8"
}
},
"side-channel": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
- "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"requires": {
- "call-bind": "^1.0.0",
- "get-intrinsic": "^1.0.2",
- "object-inspect": "^1.9.0"
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ }
+ },
+ "side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "requires": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ }
+ },
+ "side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "requires": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ }
+ },
+ "side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "requires": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
}
},
"signal-exit": {
@@ -25070,23 +25172,23 @@
}
},
"sinon": {
- "version": "13.0.1",
- "resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
- "integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz",
+ "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==",
"dev": true,
"requires": {
- "@sinonjs/commons": "^1.8.3",
- "@sinonjs/fake-timers": "^9.0.0",
- "@sinonjs/samsam": "^6.1.1",
- "diff": "^5.0.0",
- "nise": "^5.1.1",
- "supports-color": "^7.2.0"
+ "@sinonjs/commons": "^3.0.1",
+ "@sinonjs/fake-timers": "^11.2.2",
+ "@sinonjs/samsam": "^8.0.0",
+ "diff": "^5.2.0",
+ "nise": "^6.0.0",
+ "supports-color": "^7"
},
"dependencies": {
"diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz",
+ "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==",
"dev": true
},
"has-flag": {
@@ -25123,166 +25225,10 @@
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
- "slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- }
- }
- },
- "snapdragon": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
- "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
- "dev": true,
- "requires": {
- "base": "^0.11.1",
- "debug": "^2.2.0",
- "define-property": "^0.2.5",
- "extend-shallow": "^2.0.1",
- "map-cache": "^0.2.2",
- "source-map": "^0.5.6",
- "source-map-resolve": "^0.5.0",
- "use": "^3.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- },
- "extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
- "dev": true,
- "requires": {
- "is-extendable": "^0.1.0"
- }
- },
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "dev": true
- }
- }
- },
- "snapdragon-node": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
- "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
- "dev": true,
- "requires": {
- "define-property": "^1.0.0",
- "isobject": "^3.0.0",
- "snapdragon-util": "^3.0.1"
- },
- "dependencies": {
- "define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
- "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^1.0.0"
- }
- },
- "is-accessor-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
- "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-data-descriptor": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
- "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
- "dev": true,
- "requires": {
- "kind-of": "^6.0.0"
- }
- },
- "is-descriptor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
- "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
- "dev": true,
- "requires": {
- "is-accessor-descriptor": "^1.0.0",
- "is-data-descriptor": "^1.0.0",
- "kind-of": "^6.0.2"
- }
- }
- }
- },
- "snapdragon-util": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
- "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
- "dev": true,
- "requires": {
- "kind-of": "^3.2.0"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
- }
- }
- },
"sort-keys": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
- "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+ "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==",
"dev": true,
"requires": {
"is-plain-obj": "^1.0.0"
@@ -25291,30 +25237,28 @@
"sort-keys-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
- "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
+ "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==",
"dev": true,
"requires": {
"sort-keys": "^1.0.0"
+ },
+ "dependencies": {
+ "sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==",
+ "dev": true,
+ "requires": {
+ "is-plain-obj": "^1.0.0"
+ }
+ }
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "source-map-resolve": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
- "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
- "dev": true,
- "requires": {
- "atob": "^2.1.1",
- "decode-uri-component": "^0.2.0",
- "resolve-url": "^0.2.1",
- "source-map-url": "^0.4.0",
- "urix": "^0.1.0"
- }
+ "dev": true
},
"source-map-support": {
"version": "0.5.21",
@@ -25326,16 +25270,10 @@
"source-map": "^0.6.0"
}
},
- "source-map-url": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
- "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
- "dev": true
- },
"sparkles": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
- "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz",
+ "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==",
"dev": true
},
"spawn-wrap": {
@@ -25352,47 +25290,6 @@
"which": "^2.0.1"
}
},
- "spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
- "dev": true
- },
- "spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.13",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
- "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
- "dev": true
- },
- "split-string": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
- "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
- "dev": true,
- "requires": {
- "extend-shallow": "^3.0.0"
- }
- },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -25409,26 +25306,11 @@
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
},
- "static-extend": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
- "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
- "dev": true,
- "requires": {
- "define-property": "^0.2.5",
- "object-copy": "^0.1.0"
- },
- "dependencies": {
- "define-property": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
- "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
- "dev": true,
- "requires": {
- "is-descriptor": "^0.1.0"
- }
- }
- }
+ "stoppable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
+ "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
+ "dev": true
},
"stream-browserify": {
"version": "2.0.2",
@@ -25440,6 +25322,15 @@
"readable-stream": "^2.0.2"
}
},
+ "stream-composer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
+ "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==",
+ "dev": true,
+ "requires": {
+ "streamx": "^2.13.2"
+ }
+ },
"stream-exhaust": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
@@ -25465,10 +25356,22 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true
},
+ "streamx": {
+ "version": "2.18.0",
+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz",
+ "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==",
+ "dev": true,
+ "requires": {
+ "bare-events": "^2.2.0",
+ "fast-fifo": "^1.3.2",
+ "queue-tick": "^1.0.1",
+ "text-decoder": "^1.1.0"
+ }
+ },
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
- "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+ "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==",
"dev": true
},
"string_decoder": {
@@ -25489,31 +25392,25 @@
}
},
"string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
- "dev": true
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
- "dev": true,
- "requires": {
- "ansi-regex": "^2.0.0"
- }
- }
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "string-width-cjs": {
+ "version": "npm:string-width@4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
}
},
"string.prototype.matchall": {
@@ -25532,24 +25429,38 @@
"side-channel": "^1.0.4"
}
},
+ "string.prototype.trim": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
+ }
+ },
"string.prototype.trimend": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
- "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
}
},
"string.prototype.trimstart": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
- "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
"requires": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
}
},
"strip-ansi": {
@@ -25561,13 +25472,13 @@
"ansi-regex": "^5.0.1"
}
},
- "strip-bom": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
- "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
+ "strip-ansi-cjs": {
+ "version": "npm:strip-ansi@6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"requires": {
- "is-utf8": "^0.2.0"
+ "ansi-regex": "^5.0.1"
}
},
"strip-dirs": {
@@ -25619,76 +25530,34 @@
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
},
- "sver-compat": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
- "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
- "dev": true,
- "requires": {
- "es6-iterator": "^2.0.1",
- "es6-symbol": "^3.1.1"
- }
- },
- "table": {
- "version": "6.7.5",
- "resolved": "https://registry.npmjs.org/table/-/table-6.7.5.tgz",
- "integrity": "sha512-LFNeryOqiQHqCVKzhkymKwt6ozeRhlm8IL1mE8rNUurkir4heF6PzMyRgaTa4tlyPTGGgXuvVOF/OLWiH09Lqw==",
+ "sver": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz",
+ "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==",
"dev": true,
"requires": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
+ "semver": "^6.3.0"
},
"dependencies": {
- "ajv": {
- "version": "8.10.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.10.0.tgz",
- "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==",
- "dev": true,
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- }
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
- "json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
- "string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- }
+ "optional": true
}
}
},
"tapable": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
- "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",
+ "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
"dev": true
},
"tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
+ "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
"dev": true,
"optional": true,
"requires": {
@@ -25765,36 +25634,82 @@
}
},
"tas-client": {
- "version": "0.1.73",
- "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.1.73.tgz",
- "integrity": "sha512-UDdUF9kV2hYdlv+7AgqP2kXarVSUhjK7tg1BUflIRGEgND0/QoNpN64rcEuhEcM8AIbW65yrCopJWqRhLZ3m8w==",
+ "version": "0.2.33",
+ "resolved": "https://registry.npmjs.org/tas-client/-/tas-client-0.2.33.tgz",
+ "integrity": "sha512-V+uqV66BOQnWxvI6HjDnE4VkInmYZUQ4dgB7gzaDyFyFSK1i1nF/j7DpS9UbQAgV9NaF1XpcyuavnM1qOeiEIg=="
+ },
+ "teex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
+ "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
+ "dev": true,
"requires": {
- "axios": "^1.6.1"
+ "streamx": "^2.12.5"
}
},
"terser": {
- "version": "5.14.2",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
- "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
+ "version": "5.46.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz",
+ "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==",
"dev": true,
"requires": {
- "@jridgewell/source-map": "^0.3.2",
- "acorn": "^8.5.0",
+ "@jridgewell/source-map": "^0.3.3",
+ "acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
}
},
"terser-webpack-plugin": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.1.tgz",
- "integrity": "sha512-GvlZdT6wPQKbDNW/GDQzZFg/j4vKU96yl2q6mcUkzKOgW4gwf1Z8cZToUCrz31XHlPWH8MVb1r2tFtdDtTGJ7g==",
+ "version": "5.3.17",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.17.tgz",
+ "integrity": "sha512-YR7PtUp6GMU91BgSJmlaX/rS2lGDbAF7D+Wtq7hRO+MiljNmodYvqslzCFiYVAgW+Qoaaia/QUIP4lGXufjdZw==",
"dev": true,
"requires": {
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.0",
- "source-map": "^0.6.1",
- "terser": "^5.7.2"
+ "schema-utils": "^4.3.0",
+ "terser": "^5.31.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.3"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ }
+ }
}
},
"test-exclude": {
@@ -25809,9 +25724,9 @@
},
"dependencies": {
"minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
@@ -25819,6 +25734,15 @@
}
}
},
+ "text-decoder": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz",
+ "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==",
+ "dev": true,
+ "requires": {
+ "b4a": "^1.6.4"
+ }
+ },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -25828,7 +25752,7 @@
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true
},
"through2": {
@@ -25851,16 +25775,10 @@
"xtend": "~4.0.0"
}
},
- "time-stamp": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
- "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
- "dev": true
- },
"timed-out": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
- "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+ "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==",
"dev": true
},
"timers-browserify": {
@@ -25873,12 +25791,9 @@
}
},
"tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
- "requires": {
- "os-tmpdir": "~1.0.2"
- }
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz",
+ "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="
},
"to-absolute-glob": {
"version": "2.0.2",
@@ -25897,57 +25812,37 @@
"dev": true
},
"to-buffer": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
- "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
- "dev": true
- },
- "to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true
- },
- "to-object-path": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
- "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
+ "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
"dev": true,
"requires": {
- "kind-of": "^3.0.2"
+ "isarray": "^2.0.5",
+ "safe-buffer": "^5.2.1",
+ "typed-array-buffer": "^1.0.3"
},
"dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "^1.1.5"
- }
+ "isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true
}
}
},
- "to-regex": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
- "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
- "dev": true,
- "requires": {
- "define-property": "^2.0.2",
- "extend-shallow": "^3.0.2",
- "regex-not": "^1.0.2",
- "safe-regex": "^1.1.0"
- }
- },
"to-regex-range": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
- "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
- "is-number": "^3.0.0",
- "repeat-string": "^1.6.1"
+ "is-number": "^7.0.0"
}
},
"to-through": {
@@ -25968,12 +25863,19 @@
"trim-repeated": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
- "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+ "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.2"
}
},
+ "ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "dev": true,
+ "requires": {}
+ },
"ts-loader": {
"version": "9.2.8",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz",
@@ -25995,15 +25897,6 @@
"color-convert": "^2.0.1"
}
},
- "braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "requires": {
- "fill-range": "^7.0.1"
- }
- },
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -26029,37 +25922,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "requires": {
- "to-regex-range": "^5.0.1"
- }
- },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
- "is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true
- },
- "micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "dev": true,
- "requires": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
- }
- },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -26068,15 +25936,6 @@
"requires": {
"has-flag": "^4.0.0"
}
- },
- "to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "requires": {
- "is-number": "^7.0.0"
- }
}
}
},
@@ -26111,13 +25970,13 @@
}
},
"tsconfig-paths": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
- "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
"dev": true,
"requires": {
"@types/json5": "^0.0.29",
- "json5": "^1.0.1",
+ "json5": "^1.0.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
},
@@ -26206,15 +26065,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
- "tsutils": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
- "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
- "dev": true,
- "requires": {
- "tslib": "^1.8.1"
- }
- },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -26237,12 +26087,6 @@
"safe-buffer": "^5.0.1"
}
},
- "type": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz",
- "integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw==",
- "dev": true
- },
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -26264,34 +26108,69 @@
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
+ "typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "requires": {
+ "call-bound": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.14"
+ }
+ },
+ "typed-array-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ }
+ },
+ "typed-array-byte-offset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+ "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+ "dev": true,
+ "requires": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ }
+ },
+ "typed-array-length": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0"
+ }
+ },
"typed-rest-client": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.5.tgz",
- "integrity": "sha512-952/Aegu3lTqUAI1anbDLbewojnF/gh8at9iy1CIrfS1h/+MtNjB1Y9z6ZF5n2kZd+97em56lZ9uu7Zz3y/pwg==",
+ "version": "1.8.11",
+ "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
+ "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==",
"dev": true,
"requires": {
"qs": "^6.9.1",
"tunnel": "0.0.6",
- "underscore": "^1.12.1"
- },
- "dependencies": {
- "qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
- "dev": true,
- "requires": {
- "side-channel": "^1.0.4"
- }
- }
+ "underscore": "^1.12.1"
}
},
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
- "dev": true
- },
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
@@ -26313,9 +26192,9 @@
}
},
"typescript": {
- "version": "4.5.5",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
- "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true
},
"uc.micro": {
@@ -26330,21 +26209,21 @@
"integrity": "sha512-mliiCSrsE29aNBI7O9W5gGv6WmA9kBR8PtTt6Apaxns076IRdYrrtFhXHEWMj5CSum3U7cv7/pi4xmi4XsIOqg=="
},
"unbox-primitive": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
- "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+ "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
"dev": true,
"requires": {
- "function-bind": "^1.1.1",
- "has-bigints": "^1.0.1",
- "has-symbols": "^1.0.2",
+ "call-bind": "^1.0.2",
+ "has-bigints": "^1.0.2",
+ "has-symbols": "^1.0.3",
"which-boxed-primitive": "^1.0.2"
}
},
"unbzip2-stream": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz",
- "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
"dev": true,
"requires": {
"buffer": "^5.2.1",
@@ -26358,32 +26237,44 @@
"dev": true
},
"underscore": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
- "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
+ "version": "1.13.6",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
"dev": true
},
"undertaker": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz",
- "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz",
+ "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==",
"dev": true,
"requires": {
- "arr-flatten": "^1.0.1",
- "arr-map": "^2.0.0",
- "bach": "^1.0.0",
- "collection-map": "^1.0.0",
- "es6-weak-map": "^2.0.1",
- "last-run": "^1.1.0",
- "object.defaults": "^1.0.0",
- "object.reduce": "^1.0.0",
- "undertaker-registry": "^1.0.0"
+ "bach": "^2.0.1",
+ "fast-levenshtein": "^3.0.0",
+ "last-run": "^2.0.0",
+ "undertaker-registry": "^2.0.0"
+ },
+ "dependencies": {
+ "fast-levenshtein": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
+ "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
+ "dev": true,
+ "requires": {
+ "fastest-levenshtein": "^1.0.7"
+ }
+ }
}
},
"undertaker-registry": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
- "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz",
+ "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==",
+ "dev": true
+ },
+ "undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true
},
"unicode": {
@@ -26391,18 +26282,6 @@
"resolved": "https://registry.npmjs.org/unicode/-/unicode-14.0.0.tgz",
"integrity": "sha512-BjinxTXkbm9Jomp/YBTMGusr4fxIG67fNGShHIRAL16Ur2GJTq2xvLi+sxuiJmInCmwqqev2BCFKyvbfp/yAkg=="
},
- "union-value": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
- "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
- "dev": true,
- "requires": {
- "arr-union": "^3.1.0",
- "get-value": "^2.0.6",
- "is-extendable": "^0.1.1",
- "set-value": "^2.0.1"
- }
- },
"unique-stream": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
@@ -26413,65 +26292,14 @@
"through2-filter": "^3.0.0"
}
},
- "unset-value": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
- "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
- "dev": true,
- "requires": {
- "has-value": "^0.3.1",
- "isobject": "^3.0.0"
- },
- "dependencies": {
- "has-value": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
- "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
- "dev": true,
- "requires": {
- "get-value": "^2.0.3",
- "has-values": "^0.1.4",
- "isobject": "^2.0.0"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- }
- }
- },
- "has-values": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
- "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
- "dev": true
- }
- }
- },
- "untildify": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
- "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw=="
- },
- "upath": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
- "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
- "dev": true
- },
"update-browserslist-db": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
- "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+ "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
"dev": true,
"requires": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
}
},
"uri-js": {
@@ -26483,12 +26311,6 @@
"punycode": "^2.1.0"
}
},
- "urix": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
- "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
- "dev": true
- },
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -26516,7 +26338,7 @@
"url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
- "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==",
"dev": true,
"requires": {
"prepend-http": "^2.0.0"
@@ -26525,13 +26347,7 @@
"url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
- "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
- "dev": true
- },
- "use": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
- "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==",
"dev": true
},
"util": {
@@ -26558,14 +26374,9 @@
"dev": true
},
"uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
- },
- "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==",
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
+ "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"dev": true
},
"v8-compile-cache-lib": {
@@ -26575,23 +26386,10 @@
"dev": true
},
"v8flags": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
- "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
- "dev": true,
- "requires": {
- "homedir-polyfill": "^1.0.1"
- }
- },
- "validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz",
+ "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==",
+ "dev": true
},
"value-or-function": {
"version": "3.0.0",
@@ -26613,6 +26411,69 @@
"replace-ext": "^1.0.0"
}
},
+ "vinyl-contents": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz",
+ "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==",
+ "dev": true,
+ "requires": {
+ "bl": "^5.0.0",
+ "vinyl": "^3.0.0"
+ },
+ "dependencies": {
+ "bl": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+ "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
+ "dev": true,
+ "requires": {
+ "buffer": "^6.0.3",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "replace-ext": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz",
+ "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==",
+ "dev": true
+ },
+ "vinyl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz",
+ "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.2",
+ "clone-stats": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0",
+ "replace-ext": "^2.0.0",
+ "teex": "^1.0.1"
+ }
+ }
+ }
+ },
"vinyl-fs": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
@@ -26676,51 +26537,64 @@
"integrity": "sha512-+OMm11R1bGYbpIJ5eQIkwoDGFF4GvBz3Ztl6/VM+/RNNb2Gjk2c0Ku+oMmfhlTmTlPCpgHBsH4JqVCbUYhu5bA=="
},
"vscode-jsonrpc": {
- "version": "8.2.0",
- "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
- "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="
+ "version": "9.0.0-next.5",
+ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.0-next.5.tgz",
+ "integrity": "sha512-Sl/8RAJtfF/2x/TPBVRuhzRAcqYR/QDjEjNqMcoKFfqsxfVUPzikupRDQYB77Gkbt1RrW43sSuZ5uLtNAcikQQ=="
},
"vscode-languageclient": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
- "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
+ "version": "10.0.0-next.12",
+ "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-10.0.0-next.12.tgz",
+ "integrity": "sha512-q7cVYCcYiv+a+fJYCbjMMScOGBnX162IBeUMFg31mvnN7RHKx5/CwKaCz+r+RciJrRXMqS8y8qpEVGgeIPnbxg==",
"requires": {
- "minimatch": "^5.1.0",
- "semver": "^7.3.7",
- "vscode-languageserver-protocol": "3.17.5"
+ "minimatch": "^9.0.3",
+ "semver": "^7.6.0",
+ "vscode-languageserver-protocol": "3.17.6-next.10"
+ },
+ "dependencies": {
+ "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==",
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "requires": {
+ "brace-expansion": "^2.0.2"
+ }
+ }
}
},
"vscode-languageserver-protocol": {
- "version": "3.17.5",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
- "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
+ "version": "3.17.6-next.10",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.6-next.10.tgz",
+ "integrity": "sha512-KOrrWn4NVC5jnFC5N6y/fyNKtx8rVYr67lhL/Z0P4ZBAN27aBsCnLBWAMIkYyJ1K8EZaE5r7gqdxrS9JPB6LIg==",
"requires": {
- "vscode-jsonrpc": "8.2.0",
- "vscode-languageserver-types": "3.17.5"
+ "vscode-jsonrpc": "9.0.0-next.5",
+ "vscode-languageserver-types": "3.17.6-next.5"
}
},
"vscode-languageserver-types": {
- "version": "3.17.5",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
- "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
+ "version": "3.17.6-next.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.6-next.5.tgz",
+ "integrity": "sha512-QFmf3Yl1tCgUQfA77N9Me/LXldJXkIVypQbty2rJ1DNHQkC+iwvm4Z2tXg9czSwlhvv0pD4pbF5mT7WhAglolw=="
},
"vscode-tas-client": {
- "version": "0.1.75",
- "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.75.tgz",
- "integrity": "sha512-/+ALFWPI4U3obeRvLFSt39guT7P9bZQrkmcLoiS+2HtzJ/7iPKNt5Sj+XTiitGlPYVFGFc0plxX8AAp6Uxs0xQ==",
+ "version": "0.1.84",
+ "resolved": "https://registry.npmjs.org/vscode-tas-client/-/vscode-tas-client-0.1.84.tgz",
+ "integrity": "sha512-rUTrUopV+70hvx1hW5ebdw1nd6djxubkLvVxjGdyD/r5v/wcVF41LIfiAtbm5qLZDtQdsMH1IaCuDoluoIa88w==",
"requires": {
- "tas-client": "0.1.73"
+ "tas-client": "0.2.33"
}
},
- "vscode-uri": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz",
- "integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ=="
- },
"watchpack": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
- "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz",
+ "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==",
"dev": true,
"requires": {
"glob-to-regexp": "^0.4.1",
@@ -26728,35 +26602,77 @@
}
},
"webpack": {
- "version": "5.76.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz",
- "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==",
- "dev": true,
- "requires": {
- "@types/eslint-scope": "^3.7.3",
- "@types/estree": "^0.0.51",
- "@webassemblyjs/ast": "1.11.1",
- "@webassemblyjs/wasm-edit": "1.11.1",
- "@webassemblyjs/wasm-parser": "1.11.1",
- "acorn": "^8.7.1",
- "acorn-import-assertions": "^1.7.6",
- "browserslist": "^4.14.5",
+ "version": "5.105.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz",
+ "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==",
+ "dev": true,
+ "requires": {
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.8",
+ "@types/json-schema": "^7.0.15",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.15.0",
+ "acorn-import-phases": "^1.0.3",
+ "browserslist": "^4.28.1",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.10.0",
- "es-module-lexer": "^0.9.0",
+ "enhanced-resolve": "^5.19.0",
+ "es-module-lexer": "^2.0.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
- "graceful-fs": "^4.2.9",
+ "graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
- "loader-runner": "^4.2.0",
+ "loader-runner": "^4.3.1",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.1.0",
- "tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.1.3",
- "watchpack": "^2.4.0",
- "webpack-sources": "^3.2.3"
+ "schema-utils": "^4.3.3",
+ "tapable": "^2.3.0",
+ "terser-webpack-plugin": "^5.3.16",
+ "watchpack": "^2.5.1",
+ "webpack-sources": "^3.3.3"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ }
+ },
+ "ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.3"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
+ "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.9",
+ "ajv": "^8.9.0",
+ "ajv-formats": "^2.1.1",
+ "ajv-keywords": "^5.1.0"
+ }
+ }
}
},
"webpack-bundle-analyzer": {
@@ -26906,9 +26822,9 @@
"requires": {}
},
"webpack-sources": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
- "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
+ "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"dev": true
},
"which": {
@@ -26930,43 +26846,21 @@
"is-number-object": "^1.0.4",
"is-string": "^1.0.5",
"is-symbol": "^1.0.3"
- },
- "dependencies": {
- "is-boolean-object": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz",
- "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==",
- "dev": true,
- "requires": {
- "call-bind": "^1.0.2"
- }
- },
- "is-number-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz",
- "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",
- "dev": true
- }
}
},
- "which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==",
- "dev": true
- },
"which-typed-array": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz",
- "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==",
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"dev": true,
"requires": {
- "available-typed-arrays": "^1.0.5",
- "call-bind": "^1.0.2",
- "es-abstract": "^1.18.5",
- "foreach": "^2.0.5",
- "has-tostringtag": "^1.0.0",
- "is-typed-array": "^1.1.7"
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2"
}
},
"wildcard": {
@@ -27006,35 +26900,82 @@
}
},
"workerpool": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
- "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
+ "version": "9.3.4",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz",
+ "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==",
"dev": true
},
"wrap-ansi": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
- "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1"
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
},
"dependencies": {
- "ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
+ }
+ }
+ },
+ "wrap-ansi-cjs": {
+ "version": "npm:wrap-ansi@7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
},
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
- "ansi-regex": "^2.0.0"
+ "color-name": "~1.1.4"
}
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
}
}
},
@@ -27056,9 +26997,9 @@
}
},
"ws": {
- "version": "7.5.7",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
- "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==",
+ "version": "7.5.10",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
+ "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"dev": true,
"requires": {}
},
@@ -27154,35 +27095,12 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
- "get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
- },
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
- "string-width": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
- "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
- "dev": true,
- "requires": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.0"
- }
- },
"which-module": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
diff --git a/package.json b/package.json
index 4914c57cf96e..9f689b60ff34 100644
--- a/package.json
+++ b/package.json
@@ -1,15 +1,15 @@
{
"name": "python",
"displayName": "Python",
- "description": "IntelliSense (Pylance), Linting, Debugging (Python Debugger), code formatting, refactoring, unit tests, and more.",
- "version": "2024.1.0-dev",
+ "description": "Python language support with extension access points for IntelliSense (Pylance), Debugging (Python Debugger), linting, formatting, refactoring, unit tests, and more.",
+ "version": "2026.5.0-dev",
"featureFlags": {
"usingNewInterpreterStorage": true
},
"capabilities": {
"untrustedWorkspaces": {
- "supported": "limited",
- "description": "Only Partial IntelliSense with Pylance is supported. Cannot execute Python with untrusted files."
+ "supported": false,
+ "description": "The Python extension is not available in untrusted workspaces. Use Pylance to get partial IntelliSense support for Python files."
},
"virtualWorkspaces": {
"supported": "limited",
@@ -23,7 +23,10 @@
"testObserver",
"quickPickItemTooltip",
"terminalDataWriteEvent",
- "terminalExecuteCommandEvent"
+ "terminalExecuteCommandEvent",
+ "codeActionAI",
+ "notebookReplDocument",
+ "notebookVariableProvider"
],
"author": {
"name": "Microsoft Corporation"
@@ -44,7 +47,7 @@
"theme": "dark"
},
"engines": {
- "vscode": "^1.82.0"
+ "vscode": "^1.95.0"
},
"enableTelemetry": false,
"keywords": [
@@ -56,8 +59,6 @@
"categories": [
"Programming Languages",
"Debuggers",
- "Linters",
- "Formatters",
"Other",
"Data Science",
"Machine Learning"
@@ -66,111 +67,57 @@
"onDebugInitialConfigurations",
"onLanguage:python",
"onDebugResolve:python",
+ "onCommand:python.copilotSetupTests",
"workspaceContains:mspythonconfig.json",
"workspaceContains:pyproject.toml",
"workspaceContains:Pipfile",
"workspaceContains:setup.py",
"workspaceContains:requirements.txt",
+ "workspaceContains:pylock.toml",
+ "workspaceContains:**/pylock.*.toml",
"workspaceContains:manage.py",
- "workspaceContains:app.py"
+ "workspaceContains:app.py",
+ "workspaceContains:.venv",
+ "workspaceContains:.conda",
+ "onLanguageModelTool:get_python_environment_details",
+ "onLanguageModelTool:get_python_executable_details",
+ "onLanguageModelTool:install_python_packages",
+ "onLanguageModelTool:configure_python_environment",
+ "onLanguageModelTool:create_virtual_environment",
+ "onTerminalShellIntegration:python"
],
"main": "./out/client/extension",
"browser": "./dist/extension.browser.js",
"l10n": "./l10n",
"contributes": {
- "walkthroughs": [
+ "problemMatchers": [
{
- "id": "pythonWelcome",
- "title": "%walkthrough.pythonWelcome.title%",
- "description": "%walkthrough.pythonWelcome.description%",
- "when": "workspacePlatform != webworker",
- "steps": [
- {
- "id": "python.createPythonFile",
- "title": "%walkthrough.step.python.createPythonFile.title%",
- "description": "%walkthrough.step.python.createPythonFile.description%",
- "media": {
- "svg": "resources/walkthrough/open-folder.svg",
- "altText": "%walkthrough.step.python.createPythonFile.altText%"
- },
- "when": ""
- },
- {
- "id": "python.installPythonWin8",
- "title": "%walkthrough.step.python.installPythonWin8.title%",
- "description": "%walkthrough.step.python.installPythonWin8.description%",
- "media": {
- "markdown": "resources/walkthrough/install-python-windows-8.md"
- },
- "when": "workspacePlatform == windows && showInstallPythonTile"
- },
- {
- "id": "python.installPythonMac",
- "title": "%walkthrough.step.python.installPythonMac.title%",
- "description": "%walkthrough.step.python.installPythonMac.description%",
- "media": {
- "markdown": "resources/walkthrough/install-python-macos.md"
- },
- "when": "workspacePlatform == mac && showInstallPythonTile",
- "command": "workbench.action.terminal.new"
- },
- {
- "id": "python.installPythonLinux",
- "title": "%walkthrough.step.python.installPythonLinux.title%",
- "description": "%walkthrough.step.python.installPythonLinux.description%",
- "media": {
- "markdown": "resources/walkthrough/install-python-linux.md"
- },
- "when": "workspacePlatform == linux && showInstallPythonTile",
- "command": "workbench.action.terminal.new"
- },
- {
- "id": "python.selectInterpreter",
- "title": "%walkthrough.step.python.selectInterpreter.title%",
- "description": "%walkthrough.step.python.selectInterpreter.description%",
- "media": {
- "svg": "resources/walkthrough/python-interpreter.svg",
- "altText": "%walkthrough.step.python.selectInterpreter.altText%"
- },
- "when": "workspaceFolderCount == 0"
- },
+ "name": "python",
+ "owner": "python",
+ "source": "python",
+ "fileLocation": "autoDetect",
+ "pattern": [
{
- "id": "python.createEnvironment",
- "title": "%walkthrough.step.python.createEnvironment.title%",
- "description": "%walkthrough.step.python.createEnvironment.description%",
- "media": {
- "svg": "resources/walkthrough/create-environment.svg",
- "altText": "%walkthrough.step.python.createEnvironment.altText%"
- },
- "when": "workspaceFolderCount > 0"
+ "regexp": "^.*File \\\"([^\\\"]|.*)\\\", line (\\d+).*",
+ "file": 1,
+ "line": 2
},
{
- "id": "python.runAndDebug",
- "title": "%walkthrough.step.python.runAndDebug.title%",
- "description": "%walkthrough.step.python.runAndDebug.description%",
- "media": {
- "svg": "resources/walkthrough/rundebug2.svg",
- "altText": "%walkthrough.step.python.runAndDebug.altText%"
- },
- "when": ""
+ "regexp": "^\\s*(.*)\\s*$"
},
{
- "id": "python.learnMoreWithDS",
- "title": "%walkthrough.step.python.learnMoreWithDS.title%",
- "description": "%walkthrough.step.python.learnMoreWithDS.description%",
- "media": {
- "altText": "%walkthrough.step.python.learnMoreWithDS.altText%",
- "svg": "resources/walkthrough/learnmore.svg"
- },
- "when": ""
+ "regexp": "^\\s*(.*Error.*)$",
+ "message": 1
}
]
- },
+ }
+ ],
+ "walkthroughs": [
{
- "id": "pythonWelcome2",
+ "id": "pythonWelcome",
"title": "%walkthrough.pythonWelcome.title%",
"description": "%walkthrough.pythonWelcome.description%",
- "when": "false",
+ "when": "workspacePlatform != webworker",
"steps": [
{
"id": "python.createPythonFolder",
@@ -189,8 +136,7 @@
"media": {
"svg": "resources/walkthrough/open-folder.svg",
"altText": "%walkthrough.step.python.createPythonFile.altText%"
- },
- "when": ""
+ }
},
{
"id": "python.installPythonWin8",
@@ -222,13 +168,13 @@
"command": "workbench.action.terminal.new"
},
{
- "id": "python.createEnvironment2",
- "title": "%walkthrough.step.python.createEnvironment.title2%",
- "description": "%walkthrough.step.python.createEnvironment.description2%",
+ "id": "python.createEnvironment",
+ "title": "%walkthrough.step.python.createEnvironment.title%",
+ "description": "%walkthrough.step.python.createEnvironment.description%",
"media": {
- "markdown": "resources/walkthrough/environments-info.md"
- },
- "when": ""
+ "svg": "resources/walkthrough/create-environment.svg",
+ "altText": "%walkthrough.step.python.createEnvironment.altText%"
+ }
},
{
"id": "python.runAndDebug",
@@ -237,18 +183,16 @@
"media": {
"svg": "resources/walkthrough/rundebug2.svg",
"altText": "%walkthrough.step.python.runAndDebug.altText%"
- },
- "when": ""
+ }
},
{
- "id": "python.learnMoreWithDS2",
+ "id": "python.learnMoreWithDS",
"title": "%walkthrough.step.python.learnMoreWithDS.title%",
- "description": "%walkthrough.step.python.learnMoreWithDS.description2%",
+ "description": "%walkthrough.step.python.learnMoreWithDS.description%",
"media": {
"altText": "%walkthrough.step.python.learnMoreWithDS.altText%",
"svg": "resources/walkthrough/learnmore.svg"
- },
- "when": ""
+ }
}
]
},
@@ -329,6 +273,11 @@
"category": "Python",
"command": "python.createNewFile"
},
+ {
+ "category": "Python",
+ "command": "python.copyTestId",
+ "title": "%python.command.python.testing.copyTestId.title%"
+ },
{
"category": "Python",
"command": "python.analysis.restartLanguageServer",
@@ -364,11 +313,6 @@
"command": "python.createEnvironment-button",
"title": "%python.command.python.createEnvironment.title%"
},
- {
- "category": "Python",
- "command": "python.enableSourceMapSupport",
- "title": "%python.command.python.enableSourceMapSupport.title%"
- },
{
"category": "Python",
"command": "python.execInTerminal",
@@ -394,19 +338,13 @@
{
"category": "Python",
"command": "python.execSelectionInTerminal",
- "title": "%python.command.python.execSelectionInTerminal.title%"
+ "title": "%python.command.python.execSelectionInTerminal.title%",
+ "shortTitle": "%python.command.python.execSelectionInTerminal.shortTitle%"
},
{
"category": "Python",
- "command": "python.launchTensorBoard",
- "title": "%python.command.python.launchTensorBoard.title%"
- },
- {
- "category": "Python",
- "command": "python.refreshTensorBoard",
- "enablement": "python.hasActiveTensorBoardSession",
- "icon": "$(refresh)",
- "title": "%python.command.python.refreshTensorBoard.title%"
+ "command": "python.execInREPL",
+ "title": "%python.command.python.execInREPL.title%"
},
{
"category": "Python",
@@ -427,7 +365,12 @@
{
"category": "Python",
"command": "python.startREPL",
- "title": "%python.command.python.startREPL.title%"
+ "title": "%python.command.python.startTerminalREPL.title%"
+ },
+ {
+ "category": "Python",
+ "command": "python.startNativeREPL",
+ "title": "%python.command.python.startNativeREPL.title%"
},
{
"category": "Python",
@@ -466,7 +409,7 @@
"uniqueItems": true
},
"python.createEnvironment.contentButton": {
- "default": "show",
+ "default": "hide",
"markdownDescription": "%python.createEnvironment.contentButton.description%",
"scope": "machine-overridable",
"type": "string",
@@ -476,16 +419,13 @@
]
},
"python.createEnvironment.trigger": {
- "default": "off",
+ "default": "prompt",
"markdownDescription": "%python.createEnvironment.trigger.description%",
"scope": "machine-overridable",
"type": "string",
"enum": [
"off",
"prompt"
- ],
- "tags": [
- "experimental"
]
},
"python.condaPath": {
@@ -500,22 +440,26 @@
"scope": "machine-overridable",
"type": "string"
},
- "python.diagnostics.sourceMapsEnabled": {
- "default": false,
- "description": "%python.diagnostics.sourceMapsEnabled.description%",
- "scope": "application",
- "type": "boolean"
- },
"python.envFile": {
"default": "${workspaceFolder}/.env",
"description": "%python.envFile.description%",
"scope": "resource",
"type": "string"
},
+ "python.useEnvironmentsExtension": {
+ "default": false,
+ "description": "%python.useEnvironmentsExtension.description%",
+ "scope": "machine-overridable",
+ "type": "boolean",
+ "tags": [
+ "onExP",
+ "preview"
+ ]
+ },
"python.experiments.enabled": {
"default": true,
"description": "%python.experiments.enabled.description%",
- "scope": "machine",
+ "scope": "window",
"type": "boolean"
},
"python.experiments.optInto": {
@@ -528,9 +472,7 @@
"pythonPromptNewToolsExt",
"pythonTerminalEnvVarActivation",
"pythonDiscoveryUsingWorkers",
- "pythonTestAdapter",
- "pythonREPLSmartSend",
- "pythonRecommendTensorboardExt"
+ "pythonTestAdapter"
],
"enumDescriptions": [
"%python.experiments.All.description%",
@@ -538,12 +480,10 @@
"%python.experiments.pythonPromptNewToolsExt.description%",
"%python.experiments.pythonTerminalEnvVarActivation.description%",
"%python.experiments.pythonDiscoveryUsingWorkers.description%",
- "%python.experiments.pythonTestAdapter.description%",
- "%python.experiments.pythonREPLSmartSend.description%",
- "%python.experiments.pythonRecommendTensorboardExt.description%"
+ "%python.experiments.pythonTestAdapter.description%"
]
},
- "scope": "machine",
+ "scope": "window",
"type": "array",
"uniqueItems": true
},
@@ -557,8 +497,7 @@
"pythonPromptNewToolsExt",
"pythonTerminalEnvVarActivation",
"pythonDiscoveryUsingWorkers",
- "pythonTestAdapter",
- "pythonREPLSmartSend"
+ "pythonTestAdapter"
],
"enumDescriptions": [
"%python.experiments.All.description%",
@@ -566,11 +505,10 @@
"%python.experiments.pythonPromptNewToolsExt.description%",
"%python.experiments.pythonTerminalEnvVarActivation.description%",
"%python.experiments.pythonDiscoveryUsingWorkers.description%",
- "%python.experiments.pythonTestAdapter.description%",
- "%python.experiments.pythonREPLSmartSend.description%"
+ "%python.experiments.pythonTestAdapter.description%"
]
},
- "scope": "machine",
+ "scope": "window",
"type": "array",
"uniqueItems": true
},
@@ -638,10 +576,21 @@
"Warning"
],
"scope": "resource",
- "type": "string",
+ "type": "string"
+ },
+ "python.locator": {
+ "default": "js",
+ "description": "%python.locator.description%",
+ "enum": [
+ "js",
+ "native"
+ ],
"tags": [
- "experimental"
- ]
+ "onExP",
+ "preview"
+ ],
+ "scope": "machine",
+ "type": "string"
},
"python.pipenvPath": {
"default": "pipenv",
@@ -655,13 +604,11 @@
"scope": "machine-overridable",
"type": "string"
},
- "python.tensorBoard.logDirectory": {
- "default": "",
- "description": "%python.tensorBoard.logDirectory.description%",
- "scope": "resource",
- "type": "string",
- "markdownDeprecationMessage": "%python.tensorBoard.logDirectory.markdownDeprecationMessage%",
- "deprecationMessage": "%python.tensorBoard.logDirectory.deprecationMessage%"
+ "python.pixiToolPath": {
+ "default": "pixi",
+ "description": "%python.pixiToolPath.description%",
+ "scope": "machine-overridable",
+ "type": "string"
},
"python.terminal.activateEnvInCurrentTerminal": {
"default": false,
@@ -693,18 +640,45 @@
"scope": "resource",
"type": "array"
},
+ "python.terminal.shellIntegration.enabled": {
+ "default": true,
+ "markdownDescription": "%python.terminal.shellIntegration.enabled.description%",
+ "scope": "resource",
+ "type": "boolean",
+ "tags": [
+ "preview"
+ ]
+ },
"python.REPL.enableREPLSmartSend": {
"default": true,
"description": "%python.EnableREPLSmartSend.description%",
"scope": "resource",
"type": "boolean"
},
+ "python.REPL.sendToNativeREPL": {
+ "default": false,
+ "description": "%python.REPL.sendToNativeREPL.description%",
+ "scope": "resource",
+ "type": "boolean"
+ },
+ "python.REPL.provideVariables": {
+ "default": true,
+ "description": "%python.REPL.provideVariables.description%",
+ "scope": "resource",
+ "type": "boolean"
+ },
"python.testing.autoTestDiscoverOnSaveEnabled": {
"default": true,
"description": "%python.testing.autoTestDiscoverOnSaveEnabled.description%",
"scope": "resource",
"type": "boolean"
},
+ "python.testing.autoTestDiscoverOnSavePattern": {
+ "default": "**/*.py",
+ "description": "%python.testing.autoTestDiscoverOnSavePattern.description%",
+ "scope": "resource",
+ "type": "string"
+ },
"python.testing.cwd": {
"default": null,
"description": "%python.testing.cwd.description%",
@@ -1179,13 +1153,22 @@
{
"command": "python.execSelectionInTerminal",
"key": "shift+enter",
- "when": "editorTextFocus && editorLangId == python && !findInputFocussed && !replaceInputFocussed && !jupyter.ownsSelection && !notebookEditorFocused"
+ "when": "editorTextFocus && editorLangId == python && !findInputFocussed && !replaceInputFocussed && !jupyter.ownsSelection && !notebookEditorFocused && !isCompositeNotebook"
+ },
+ {
+ "command": "python.execInREPL",
+ "key": "shift+enter",
+ "when": "config.python.REPL.sendToNativeREPL && editorLangId == python && editorTextFocus && !jupyter.ownsSelection && !notebookEditorFocused && !isCompositeNotebook"
+ },
+ {
+ "command": "python.execInREPLEnter",
+ "key": "enter",
+ "when": "!config.interactiveWindow.executeWithShiftEnter && isCompositeNotebook && activeEditor == 'workbench.editor.repl' && !inlineChatFocused && !notebookCellListFocused"
},
{
- "command": "python.refreshTensorBoard",
- "key": "ctrl+r",
- "mac": "cmd+r",
- "when": "python.hasActiveTensorBoardSession"
+ "command": "python.execInInteractiveWindowEnter",
+ "key": "enter",
+ "when": "!config.interactiveWindow.executeWithShiftEnter && isCompositeNotebook && activeEditor == 'workbench.editor.interactive' && !inlineChatFocused && !notebookCellListFocused"
}
],
"languages": [
@@ -1236,7 +1219,8 @@
{
"filenames": [
"Pipfile",
- "poetry.lock"
+ "poetry.lock",
+ "uv.lock"
],
"id": "toml"
},
@@ -1248,12 +1232,31 @@
}
],
"menus": {
+ "issue/reporter": [
+ {
+ "command": "python.reportIssue"
+ }
+ ],
+ "testing/item/context": [
+ {
+ "command": "python.copyTestId",
+ "group": "navigation",
+ "when": "controllerId == 'python-tests'"
+ }
+ ],
+ "testing/item/gutter": [
+ {
+ "command": "python.copyTestId",
+ "group": "navigation",
+ "when": "controllerId == 'python-tests'"
+ }
+ ],
"commandPalette": [
{
"category": "Python",
"command": "python.analysis.restartLanguageServer",
"title": "%python.command.python.analysis.restartLanguageServer.title%",
- "when": "!virtualWorkspace && shellExecutionSupported && editorLangId == python"
+ "when": "!virtualWorkspace && shellExecutionSupported && (editorLangId == python || notebookType == jupyter-notebook)"
},
{
"category": "Python",
@@ -1291,12 +1294,6 @@
"title": "%python.command.python.createTerminal.title%",
"when": "!virtualWorkspace && shellExecutionSupported"
},
- {
- "category": "Python",
- "command": "python.enableSourceMapSupport",
- "title": "%python.command.python.enableSourceMapSupport.title%",
- "when": "!virtualWorkspace && shellExecutionSupported"
- },
{
"category": "Python",
"command": "python.execInTerminal",
@@ -1331,17 +1328,15 @@
},
{
"category": "Python",
- "command": "python.launchTensorBoard",
- "title": "%python.command.python.launchTensorBoard.title%",
- "when": "!virtualWorkspace && shellExecutionSupported && !python.tensorboardExtInstalled"
+ "command": "python.copyTestId",
+ "title": "%python.command.python.testing.copyTestId.title%",
+ "when": "false"
},
{
"category": "Python",
- "command": "python.refreshTensorBoard",
- "enablement": "python.hasActiveTensorBoardSession",
- "icon": "$(refresh)",
- "title": "%python.command.python.refreshTensorBoard.title%",
- "when": "!virtualWorkspace && shellExecutionSupported && !python.tensorboardExtInstalled"
+ "command": "python.execInREPL",
+ "title": "%python.command.python.execInREPL.title%",
+ "when": "false"
},
{
"category": "Python",
@@ -1365,7 +1360,13 @@
{
"category": "Python",
"command": "python.startREPL",
- "title": "%python.command.python.startREPL.title%",
+ "title": "%python.command.python.startTerminalREPL.title%",
+ "when": "!virtualWorkspace && shellExecutionSupported"
+ },
+ {
+ "category": "Python",
+ "command": "python.startNativeREPL",
+ "title": "%python.command.python.startNativeREPL.title%",
"when": "!virtualWorkspace && shellExecutionSupported"
},
{
@@ -1398,12 +1399,12 @@
{
"submenu": "python.run",
"group": "Python",
- "when": "editorLangId == python && !virtualWorkspace && shellExecutionSupported && isWorkspaceTrusted"
+ "when": "editorLangId == python && !virtualWorkspace && shellExecutionSupported && isWorkspaceTrusted && !inChat && notebookType != jupyter-notebook"
},
{
"submenu": "python.runFileInteractive",
"group": "Jupyter2",
- "when": "editorLangId == python && !virtualWorkspace && shellExecutionSupported && !isJupyterInstalled && isWorkspaceTrusted"
+ "when": "editorLangId == python && !virtualWorkspace && shellExecutionSupported && !isJupyterInstalled && isWorkspaceTrusted && !inChat"
}
],
"python.runFileInteractive": [
@@ -1427,14 +1428,12 @@
{
"command": "python.execSelectionInTerminal",
"group": "Python",
- "when": "editorFocus && editorLangId == python && !virtualWorkspace && shellExecutionSupported"
- }
- ],
- "editor/title": [
+ "when": "!config.python.REPL.sendToNativeREPL && editorFocus && editorLangId == python && !virtualWorkspace && shellExecutionSupported"
+ },
{
- "command": "python.refreshTensorBoard",
- "group": "navigation@0",
- "when": "python.hasActiveTensorBoardSession && !virtualWorkspace && shellExecutionSupported"
+ "command": "python.execInREPL",
+ "group": "Python",
+ "when": "editorFocus && editorLangId == python && !virtualWorkspace && shellExecutionSupported && config.python.REPL.sendToNativeREPL"
}
],
"editor/title/run": [
@@ -1504,8 +1503,167 @@
"fileMatch": "meta.yaml",
"url": "./schemas/conda-meta.json"
}
+ ],
+ "languageModelTools": [
+ {
+ "name": "get_python_environment_details",
+ "displayName": "Get Python Environment Info",
+ "userDescription": "%python.languageModelTools.get_python_environment_details.userDescription%",
+ "modelDescription": "This tool will retrieve the details of the Python Environment for the specified file or workspace. The details returned include the 1. Type of Python Environment (conda, venv, etc), 2. Version of Python, 3. List of all installed Python packages with their versions. ALWAYS call configure_python_environment before using this tool. IMPORTANT: This tool is only for Python environments (venv, virtualenv, conda, pipenv, poetry, pyenv, pixi, or any other Python environment manager). Do not use this tool for npm packages, system packages, Ruby gems, or any other non-Python dependencies.",
+ "toolReferenceName": "getPythonEnvironmentInfo",
+ "tags": [
+ "python",
+ "python environment",
+ "extension_installed_by_tool",
+ "enable_other_tool_configure_python_environment"
+ ],
+ "icon": "$(snake)",
+ "canBeReferencedInPrompt": true,
+ "inputSchema": {
+ "type": "object",
+ "properties": {
+ "resourcePath": {
+ "type": "string",
+ "description": "The path to the Python file or workspace to get the environment information for."
+ }
+ },
+ "required": []
+ }
+ },
+ {
+ "name": "get_python_executable_details",
+ "displayName": "Get Python Executable",
+ "userDescription": "%python.languageModelTools.get_python_executable_details.userDescription%",
+ "modelDescription": "This tool will retrieve the details of the Python Environment for the specified file or workspace. ALWAYS use this tool before executing any Python command in the terminal. This tool returns the details of how to construct the fully qualified path and or command including details such as arguments required to run Python in a terminal. Note: Instead of executing `python --version` or `python -c 'import sys; print(sys.executable)'`, use this tool to get the Python executable path to replace the `python` command. E.g. instead of using `python -c 'import sys; print(sys.executable)'`, use this tool to build the command `conda run -n -c 'import sys; print(sys.executable)'`. ALWAYS call configure_python_environment before using this tool. IMPORTANT: This tool is only for Python environments (venv, virtualenv, conda, pipenv, poetry, pyenv, pixi, or any other Python environment manager). Do not use this tool for npm packages, system packages, Ruby gems, or any other non-Python dependencies.",
+ "toolReferenceName": "getPythonExecutableCommand",
+ "tags": [
+ "python",
+ "python environment",
+ "extension_installed_by_tool",
+ "enable_other_tool_configure_python_environment"
+ ],
+ "icon": "$(terminal)",
+ "canBeReferencedInPrompt": true,
+ "inputSchema": {
+ "type": "object",
+ "properties": {
+ "resourcePath": {
+ "type": "string",
+ "description": "The path to the Python file or workspace to get the executable information for. If not provided, the current workspace will be used. Where possible pass the path to the file or workspace."
+ }
+ },
+ "required": []
+ }
+ },
+ {
+ "name": "install_python_packages",
+ "displayName": "Install Python Package",
+ "userDescription": "%python.languageModelTools.install_python_packages.userDescription%",
+ "modelDescription": "Installs Python packages in the given workspace. Use this tool to install Python packages in the user's chosen Python environment. ALWAYS call configure_python_environment before using this tool. IMPORTANT: This tool should only be used to install Python packages using package managers like pip or conda (works with any Python environment: venv, virtualenv, pipenv, poetry, pyenv, pixi, conda, etc.). Do not use this tool to install npm packages, system packages (apt/brew/yum), Ruby gems, or any other non-Python dependencies.",
+ "toolReferenceName": "installPythonPackage",
+ "tags": [
+ "python",
+ "python environment",
+ "install python package",
+ "extension_installed_by_tool",
+ "enable_other_tool_configure_python_environment"
+ ],
+ "icon": "$(package)",
+ "canBeReferencedInPrompt": true,
+ "inputSchema": {
+ "type": "object",
+ "properties": {
+ "packageList": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "The list of Python packages to install."
+ },
+ "resourcePath": {
+ "type": "string",
+ "description": "The path to the Python file or workspace into which the packages are installed. If not provided, the current workspace will be used. Where possible pass the path to the file or workspace."
+ }
+ },
+ "required": [
+ "packageList"
+ ]
+ }
+ },
+ {
+ "name": "configure_python_environment",
+ "displayName": "Configure Python Environment",
+ "modelDescription": "This tool configures a Python environment in the given workspace. ALWAYS Use this tool to set up the user's chosen environment and ALWAYS call this tool before using any other Python related tools or running any Python command in the terminal. IMPORTANT: This tool is only for Python environments (venv, virtualenv, conda, pipenv, poetry, pyenv, pixi, or any other Python environment manager). Do not use this tool for npm packages, system packages, Ruby gems, or any other non-Python dependencies.",
+ "userDescription": "%python.languageModelTools.configure_python_environment.userDescription%",
+ "toolReferenceName": "configurePythonEnvironment",
+ "tags": [
+ "python",
+ "python environment",
+ "extension_installed_by_tool"
+ ],
+ "icon": "$(gear)",
+ "canBeReferencedInPrompt": true,
+ "inputSchema": {
+ "type": "object",
+ "properties": {
+ "resourcePath": {
+ "type": "string",
+ "description": "The path to the Python file or workspace for which a Python Environment needs to be configured."
+ }
+ },
+ "required": []
+ }
+ },
+ {
+ "name": "create_virtual_environment",
+ "displayName": "Create a Virtual Environment",
+ "modelDescription": "This tool will create a Virual Environment",
+ "tags": [],
+ "canBeReferencedInPrompt": false,
+ "inputSchema": {
+ "type": "object",
+ "properties": {
+ "packageList": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "The list of packages to install."
+ },
+ "resourcePath": {
+ "type": "string",
+ "description": "The path to the Python file or workspace for which a Python Environment needs to be configured."
+ }
+ },
+ "required": []
+ },
+ "when": "false"
+ },
+ {
+ "name": "selectEnvironment",
+ "displayName": "Select a Python Environment",
+ "modelDescription": "This tool will prompt the user to select an existing Python Environment",
+ "tags": [],
+ "canBeReferencedInPrompt": false,
+ "inputSchema": {
+ "type": "object",
+ "properties": {
+ "resourcePath": {
+ "type": "string",
+ "description": "The path to the Python file or workspace for which a Python Environment needs to be configured."
+ }
+ },
+ "required": []
+ },
+ "when": "false"
+ }
]
},
+ "copilot": {
+ "tests": {
+ "getSetupConfirmation": "python.copilotSetupTests"
+ }
+ },
"scripts": {
"package": "gulp clean && gulp prePublishBundle && vsce package -o ms-python-insiders.vsix",
"prePublish": "gulp clean && gulp prePublishNonBundle",
@@ -1533,10 +1691,13 @@
"testSmoke": "cross-env INSTALL_JUPYTER_EXTENSION=true \"node ./out/test/smokeTest.js\"",
"testInsiders": "cross-env VSC_PYTHON_CI_TEST_VSC_CHANNEL=insiders INSTALL_PYLANCE_EXTENSION=true TEST_FILES_SUFFIX=insiders.test CODE_TESTS_WORKSPACE=src/testMultiRootWkspc/smokeTests \"node ./out/test/standardTest.js\"",
"lint-staged": "node gulpfile.js",
- "lint": "eslint --ext .ts,.js src build pythonExtensionApi",
- "lint-fix": "eslint --fix --ext .ts,.js src build pythonExtensionApi gulpfile.js",
+ "lint": "eslint src build pythonExtensionApi",
+ "lint-fix": "eslint --fix src build pythonExtensionApi gulpfile.js",
"format-check": "prettier --check 'src/**/*.ts' 'build/**/*.js' '.github/**/*.yml' gulpfile.js",
"format-fix": "prettier --write 'src/**/*.ts' 'build/**/*.js' '.github/**/*.yml' gulpfile.js",
+ "check-python": "npm run check-python:ruff && npm run check-python:pyright",
+ "check-python:ruff": "cd python_files && python -m pip install -U ruff && python -m ruff check . && python -m ruff format --check",
+ "check-python:pyright": "cd python_files && npx --yes pyright@1.1.308 .",
"clean": "gulp clean",
"addExtensionPackDependencies": "gulp addExtensionPackDependencies",
"updateBuildNumber": "gulp updateBuildNumber",
@@ -1544,35 +1705,32 @@
"webpack": "webpack"
},
"dependencies": {
- "@iarna/toml": "^2.2.5",
+ "@iarna/toml": "^3.0.0",
"@vscode/extension-telemetry": "^0.8.4",
- "@vscode/jupyter-lsp-middleware": "^0.2.50",
"arch": "^2.1.0",
- "fs-extra": "^10.0.1",
+ "fs-extra": "^11.2.0",
"glob": "^7.2.0",
- "hash.js": "^1.1.7",
"iconv-lite": "^0.6.3",
- "inversify": "^5.0.4",
+ "inversify": "^6.0.2",
"jsonc-parser": "^3.0.0",
- "lodash": "^4.17.21",
- "minimatch": "^5.0.1",
+ "lodash": "^4.18.1",
+ "minimatch": "^5.1.8",
"named-js-regexp": "^1.3.3",
"node-stream-zip": "^1.6.0",
- "reflect-metadata": "^0.1.12",
+ "reflect-metadata": "^0.2.2",
"rxjs": "^6.5.4",
"rxjs-compat": "^6.5.4",
"semver": "^7.5.2",
"stack-trace": "0.0.10",
"sudo-prompt": "^9.2.1",
- "tmp": "^0.0.33",
+ "tmp": "^0.2.5",
"uint64be": "^3.0.0",
"unicode": "^14.0.0",
- "untildify": "^4.0.0",
"vscode-debugprotocol": "^1.28.0",
- "vscode-jsonrpc": "^8.2.0",
- "vscode-languageclient": "^9.0.1",
- "vscode-languageserver-protocol": "^3.17.5",
- "vscode-tas-client": "^0.1.75",
+ "vscode-jsonrpc": "^9.0.0-next.5",
+ "vscode-languageclient": "^10.0.0-next.12",
+ "vscode-languageserver-protocol": "^3.17.6-next.10",
+ "vscode-tas-client": "^0.1.84",
"which": "^2.0.2",
"winreg": "^1.2.4",
"xml2js": "^0.5.0"
@@ -1584,45 +1742,46 @@
"@types/chai-arrays": "^2.0.0",
"@types/chai-as-promised": "^7.1.0",
"@types/download": "^8.0.1",
- "@types/fs-extra": "^9.0.13",
+ "@types/fs-extra": "^11.0.4",
"@types/glob": "^7.2.0",
"@types/lodash": "^4.14.104",
"@types/mocha": "^9.1.0",
- "@types/node": "^18.17.1",
+ "@types/node": "^22.19.1",
"@types/semver": "^5.5.0",
"@types/shortid": "^0.0.29",
- "@types/sinon": "^10.0.11",
+ "@types/sinon": "^17.0.3",
"@types/stack-trace": "0.0.29",
"@types/tmp": "^0.0.33",
- "@types/vscode": "^1.81.0",
+ "@types/vscode": "^1.95.0",
"@types/which": "^2.0.1",
"@types/winreg": "^1.2.30",
"@types/xml2js": "^0.4.2",
- "@typescript-eslint/eslint-plugin": "^3.7.0",
- "@typescript-eslint/parser": "^3.7.0",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
"@vscode/test-electron": "^2.3.8",
- "@vscode/vsce": "^2.18.0",
+ "@vscode/vsce": "^2.27.0",
"bent": "^7.3.12",
"chai": "^4.1.2",
"chai-arrays": "^2.0.0",
"chai-as-promised": "^7.1.1",
"copy-webpack-plugin": "^9.1.0",
+ "cross-env": "^7.0.3",
"cross-spawn": "^6.0.5",
"del": "^6.0.0",
"download": "^8.0.0",
- "eslint": "^7.2.0",
- "eslint-config-airbnb": "^18.2.0",
+ "eslint": "^8.57.1",
"eslint-config-prettier": "^8.3.0",
- "eslint-plugin-import": "^2.25.4",
+ "eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
+ "eslint-plugin-no-only-tests": "^3.3.0",
"eslint-plugin-react": "^7.20.3",
"eslint-plugin-react-hooks": "^4.0.0",
"expose-loader": "^3.1.0",
"flat": "^5.0.2",
"get-port": "^5.1.1",
- "gulp": "^4.0.0",
+ "gulp": "^5.0.0",
"gulp-typescript": "^5.0.0",
- "mocha": "^9.2.2",
+ "mocha": "^11.1.0",
"mocha-junit-reporter": "^2.0.2",
"mocha-multi-reporters": "^1.1.7",
"node-has-native-dependencies": "^1.0.2",
@@ -1632,16 +1791,16 @@
"prettier": "^2.0.2",
"rewiremock": "^3.13.0",
"shortid": "^2.2.8",
- "sinon": "^13.0.1",
+ "sinon": "^18.0.0",
"source-map-support": "^0.5.12",
"ts-loader": "^9.2.8",
"ts-mockito": "^2.5.0",
"ts-node": "^10.7.0",
"tsconfig-paths-webpack-plugin": "^3.2.0",
"typemoq": "^2.1.0",
- "typescript": "4.5.5",
- "uuid": "^8.3.2",
- "webpack": "^5.76.0",
+ "typescript": "~5.2",
+ "uuid": "^14.0.0",
+ "webpack": "^5.105.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2",
"webpack-fix-default-import-plugin": "^1.0.3",
diff --git a/package.nls.json b/package.nls.json
index 5a4c44a78191..57f2ed95b2c0 100644
--- a/package.nls.json
+++ b/package.nls.json
@@ -1,5 +1,10 @@
{
- "python.command.python.startREPL.title": "Start REPL",
+ "python.command.python.startTerminalREPL.title": "Start Terminal REPL",
+ "python.languageModelTools.get_python_environment_details.userDescription": "Get information for a Python Environment, such as Type, Version, Packages, and more.",
+ "python.languageModelTools.install_python_packages.userDescription": "Installs Python packages in a Python Environment.",
+ "python.languageModelTools.get_python_executable_details.userDescription": "Get executable info for a Python Environment",
+ "python.languageModelTools.configure_python_environment.userDescription": "Configure a Python Environment for a workspace",
+ "python.command.python.startNativeREPL.title": "Start Native Python REPL",
"python.command.python.createEnvironment.title": "Create Environment...",
"python.command.python.createNewFile.title": "New Python File",
"python.command.python.createTerminal.title": "Create Terminal",
@@ -14,13 +19,15 @@
"python.command.python.configureTests.title": "Configure Tests",
"python.command.testing.rerunFailedTests.title": "Rerun Failed Tests",
"python.command.python.execSelectionInTerminal.title": "Run Selection/Line in Python Terminal",
+ "python.command.python.execSelectionInTerminal.shortTitle": "Run Selection/Line",
+ "python.command.python.execInREPL.title": "Run Selection/Line in Native Python REPL",
"python.command.python.execSelectionInDjangoShell.title": "Run Selection/Line in Django Shell",
"python.command.python.reportIssue.title": "Report Issue...",
- "python.command.python.enableSourceMapSupport.title": "Enable Source Map Support For Extension Debugging",
"python.command.python.clearCacheAndReload.title": "Clear Cache and Reload Window",
"python.command.python.analysis.restartLanguageServer.title": "Restart Language Server",
"python.command.python.launchTensorBoard.title": "Launch TensorBoard",
"python.command.python.refreshTensorBoard.title": "Refresh TensorBoard",
+ "python.command.python.testing.copyTestId.title": "Copy Test Id",
"python.createEnvironment.contentButton.description": "Show or hide Create Environment button in the editor for `requirements.txt` or other dependency files.",
"python.createEnvironment.trigger.description": "Detect if environment creation is required for the current project",
"python.menu.createNewFile.title": "Python File",
@@ -31,18 +38,17 @@
"python.condaPath.description": "Path to the conda executable to use for activation (version 4.4+).",
"python.debugger.deprecatedMessage": "This configuration will be deprecated soon. Please replace `python` with `debugpy` to use the new Python Debugger extension.",
"python.defaultInterpreterPath.description": "Path to default Python to use when extension loads up for the first time, no longer used once an interpreter is selected for the workspace. See [here](https://aka.ms/AAfekmf) to understand when this is used",
- "python.diagnostics.sourceMapsEnabled.description": "Enable source map support for meaningful stack traces in error logs.",
"python.envFile.description": "Absolute path to a file containing environment variable definitions.",
+ "python.useEnvironmentsExtension.description": "Enables the Python Environments extension. Requires window reload on change.",
"python.experiments.enabled.description": "Enables A/B tests experiments in the Python extension. If enabled, you may get included in proposed enhancements and/or features.",
- "python.experiments.optInto.description": "List of experiment to opt into. If empty, user is assigned the default experiment groups. See [here](https://github.com/microsoft/vscode-python/wiki/AB-Experiments) for more details.",
- "python.experiments.optOutFrom.description": "List of experiment to opt out of. If empty, user is assigned the default experiment groups. See [here](https://github.com/microsoft/vscode-python/wiki/AB-Experiments) for more details.",
+ "python.experiments.optInto.description": "List of experiments to opt into. If empty, user is assigned the default experiment groups. See [here](https://github.com/microsoft/vscode-python/wiki/AB-Experiments) for more details.",
+ "python.experiments.optOutFrom.description": "List of experiments to opt out of. If empty, user is assigned the default experiment groups. See [here](https://github.com/microsoft/vscode-python/wiki/AB-Experiments) for more details.",
"python.experiments.All.description": "Combined list of all experiments.",
"python.experiments.pythonSurveyNotification.description": "Denotes the Python Survey Notification experiment.",
"python.experiments.pythonPromptNewToolsExt.description": "Denotes the Python Prompt New Tools Extension experiment.",
"python.experiments.pythonTerminalEnvVarActivation.description": "Enables use of environment variables to activate terminals instead of sending activation commands.",
"python.experiments.pythonDiscoveryUsingWorkers.description": "Enables use of worker threads to do heavy computation when discovering interpreters.",
"python.experiments.pythonTestAdapter.description": "Denotes the Python Test Adapter experiment.",
- "python.experiments.pythonREPLSmartSend.description": "Denotes the Python REPL Smart Send experiment.",
"python.experiments.pythonRecommendTensorboardExt.description": "Denotes the Tensorboard Extension recommendation experiment.",
"python.globalModuleInstallation.description": "Whether to install Python modules globally when not using an environment.",
"python.languageServer.description": "Defines type of the language server.",
@@ -57,24 +63,30 @@
"python.logging.level.description": "The logging level the extension logs at, defaults to 'error'",
"python.logging.level.deprecation": "This setting is deprecated. Please use command `Developer: Set Log Level...` to set logging level.",
"python.missingPackage.severity.description": "Set severity of missing packages in requirements.txt or pyproject.toml",
+ "python.locator.description": "[Experimental] Select implementation of environment locators. This is an experimental setting while we test native environment location.",
"python.pipenvPath.description": "Path to the pipenv executable to use for activation.",
"python.poetryPath.description": "Path to the poetry executable.",
+ "python.pixiToolPath.description": "Path to the pixi executable.",
"python.EnableREPLSmartSend.description": "Toggle Smart Send for the Python REPL. Smart Send enables sending the smallest runnable block of code to the REPL on Shift+Enter and moves the cursor accordingly.",
+ "python.REPL.sendToNativeREPL.description": "Toggle to send code to Python REPL instead of the terminal on execution. Turning this on will change the behavior for both Smart Send and Run Selection/Line in the Context Menu.",
+ "python.REPL.provideVariables.description": "Toggle to provide variables for the REPL variable view for the native REPL.",
"python.tensorBoard.logDirectory.description": "Set this setting to your preferred TensorBoard log directory to skip log directory prompt when starting TensorBoard.",
"python.tensorBoard.logDirectory.markdownDeprecationMessage": "Tensorboard support has been moved to the extension [Tensorboard extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.tensorboard). Instead use the setting `tensorBoard.logDirectory`.",
"python.tensorBoard.logDirectory.deprecationMessage": "Tensorboard support has been moved to the extension Tensorboard extension. Instead use the setting `tensorBoard.logDirectory`.",
+ "python.terminal.shellIntegration.enabled.description": "Enable [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration) for the terminals running python. Shell integration enhances the terminal experience by enabling command decorations, run recent command, improving accessibility among other things. Note: PyREPL (available in Python 3.13+) is automatically disabled when shell integration is enabled to avoid cursor indentation issues.",
"python.terminal.activateEnvInCurrentTerminal.description": "Activate Python Environment in the current Terminal on load of the Extension.",
"python.terminal.activateEnvironment.description": "Activate Python Environment in all Terminals created.",
"python.terminal.executeInFileDir.description": "When executing a file in the terminal, whether to use execute in the file's directory, instead of the current open folder.",
"python.terminal.focusAfterLaunch.description": "When launching a python terminal, whether to focus the cursor on the terminal.",
"python.terminal.launchArgs.description": "Python launch arguments to use when executing a file in the terminal.",
"python.testing.autoTestDiscoverOnSaveEnabled.description": "Enable auto run test discovery when saving a test file.",
+ "python.testing.autoTestDiscoverOnSavePattern.description": "Glob pattern used to determine which files are used by autoTestDiscoverOnSaveEnabled.",
"python.testing.cwd.description": "Optional working directory for tests.",
"python.testing.debugPort.description": "Port number used for debugging of tests.",
"python.testing.promptToConfigure.description": "Prompt to configure a test framework if potential tests directories are discovered.",
"python.testing.pytestArgs.description": "Arguments passed in. Each argument is a separate item in the array.",
"python.testing.pytestEnabled.description": "Enable testing using pytest.",
- "python.testing.pytestPath.description": "Path to pytest (pytest), you can use a custom version of pytest by modifying this setting to include the full path.",
+ "python.testing.pytestPath.description": "Path to pytest. You can use a custom version of pytest by modifying this setting to include the full path.",
"python.testing.unittestArgs.description": "Arguments passed in. Each argument is a separate item in the array.",
"python.testing.unittestEnabled.description": "Enable testing using unittest.",
"python.venvFolders.description": "Folders in your home directory to look into for virtual environments (supports pyenv, direnv and virtualenvwrapper by default).",
@@ -93,7 +105,7 @@
},
"walkthrough.step.python.createPythonFolder.description": {
"message": "[Open](command:workbench.action.files.openFolder) or create a project folder.\n[Open Project Folder](command:workbench.action.files.openFolder)",
- "comment": [
+ "comment": [
"{Locked='](command:workbench.action.files.openFolder'}",
"Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
"Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
@@ -120,40 +132,29 @@
]
},
"walkthrough.step.python.selectInterpreter.title": "Select a Python Interpreter",
- "walkthrough.step.python.selectInterpreter.description": {
- "message": "Choose which Python interpreter/environment you want to use for your Python project.\n[Select Python Interpreter](command:python.setInterpreter)\n**Tip**: Run the ``Python: Select Interpreter`` command in the [Command Palette](command:workbench.action.showCommands).",
- "comment": [
- "{Locked='](command:python.setInterpreter'}",
- "{Locked='](command:workbench.action.showCommands'}",
- "Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
- "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
- ]
- },
- "walkthrough.step.python.createEnvironment.title": "Create a Python Environment ",
- "walkthrough.step.python.createEnvironment.title2": "Create or select a Python Environment ",
+ "walkthrough.step.python.createEnvironment.title": "Select or create a Python environment",
"walkthrough.step.python.createEnvironment.description": {
- "message": "Create an environment for your Python project.\n[Create Environment](command:python.createEnvironment)\n**Tip**: Run the ``Python: Create Environment`` command in the [Command Palette](command:workbench.action.showCommands).\n π Check out our [docs](https://aka.ms/pythonenvs) to learn more.",
- "comment": [
+ "message": "Create an environment for your Python project or use [Select Python Interpreter](command:python.setInterpreter) to select an existing one.\n[Create Environment](command:python.createEnvironment)\n**Tip**: Run the ``Python: Create Environment`` command in the [Command Palette](command:workbench.action.showCommands).",
+ "comment": [
"{Locked='](command:python.createEnvironment'}",
"{Locked='](command:workbench.action.showCommands'}",
+ "{Locked='](command:python.setInterpreter'}",
"Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
"Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
]
},
- "walkthrough.step.python.createEnvironment.description2": "Create an environment for your Python project or use [Select Python Interpreter](command:python.setInterpreter) to select an existing one.\n[Create Environment](command:python.createEnvironment)\n**Tip**: Run the ``Python: Create Environment`` command in the [Command Palette](command:workbench.action.showCommands).",
"walkthrough.step.python.runAndDebug.title": "Run and debug your Python file",
"walkthrough.step.python.runAndDebug.description": "Open your Python file and click on the play button on the top right of the editor, or press F5 when on the file and select \"Python File\" to run with the debugger. \n \n[Learn more](https://code.visualstudio.com/docs/python/python-tutorial#_run-hello-world)",
- "walkthrough.step.python.learnMoreWithDS.title": "Explore more resources",
+ "walkthrough.step.python.learnMoreWithDS.title": "Keep exploring!",
"walkthrough.step.python.learnMoreWithDS.description": {
- "message":"π¨ Explore all the features the Python extension has to offer by looking for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n π Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n β¨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Learn More](https://aka.ms/AA8dqti)",
- "comment":[
+ "message": "π¨ Explore all the features the Python extension has to offer by looking for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n π Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n β¨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Follow along with the Python Tutorial](https://aka.ms/AA8dqti)",
+ "comment": [
"{Locked='](command:workbench.action.showCommands'}",
"{Locked='](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D'}",
"Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for VS Code",
"Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links"
]
},
- "walkthrough.step.python.learnMoreWithDS.description2": "π¨ Explore all the features the Python extension has to offer by looking for \"Python\" in the [Command Palette](command:workbench.action.showCommands). \n π Learn more about getting started with [data science](command:workbench.action.openWalkthrough?%7B%22category%22%3A%22ms-python.python%23pythonDataScienceWelcome%22%2C%22step%22%3A%22ms-python.python%23python.createNewNotebook%22%7D) in Python. \n β¨ Take a look at our [Release Notes](https://aka.ms/AA8dxtb) to learn more about the latest features. \n \n[Follow along with the Python Tutorial](https://aka.ms/AA8dqti)",
"walkthrough.pythonDataScienceWelcome.title": "Get Started with Python for Data Science",
"walkthrough.pythonDataScienceWelcome.description": "Your first steps to getting started with a Data Science project with Python!",
"walkthrough.step.python.installJupyterExt.title": "Install Jupyter extension",
diff --git a/pythonExtensionApi/package-lock.json b/pythonExtensionApi/package-lock.json
index ef6914e0e786..e462fc1c888a 100644
--- a/pythonExtensionApi/package-lock.json
+++ b/pythonExtensionApi/package-lock.json
@@ -1,28 +1,29 @@
{
"name": "@vscode/python-extension",
- "version": "1.0.5",
+ "version": "1.0.6",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@vscode/python-extension",
- "version": "1.0.5",
+ "version": "1.0.6",
"license": "MIT",
"devDependencies": {
- "@types/vscode": "^1.78.0",
+ "@types/vscode": "^1.93.0",
"source-map": "^0.8.0-beta.0",
- "typescript": "5.0.4"
+ "typescript": "~5.2"
},
"engines": {
- "node": ">=18.17.1",
- "vscode": "^1.78.0"
+ "node": ">=22.17.0",
+ "vscode": "^1.93.0"
}
},
"node_modules/@types/vscode": {
- "version": "1.80.0",
- "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.80.0.tgz",
- "integrity": "sha512-qK/CmOdS2o7ry3k6YqU4zD3R2AYlJfbwBoSbKpBoP+GpXNE+0NEgJOli4n0bm0diK5kfBnchgCEj4igQz/44Hg==",
- "dev": true
+ "version": "1.94.0",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.94.0.tgz",
+ "integrity": "sha512-UyQOIUT0pb14XSqJskYnRwD2aG0QrPVefIfrW1djR+/J4KeFQ0i1+hjZoaAmeNf3Z2jleK+R2hv+EboG/m8ruw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/lodash.sortby": {
"version": "4.7.0",
@@ -61,16 +62,17 @@
}
},
"node_modules/typescript": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
- "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true,
+ "license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
- "node": ">=12.20"
+ "node": ">=14.17"
}
},
"node_modules/webidl-conversions": {
@@ -93,9 +95,9 @@
},
"dependencies": {
"@types/vscode": {
- "version": "1.80.0",
- "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.80.0.tgz",
- "integrity": "sha512-qK/CmOdS2o7ry3k6YqU4zD3R2AYlJfbwBoSbKpBoP+GpXNE+0NEgJOli4n0bm0diK5kfBnchgCEj4igQz/44Hg==",
+ "version": "1.94.0",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.94.0.tgz",
+ "integrity": "sha512-UyQOIUT0pb14XSqJskYnRwD2aG0QrPVefIfrW1djR+/J4KeFQ0i1+hjZoaAmeNf3Z2jleK+R2hv+EboG/m8ruw==",
"dev": true
},
"lodash.sortby": {
@@ -129,9 +131,9 @@
}
},
"typescript": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
- "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"dev": true
},
"webidl-conversions": {
diff --git a/pythonExtensionApi/package.json b/pythonExtensionApi/package.json
index 9e58f1a2400c..11e0445aa8da 100644
--- a/pythonExtensionApi/package.json
+++ b/pythonExtensionApi/package.json
@@ -1,21 +1,21 @@
{
"name": "@vscode/python-extension",
"description": "An API facade for the Python extension in VS Code",
- "version": "1.0.5",
+ "version": "1.0.6",
"author": {
- "name": "Microsoft Corporation"
+ "name": "Microsoft Corporation"
},
"keywords": [
"Python",
- "VSCode",
- "API"
- ],
- "main": "./out/main.js",
- "types": "./out/main.d.ts",
- "engines": {
- "node": ">=18.17.1",
- "vscode": "^1.78.0"
- },
+ "VSCode",
+ "API"
+ ],
+ "main": "./out/main.js",
+ "types": "./out/main.d.ts",
+ "engines": {
+ "node": ">=22.21.1",
+ "vscode": "^1.93.0"
+ },
"license": "MIT",
"homepage": "https://github.com/microsoft/vscode-python/tree/main/pythonExtensionApi",
"repository": {
@@ -26,18 +26,18 @@
"url": "https://github.com/Microsoft/vscode-python/issues"
},
"devDependencies": {
- "typescript": "5.0.4",
- "@types/vscode": "^1.78.0",
+ "typescript": "~5.2",
+ "@types/vscode": "^1.102.0",
"source-map": "^0.8.0-beta.0"
},
"scripts": {
"prepublishOnly": "echo \"β Can only publish from a secure pipeline β\" && node ../build/fail",
- "prepack": "npm run all:publish",
- "compile": "node ./node_modules/typescript/lib/tsc.js -b ./tsconfig.json",
- "clean": "node ../node_modules/rimraf/bin.js out",
- "lint": "node ../node_modules/eslint/bin/eslint.js --ext ts src",
- "all": "npm run clean && npm run compile",
+ "prepack": "npm run all:publish",
+ "compile": "node ./node_modules/typescript/lib/tsc.js -b ./tsconfig.json",
+ "clean": "node ../node_modules/rimraf/bin.js out",
+ "lint": "node ../node_modules/eslint/bin/eslint.js --ext ts src",
+ "all": "npm run clean && npm run compile",
"formatTypings": "node ../node_modules/eslint/bin/eslint.js --fix ./out/main.d.ts",
- "all:publish": "git clean -xfd . && npm install && npm run compile && npm run formatTypings"
+ "all:publish": "git clean -xfd . && npm install && npm run compile && npm run formatTypings"
}
}
diff --git a/pythonExtensionApi/src/main.ts b/pythonExtensionApi/src/main.ts
index 4de554bf5a24..2173245cbb28 100644
--- a/pythonExtensionApi/src/main.ts
+++ b/pythonExtensionApi/src/main.ts
@@ -16,7 +16,7 @@ export interface PythonExtension {
/**
* Generate an array of strings for commands to pass to the Python executable to launch the debugger for remote debugging.
* Users can append another array of strings of what they want to execute along with relevant arguments to Python.
- * E.g `['/Users/..../pythonVSCode/pythonFiles/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
+ * E.g `['/Users/..../pythonVSCode/python_files/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
* @param host
* @param port
* @param waitUntilDebuggerAttaches Defaults to `true`.
@@ -25,7 +25,6 @@ export interface PythonExtension {
/**
* Gets the path to the debugger package used by the extension.
- * @returns {Promise}
*/
getDebuggerPackagePath(): Promise;
};
@@ -228,9 +227,9 @@ export type EnvironmentsChangeEvent = {
export type ActiveEnvironmentPathChangeEvent = EnvironmentPath & {
/**
- * Workspace folder the environment changed for.
+ * Resource the environment changed for.
*/
- readonly resource: WorkspaceFolder | undefined;
+ readonly resource: Resource | undefined;
};
/**
diff --git a/pythonFiles/install_debugpy.py b/pythonFiles/install_debugpy.py
deleted file mode 100644
index 9377d00237d7..000000000000
--- a/pythonFiles/install_debugpy.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import io
-import json
-import os
-import urllib.request as url_lib
-import zipfile
-
-from packaging.version import parse as version_parser
-
-EXTENSION_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-DEBUGGER_DEST = os.path.join(EXTENSION_ROOT, "pythonFiles", "lib", "python")
-DEBUGGER_PACKAGE = "debugpy"
-DEBUGGER_PYTHON_ABI_VERSIONS = ("cp310",)
-DEBUGGER_VERSION = "1.8.0" # can also be "latest"
-
-
-def _contains(s, parts=()):
- return any(p in s for p in parts)
-
-
-def _get_package_data():
- json_uri = "https://pypi.org/pypi/{0}/json".format(DEBUGGER_PACKAGE)
- # Response format: https://warehouse.readthedocs.io/api-reference/json/#project
- # Release metadata format: https://github.com/pypa/interoperability-peps/blob/master/pep-0426-core-metadata.rst
- with url_lib.urlopen(json_uri) as response:
- return json.loads(response.read())
-
-
-def _get_debugger_wheel_urls(data, version):
- return list(
- r["url"]
- for r in data["releases"][version]
- if _contains(r["url"], DEBUGGER_PYTHON_ABI_VERSIONS)
- )
-
-
-def _download_and_extract(root, url, version):
- root = os.getcwd() if root is None or root == "." else root
- print(url)
- with url_lib.urlopen(url) as response:
- data = response.read()
- with zipfile.ZipFile(io.BytesIO(data), "r") as wheel:
- for zip_info in wheel.infolist():
- # Ignore dist info since we are merging multiple wheels
- if ".dist-info/" in zip_info.filename:
- continue
- print("\t" + zip_info.filename)
- wheel.extract(zip_info.filename, root)
-
-
-def main(root):
- data = _get_package_data()
-
- if DEBUGGER_VERSION == "latest":
- use_version = max(data["releases"].keys(), key=version_parser)
- else:
- use_version = DEBUGGER_VERSION
-
- for url in _get_debugger_wheel_urls(data, use_version):
- _download_and_extract(root, url, use_version)
-
-
-if __name__ == "__main__":
- main(DEBUGGER_DEST)
diff --git a/pythonFiles/jedilsp_requirements/requirements.in b/pythonFiles/jedilsp_requirements/requirements.in
deleted file mode 100644
index 0167b757cf7b..000000000000
--- a/pythonFiles/jedilsp_requirements/requirements.in
+++ /dev/null
@@ -1,8 +0,0 @@
-# This file is used to generate requirements.txt.
-# To update requirements.txt, run the following commands.
-# Use Python 3.8 when creating the environment or using pip-tools
-# 1) pip install pip-tools
-# 2) pip-compile --generate-hashes --upgrade pythonFiles\jedilsp_requirements\requirements.in
-
-jedi-language-server>=0.34.3
-pygls>=0.10.3
diff --git a/pythonFiles/jedilsp_requirements/requirements.txt b/pythonFiles/jedilsp_requirements/requirements.txt
deleted file mode 100644
index 889f021670bf..000000000000
--- a/pythonFiles/jedilsp_requirements/requirements.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# This file is autogenerated by pip-compile with Python 3.8
-# by the following command:
-#
-# pip-compile --generate-hashes 'pythonFiles\jedilsp_requirements\requirements.in'
-#
-attrs==23.1.0 \
- --hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \
- --hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015
- # via
- # cattrs
- # lsprotocol
-cattrs==23.1.2 \
- --hash=sha256:b2bb14311ac17bed0d58785e5a60f022e5431aca3932e3fc5cc8ed8639de50a4 \
- --hash=sha256:db1c821b8c537382b2c7c66678c3790091ca0275ac486c76f3c8f3920e83c657
- # via
- # jedi-language-server
- # lsprotocol
-docstring-to-markdown==0.12 \
- --hash=sha256:40004224b412bd6f64c0f3b85bb357a41341afd66c4b4896709efa56827fb2bb \
- --hash=sha256:7df6311a887dccf9e770f51242ec002b19f0591994c4783be49d24cdc1df3737
- # via jedi-language-server
-exceptiongroup==1.1.3 \
- --hash=sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9 \
- --hash=sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3
- # via cattrs
-importlib-metadata==6.8.0 \
- --hash=sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb \
- --hash=sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743
- # via typeguard
-jedi==0.19.1 \
- --hash=sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd \
- --hash=sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0
- # via jedi-language-server
-jedi-language-server==0.41.1 \
- --hash=sha256:3f15ca5cc28e728564f7d63583e171b418025582447ce023512e3f2b2d71ebae \
- --hash=sha256:ca9b3e7f48b70f0988d85ffde4f01dd1ab94c8e0f69e8c6424e6657117b44f91
- # via -r pythonFiles\jedilsp_requirements\requirements.in
-lsprotocol==2023.0.0b1 \
- --hash=sha256:ade2cd0fa0ede7965698cb59cd05d3adbd19178fd73e83f72ef57a032fbb9d62 \
- --hash=sha256:f7a2d4655cbd5639f373ddd1789807450c543341fa0a32b064ad30dbb9f510d4
- # via
- # jedi-language-server
- # pygls
-parso==0.8.3 \
- --hash=sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0 \
- --hash=sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75
- # via jedi
-pygls==1.0.2 \
- --hash=sha256:6d278d29fa6559b0f7a448263c85cb64ec6e9369548b02f1a7944060848b21f9 \
- --hash=sha256:888ed63d1f650b4fc64d603d73d37545386ec533c0caac921aed80f80ea946a4
- # via
- # -r pythonFiles\jedilsp_requirements\requirements.in
- # jedi-language-server
-typeguard==3.0.2 \
- --hash=sha256:bbe993854385284ab42fd5bd3bee6f6556577ce8b50696d6cb956d704f286c8e \
- --hash=sha256:fee5297fdb28f8e9efcb8142b5ee219e02375509cd77ea9d270b5af826358d5a
- # via pygls
-typing-extensions==4.8.0 \
- --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \
- --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
- # via
- # cattrs
- # jedi-language-server
- # typeguard
-zipp==3.17.0 \
- --hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
- --hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
- # via importlib-metadata
diff --git a/pythonFiles/printEnvVariablesToFile.py b/pythonFiles/printEnvVariablesToFile.py
deleted file mode 100644
index a4e0d24abbe0..000000000000
--- a/pythonFiles/printEnvVariablesToFile.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import os
-import sys
-
-# Last argument is the target file into which we'll write the env variables line by line.
-output_file = sys.argv[-1]
-
-with open(output_file, "w") as outfile:
- for key, val in os.environ.items():
- outfile.write(f"{key}={val}\n")
diff --git a/pythonFiles/pyproject.toml b/pythonFiles/pyproject.toml
deleted file mode 100644
index d865e27418e0..000000000000
--- a/pythonFiles/pyproject.toml
+++ /dev/null
@@ -1,67 +0,0 @@
-[tool.black]
-exclude = '''
-
-(
- /(
- .data
- | .vscode
- | lib
- )/
-)
-'''
-
-[tool.pyright]
-exclude = ['lib']
-extraPaths = ['lib/python', 'lib/jedilsp']
-ignore = [
- # Ignore all pre-existing code with issues
- 'get-pip.py',
- 'install_debugpy.py',
- 'tensorboard_launcher.py',
- 'testlauncher.py',
- 'visualstudio_py_testlauncher.py',
- 'testing_tools/unittest_discovery.py',
- 'testing_tools/adapter/util.py',
- 'testing_tools/adapter/pytest/_discovery.py',
- 'testing_tools/adapter/pytest/_pytest_item.py',
- 'tests/debug_adapter/test_install_debugpy.py',
- 'tests/testing_tools/adapter/.data',
- 'tests/testing_tools/adapter/test___main__.py',
- 'tests/testing_tools/adapter/test_discovery.py',
- 'tests/testing_tools/adapter/test_functional.py',
- 'tests/testing_tools/adapter/test_report.py',
- 'tests/testing_tools/adapter/test_util.py',
- 'tests/testing_tools/adapter/pytest/test_cli.py',
- 'tests/testing_tools/adapter/pytest/test_discovery.py',
-]
-
-[tool.ruff]
-line-length = 140
-ignore = ["E402"]
-exclude = [
- # Ignore testing_tools files same as Pyright way
- 'get-pip.py',
- 'install_debugpy.py',
- 'tensorboard_launcher.py',
- 'testlauncher.py',
- 'visualstudio_py_testlauncher.py',
- 'testing_tools/unittest_discovery.py',
- 'testing_tools/adapter/util.py',
- 'testing_tools/adapter/pytest/_discovery.py',
- 'testing_tools/adapter/pytest/_pytest_item.py',
- 'tests/debug_adapter/test_install_debugpy.py',
- 'tests/testing_tools/adapter/.data',
- 'tests/testing_tools/adapter/test___main__.py',
- 'tests/testing_tools/adapter/test_discovery.py',
- 'tests/testing_tools/adapter/test_functional.py',
- 'tests/testing_tools/adapter/test_report.py',
- 'tests/testing_tools/adapter/test_util.py',
- 'tests/testing_tools/adapter/pytest/test_cli.py',
- 'tests/testing_tools/adapter/pytest/test_discovery.py',
- 'pythonFiles/testing_tools/*',
- 'pythonFiles/testing_tools/adapter/pytest/__init__.py',
- 'pythonFiles/tests/pytestadapter/expected_execution_test_output.py',
- 'pythonFiles/tests/unittestadapter/.data/discovery_error/file_one.py',
- 'pythonFiles/tests/unittestadapter/test_utils.py',
-
-]
diff --git a/pythonFiles/run-jedi-language-server.py b/pythonFiles/run-jedi-language-server.py
deleted file mode 100644
index 31095121409f..000000000000
--- a/pythonFiles/run-jedi-language-server.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import sys
-import os
-
-# Add the lib path to our sys path so jedi_language_server can find its references
-EXTENSION_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-sys.path.insert(0, os.path.join(EXTENSION_ROOT, "pythonFiles", "lib", "jedilsp"))
-
-
-from jedi_language_server.cli import cli
-
-sys.exit(cli())
diff --git a/pythonFiles/testing_tools/adapter/__main__.py b/pythonFiles/testing_tools/adapter/__main__.py
deleted file mode 100644
index 218456897df6..000000000000
--- a/pythonFiles/testing_tools/adapter/__main__.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import
-
-import argparse
-import sys
-
-from . import pytest, report
-from .errors import UnsupportedCommandError, UnsupportedToolError
-
-TOOLS = {
- "pytest": {
- "_add_subparser": pytest.add_cli_subparser,
- "discover": pytest.discover,
- },
-}
-REPORTERS = {
- "discover": report.report_discovered,
-}
-
-
-def parse_args(
- # the args to parse
- argv=sys.argv[1:],
- # the program name
- prog=sys.argv[0],
-):
- """
- Return the subcommand & tool to run, along with its args.
-
- This defines the standard CLI for the different testing frameworks.
- """
- parser = argparse.ArgumentParser(
- description="Run Python testing operations.",
- prog=prog,
- # ...
- )
- cmdsubs = parser.add_subparsers(dest="cmd")
-
- # Add "run" and "debug" subcommands when ready.
- for cmdname in ["discover"]:
- sub = cmdsubs.add_parser(cmdname)
- subsubs = sub.add_subparsers(dest="tool")
- for toolname in sorted(TOOLS):
- try:
- add_subparser = TOOLS[toolname]["_add_subparser"]
- except KeyError:
- continue
- subsub = add_subparser(cmdname, toolname, subsubs)
- if cmdname == "discover":
- subsub.add_argument("--simple", action="store_true")
- subsub.add_argument(
- "--no-hide-stdio", dest="hidestdio", action="store_false"
- )
- subsub.add_argument("--pretty", action="store_true")
-
- # Parse the args!
- if "--" in argv:
- sep_index = argv.index("--")
- toolargs = argv[sep_index + 1 :]
- argv = argv[:sep_index]
- else:
- toolargs = []
- args = parser.parse_args(argv)
- ns = vars(args)
-
- cmd = ns.pop("cmd")
- if not cmd:
- parser.error("missing command")
-
- tool = ns.pop("tool")
- if not tool:
- parser.error("missing tool")
-
- return tool, cmd, ns, toolargs
-
-
-def main(
- toolname,
- cmdname,
- subargs,
- toolargs,
- # internal args (for testing):
- _tools=TOOLS,
- _reporters=REPORTERS,
-):
- try:
- tool = _tools[toolname]
- except KeyError:
- raise UnsupportedToolError(toolname)
-
- try:
- run = tool[cmdname]
- report_result = _reporters[cmdname]
- except KeyError:
- raise UnsupportedCommandError(cmdname)
-
- parents, result = run(toolargs, **subargs)
- report_result(result, parents, **subargs)
-
-
-if __name__ == "__main__":
- tool, cmd, subargs, toolargs = parse_args()
- main(tool, cmd, subargs, toolargs)
diff --git a/pythonFiles/testing_tools/adapter/discovery.py b/pythonFiles/testing_tools/adapter/discovery.py
deleted file mode 100644
index 798aea1e93f1..000000000000
--- a/pythonFiles/testing_tools/adapter/discovery.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import, print_function
-
-import re
-
-from .util import fix_fileid, DIRNAME, NORMCASE
-from .info import ParentInfo
-
-
-FILE_ID_RE = re.compile(
- r"""
- ^
- (?:
- ( .* [.] (?: py | txt ) \b ) # .txt for doctest files
- ( [^.] .* )?
- )
- $
- """,
- re.VERBOSE,
-)
-
-
-def fix_nodeid(
- nodeid,
- kind,
- rootdir=None,
- # *,
- _fix_fileid=fix_fileid,
-):
- if not nodeid:
- raise ValueError("missing nodeid")
- if nodeid == ".":
- return nodeid
-
- fileid = nodeid
- remainder = ""
- if kind not in ("folder", "file"):
- m = FILE_ID_RE.match(nodeid)
- if m:
- fileid, remainder = m.groups()
- elif len(nodeid) > 1:
- fileid = nodeid[:2]
- remainder = nodeid[2:]
- fileid = _fix_fileid(fileid, rootdir)
- return fileid + (remainder or "")
-
-
-class DiscoveredTests(object):
- """A container for the discovered tests and their parents."""
-
- def __init__(self):
- self.reset()
-
- def __len__(self):
- return len(self._tests)
-
- def __getitem__(self, index):
- return self._tests[index]
-
- @property
- def parents(self):
- return sorted(
- self._parents.values(),
- # Sort by (name, id).
- key=lambda p: (NORMCASE(p.root or p.name), p.id),
- )
-
- def reset(self):
- """Clear out any previously discovered tests."""
- self._parents = {}
- self._tests = []
-
- def add_test(self, test, parents):
- """Add the given test and its parents."""
- parentid = self._ensure_parent(test.path, parents)
- # Updating the parent ID and the test ID aren't necessary if the
- # provided test and parents (from the test collector) are
- # properly generated. However, we play it safe here.
- test = test._replace(
- # Clean up the ID.
- id=fix_nodeid(test.id, "test", test.path.root),
- parentid=parentid,
- )
- self._tests.append(test)
-
- def _ensure_parent(
- self,
- path,
- parents,
- # *,
- _dirname=DIRNAME,
- ):
- rootdir = path.root
- relpath = path.relfile
-
- _parents = iter(parents)
- nodeid, name, kind = next(_parents)
- # As in add_test(), the node ID *should* already be correct.
- nodeid = fix_nodeid(nodeid, kind, rootdir)
- _parentid = nodeid
- for parentid, parentname, parentkind in _parents:
- # As in add_test(), the parent ID *should* already be correct.
- parentid = fix_nodeid(parentid, kind, rootdir)
- if kind in ("folder", "file"):
- info = ParentInfo(nodeid, kind, name, rootdir, relpath, parentid)
- relpath = _dirname(relpath)
- else:
- info = ParentInfo(nodeid, kind, name, rootdir, None, parentid)
- self._parents[(rootdir, nodeid)] = info
- nodeid, name, kind = parentid, parentname, parentkind
- assert nodeid == "."
- info = ParentInfo(nodeid, kind, name=rootdir)
- self._parents[(rootdir, nodeid)] = info
-
- return _parentid
diff --git a/pythonFiles/testing_tools/adapter/errors.py b/pythonFiles/testing_tools/adapter/errors.py
deleted file mode 100644
index 3e6ae5189cb8..000000000000
--- a/pythonFiles/testing_tools/adapter/errors.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-
-class UnsupportedToolError(ValueError):
- def __init__(self, tool):
- msg = "unsupported tool {!r}".format(tool)
- super(UnsupportedToolError, self).__init__(msg)
- self.tool = tool
-
-
-class UnsupportedCommandError(ValueError):
- def __init__(self, cmd):
- msg = "unsupported cmd {!r}".format(cmd)
- super(UnsupportedCommandError, self).__init__(msg)
- self.cmd = cmd
diff --git a/pythonFiles/testing_tools/adapter/info.py b/pythonFiles/testing_tools/adapter/info.py
deleted file mode 100644
index d518a29dd97a..000000000000
--- a/pythonFiles/testing_tools/adapter/info.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from collections import namedtuple
-
-
-class SingleTestPath(namedtuple("TestPath", "root relfile func sub")):
- """Where to find a single test."""
-
- def __new__(cls, root, relfile, func, sub=None):
- self = super(SingleTestPath, cls).__new__(
- cls,
- str(root) if root else None,
- str(relfile) if relfile else None,
- str(func) if func else None,
- [str(s) for s in sub] if sub else None,
- )
- return self
-
- def __init__(self, *args, **kwargs):
- if self.root is None:
- raise TypeError("missing id")
- if self.relfile is None:
- raise TypeError("missing kind")
- # self.func may be None (e.g. for doctests).
- # self.sub may be None.
-
-
-class ParentInfo(namedtuple("ParentInfo", "id kind name root relpath parentid")):
- KINDS = ("folder", "file", "suite", "function", "subtest")
-
- def __new__(cls, id, kind, name, root=None, relpath=None, parentid=None):
- self = super(ParentInfo, cls).__new__(
- cls,
- id=str(id) if id else None,
- kind=str(kind) if kind else None,
- name=str(name) if name else None,
- root=str(root) if root else None,
- relpath=str(relpath) if relpath else None,
- parentid=str(parentid) if parentid else None,
- )
- return self
-
- def __init__(self, *args, **kwargs):
- if self.id is None:
- raise TypeError("missing id")
- if self.kind is None:
- raise TypeError("missing kind")
- if self.kind not in self.KINDS:
- raise ValueError("unsupported kind {!r}".format(self.kind))
- if self.name is None:
- raise TypeError("missing name")
- if self.root is None:
- if self.parentid is not None or self.kind != "folder":
- raise TypeError("missing root")
- if self.relpath is not None:
- raise TypeError("unexpected relpath {}".format(self.relpath))
- elif self.parentid is None:
- raise TypeError("missing parentid")
- elif self.relpath is None and self.kind in ("folder", "file"):
- raise TypeError("missing relpath")
-
-
-class SingleTestInfo(
- namedtuple("TestInfo", "id name path source markers parentid kind")
-):
- """Info for a single test."""
-
- MARKERS = ("skip", "skip-if", "expected-failure")
- KINDS = ("function", "doctest")
-
- def __new__(cls, id, name, path, source, markers, parentid, kind="function"):
- self = super(SingleTestInfo, cls).__new__(
- cls,
- str(id) if id else None,
- str(name) if name else None,
- path or None,
- str(source) if source else None,
- [str(marker) for marker in markers or ()],
- str(parentid) if parentid else None,
- str(kind) if kind else None,
- )
- return self
-
- def __init__(self, *args, **kwargs):
- if self.id is None:
- raise TypeError("missing id")
- if self.name is None:
- raise TypeError("missing name")
- if self.path is None:
- raise TypeError("missing path")
- if self.source is None:
- raise TypeError("missing source")
- else:
- srcfile, _, lineno = self.source.rpartition(":")
- if not srcfile or not lineno or int(lineno) < 0:
- raise ValueError("bad source {!r}".format(self.source))
- if self.markers:
- badmarkers = [m for m in self.markers if m not in self.MARKERS]
- if badmarkers:
- raise ValueError("unsupported markers {!r}".format(badmarkers))
- if self.parentid is None:
- raise TypeError("missing parentid")
- if self.kind is None:
- raise TypeError("missing kind")
- elif self.kind not in self.KINDS:
- raise ValueError("unsupported kind {!r}".format(self.kind))
-
- @property
- def root(self):
- return self.path.root
-
- @property
- def srcfile(self):
- return self.source.rpartition(":")[0]
-
- @property
- def lineno(self):
- return int(self.source.rpartition(":")[-1])
diff --git a/pythonFiles/testing_tools/adapter/pytest/__init__.py b/pythonFiles/testing_tools/adapter/pytest/__init__.py
deleted file mode 100644
index 89b7c066a459..000000000000
--- a/pythonFiles/testing_tools/adapter/pytest/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import
-
-from ._cli import add_subparser as add_cli_subparser # noqa: F401
-from ._discovery import discover # noqa: F401
diff --git a/pythonFiles/testing_tools/adapter/pytest/_cli.py b/pythonFiles/testing_tools/adapter/pytest/_cli.py
deleted file mode 100644
index 3d3eec09a199..000000000000
--- a/pythonFiles/testing_tools/adapter/pytest/_cli.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import
-
-from ..errors import UnsupportedCommandError
-
-
-def add_subparser(cmd, name, parent):
- """Add a new subparser to the given parent and add args to it."""
- parser = parent.add_parser(name)
- if cmd == "discover":
- # For now we don't have any tool-specific CLI options to add.
- pass
- else:
- raise UnsupportedCommandError(cmd)
- return parser
diff --git a/pythonFiles/testing_tools/adapter/pytest/_discovery.py b/pythonFiles/testing_tools/adapter/pytest/_discovery.py
deleted file mode 100644
index 4b852ecf81c9..000000000000
--- a/pythonFiles/testing_tools/adapter/pytest/_discovery.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import, print_function
-
-import sys
-
-import pytest
-
-from .. import discovery, util
-from ._pytest_item import parse_item
-
-
-def discover(
- pytestargs=None,
- hidestdio=False,
- # *,
- _pytest_main=pytest.main,
- _plugin=None,
- **_ignored
-):
- """Return the results of test discovery."""
- if _plugin is None:
- _plugin = TestCollector()
-
- pytestargs = _adjust_pytest_args(pytestargs)
- # We use this helper rather than "-pno:terminal" due to possible
- # platform-dependent issues.
- with util.hide_stdio() if hidestdio else util.noop_cm() as stdio:
- ec = _pytest_main(pytestargs, [_plugin])
- # See: https://docs.pytest.org/en/latest/usage.html#possible-exit-codes
- if ec == 5:
- # No tests were discovered.
- pass
- elif ec == 1:
- # Some tests where collected but with errors.
- pass
- elif ec != 0:
- print(
- "equivalent command: {} -m pytest {}".format(
- sys.executable, util.shlex_unsplit(pytestargs)
- )
- )
- if hidestdio:
- print(stdio.getvalue(), file=sys.stderr)
- sys.stdout.flush()
- raise Exception("pytest discovery failed (exit code {})".format(ec))
- if not _plugin._started:
- print(
- "equivalent command: {} -m pytest {}".format(
- sys.executable, util.shlex_unsplit(pytestargs)
- )
- )
- if hidestdio:
- print(stdio.getvalue(), file=sys.stderr)
- sys.stdout.flush()
- raise Exception("pytest discovery did not start")
- return (
- _plugin._tests.parents,
- list(_plugin._tests),
- )
-
-
-def _adjust_pytest_args(pytestargs):
- """Return a corrected copy of the given pytest CLI args."""
- pytestargs = list(pytestargs) if pytestargs else []
- # Duplicate entries should be okay.
- pytestargs.insert(0, "--collect-only")
- # TODO: pull in code from:
- # src/client/testing/pytest/services/discoveryService.ts
- # src/client/testing/pytest/services/argsService.ts
- return pytestargs
-
-
-class TestCollector(object):
- """This is a pytest plugin that collects the discovered tests."""
-
- @classmethod
- def parse_item(cls, item):
- return parse_item(item)
-
- def __init__(self, tests=None):
- if tests is None:
- tests = discovery.DiscoveredTests()
- self._tests = tests
- self._started = False
-
- # Relevant plugin hooks:
- # https://docs.pytest.org/en/latest/reference.html#collection-hooks
-
- def pytest_collection_modifyitems(self, session, config, items):
- self._started = True
- self._tests.reset()
- for item in items:
- test, parents = self.parse_item(item)
- if test is not None:
- self._tests.add_test(test, parents)
-
- # This hook is not specified in the docs, so we also provide
- # the "modifyitems" hook just in case.
- def pytest_collection_finish(self, session):
- self._started = True
- try:
- items = session.items
- except AttributeError:
- # TODO: Is there an alternative?
- return
- self._tests.reset()
- for item in items:
- test, parents = self.parse_item(item)
- if test is not None:
- self._tests.add_test(test, parents)
diff --git a/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py b/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py
deleted file mode 100644
index ccfe14122316..000000000000
--- a/pythonFiles/testing_tools/adapter/pytest/_pytest_item.py
+++ /dev/null
@@ -1,610 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-"""
-During "collection", pytest finds all the tests it supports. These are
-called "items". The process is top-down, mostly tracing down through
-the file system. Aside from its own machinery, pytest supports hooks
-that find tests. Effectively, pytest starts with a set of "collectors";
-objects that can provide a list of tests and sub-collectors. All
-collectors in the resulting tree are visited and the tests aggregated.
-For the most part, each test's (and collector's) parent is identified
-as the collector that collected it.
-
-Collectors and items are collectively identified as "nodes". The pytest
-API relies on collector and item objects providing specific methods and
-attributes. In addition to corresponding base classes, pytest provides
-a number of concrete implementations.
-
-The following are the known pytest node types:
-
- Node
- Collector
- FSCollector
- Session (the top-level collector)
- File
- Module
- Package
- DoctestTextfile
- DoctestModule
- PyCollector
- (Module)
- (...)
- Class
- UnitTestCase
- Instance
- Item
- Function
- TestCaseFunction
- DoctestItem
-
-Here are the unique attrs for those classes:
-
- Node
- name
- nodeid (readonly)
- config
- session
- (parent) - the parent node
- (fspath) - the file from which the node was collected
- ----
- own_marksers - explicit markers (e.g. with @pytest.mark())
- keywords
- extra_keyword_matches
-
- Item
- location - where the actual test source code is: (relfspath, lno, fullname)
- user_properties
-
- PyCollector
- module
- class
- instance
- obj
-
- Function
- module
- class
- instance
- obj
- function
- (callspec)
- (fixturenames)
- funcargs
- originalname - w/o decorations, e.g. [...] for parameterized
-
- DoctestItem
- dtest
- obj
-
-When parsing an item, we make use of the following attributes:
-
-* name
-* nodeid
-* __class__
- + __name__
-* fspath
-* location
-* function
- + __name__
- + __code__
- + __closure__
-* own_markers
-"""
-
-from __future__ import absolute_import, print_function
-
-import sys
-
-import _pytest.doctest
-import _pytest.unittest
-import pytest
-
-from ..info import SingleTestInfo, SingleTestPath
-from ..util import NORMCASE, PATH_SEP, fix_fileid
-
-
-def should_never_reach_here(item, **extra):
- """Indicates a code path we should never reach."""
- print("The Python extension has run into an unexpected situation")
- print("while processing a pytest node during test discovery. Please")
- print("Please open an issue at:")
- print(" https://github.com/microsoft/vscode-python/issues")
- print("and paste the following output there.")
- print()
- for field, info in _summarize_item(item):
- print("{}: {}".format(field, info))
- if extra:
- print()
- print("extra info:")
- for name, info in extra.items():
- print("{:10}".format(name + ":"), end="")
- if isinstance(info, str):
- print(info)
- else:
- try:
- print(*info)
- except TypeError:
- print(info)
- print()
- print("traceback:")
- import traceback
-
- traceback.print_stack()
-
- msg = "Unexpected pytest node (see printed output)."
- exc = NotImplementedError(msg)
- exc.item = item
- return exc
-
-
-def parse_item(
- item,
- # *,
- _get_item_kind=(lambda *a: _get_item_kind(*a)),
- _parse_node_id=(lambda *a: _parse_node_id(*a)),
- _split_fspath=(lambda *a: _split_fspath(*a)),
- _get_location=(lambda *a: _get_location(*a)),
-):
- """Return (TestInfo, [suite ID]) for the given item.
-
- The suite IDs, if any, are in parent order with the item's direct
- parent at the beginning. The parent of the last suite ID (or of
- the test if there are no suites) is the file ID, which corresponds
- to TestInfo.path.
-
- """
- # _debug_item(item, showsummary=True)
- kind, _ = _get_item_kind(item)
- # Skip plugin generated tests
- if kind is None:
- return None, None
-
- if kind == "function" and item.originalname and item.originalname != item.name:
- # split out parametrized decorations `node[params]`) before parsing
- # and manually attach parametrized portion back in when done.
- parameterized = item.name[len(item.originalname) :]
- (parentid, parents, fileid, testfunc, _) = _parse_node_id(
- item.nodeid[: -len(parameterized)], kind
- )
- nodeid = "{}{}".format(parentid, parameterized)
- parents = [(parentid, item.originalname, kind)] + parents
- name = parameterized[1:-1] or ""
- else:
- (nodeid, parents, fileid, testfunc, parameterized) = _parse_node_id(
- item.nodeid, kind
- )
- name = item.name
-
- # Note: testfunc does not necessarily match item.function.__name__.
- # This can result from importing a test function from another module.
-
- # Figure out the file.
- testroot, relfile = _split_fspath(str(item.fspath), fileid, item)
- location, fullname = _get_location(item, testroot, relfile)
- if kind == "function":
- if testfunc and fullname != testfunc + parameterized:
- raise should_never_reach_here(
- item,
- fullname=fullname,
- testfunc=testfunc,
- parameterized=parameterized,
- # ...
- )
- elif kind == "doctest":
- if testfunc and fullname != testfunc and fullname != "[doctest] " + testfunc:
- raise should_never_reach_here(
- item,
- fullname=fullname,
- testfunc=testfunc,
- # ...
- )
- testfunc = None
-
- # Sort out the parent.
- if parents:
- parentid, _, _ = parents[0]
- else:
- parentid = None
-
- # Sort out markers.
- # See: https://docs.pytest.org/en/latest/reference.html#marks
- markers = set()
- for marker in getattr(item, "own_markers", []):
- if marker.name == "parameterize":
- # We've already covered these.
- continue
- elif marker.name == "skip":
- markers.add("skip")
- elif marker.name == "skipif":
- markers.add("skip-if")
- elif marker.name == "xfail":
- markers.add("expected-failure")
- # We can add support for other markers as we need them?
-
- test = SingleTestInfo(
- id=nodeid,
- name=name,
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func=testfunc,
- sub=[parameterized] if parameterized else None,
- ),
- source=location,
- markers=sorted(markers) if markers else None,
- parentid=parentid,
- )
- if parents and parents[-1] == (".", None, "folder"): # This should always be true?
- parents[-1] = (".", testroot, "folder")
- return test, parents
-
-
-def _split_fspath(
- fspath,
- fileid,
- item,
- # *,
- _normcase=NORMCASE,
-):
- """Return (testroot, relfile) for the given fspath.
-
- "relfile" will match "fileid".
- """
- # "fileid" comes from nodeid and is always relative to the testroot
- # (with a "./" prefix). There are no guarantees about casing, so we
- # normcase just be to sure.
- relsuffix = fileid[1:] # Drop (only) the "." prefix.
- if not _normcase(fspath).endswith(_normcase(relsuffix)):
- raise should_never_reach_here(
- item,
- fspath=fspath,
- fileid=fileid,
- # ...
- )
- testroot = fspath[: -len(fileid) + 1] # Ignore the "./" prefix.
- relfile = "." + fspath[-len(fileid) + 1 :] # Keep the pathsep.
- return testroot, relfile
-
-
-def _get_location(
- item,
- testroot,
- relfile,
- # *,
- _matches_relfile=(lambda *a: _matches_relfile(*a)),
- _is_legacy_wrapper=(lambda *a: _is_legacy_wrapper(*a)),
- _unwrap_decorator=(lambda *a: _unwrap_decorator(*a)),
- _pathsep=PATH_SEP,
-):
- """Return (loc str, fullname) for the given item."""
- # When it comes to normcase, we favor relfile (from item.fspath)
- # over item.location in this function.
-
- srcfile, lineno, fullname = item.location
- if _matches_relfile(srcfile, testroot, relfile):
- srcfile = relfile
- else:
- # pytest supports discovery of tests imported from other
- # modules. This is reflected by a different filename
- # in item.location.
-
- if _is_legacy_wrapper(srcfile):
- srcfile = relfile
- unwrapped = _unwrap_decorator(item.function)
- if unwrapped is None:
- # It was an invalid legacy wrapper so we just say
- # "somewhere in relfile".
- lineno = None
- else:
- _srcfile, lineno = unwrapped
- if not _matches_relfile(_srcfile, testroot, relfile):
- # For legacy wrappers we really expect the wrapped
- # function to be in relfile. So here we ignore any
- # other file and just say "somewhere in relfile".
- lineno = None
- elif _matches_relfile(srcfile, testroot, relfile):
- srcfile = relfile
- # Otherwise we just return the info from item.location as-is.
-
- if not srcfile.startswith("." + _pathsep):
- srcfile = "." + _pathsep + srcfile
-
- if lineno is None:
- lineno = -1 # i.e. "unknown"
-
- # from pytest, line numbers are 0-based
- location = "{}:{}".format(srcfile, int(lineno) + 1)
- return location, fullname
-
-
-def _matches_relfile(
- srcfile,
- testroot,
- relfile,
- # *,
- _normcase=NORMCASE,
- _pathsep=PATH_SEP,
-):
- """Return True if "srcfile" matches the given relfile."""
- testroot = _normcase(testroot)
- srcfile = _normcase(srcfile)
- relfile = _normcase(relfile)
- if srcfile == relfile:
- return True
- elif srcfile == relfile[len(_pathsep) + 1 :]:
- return True
- elif srcfile == testroot + relfile[1:]:
- return True
- else:
- return False
-
-
-def _is_legacy_wrapper(
- srcfile,
- # *,
- _pathsep=PATH_SEP,
- _pyversion=sys.version_info,
-):
- """Return True if the test might be wrapped.
-
- In Python 2 unittest's decorators (e.g. unittest.skip) do not wrap
- properly, so we must manually unwrap them.
- """
- if _pyversion > (3,):
- return False
- if (_pathsep + "unittest" + _pathsep + "case.py") not in srcfile:
- return False
- return True
-
-
-def _unwrap_decorator(func):
- """Return (filename, lineno) for the func the given func wraps.
-
- If the wrapped func cannot be identified then return None. Likewise
- for the wrapped filename. "lineno" is None if it cannot be found
- but the filename could.
- """
- try:
- func = func.__closure__[0].cell_contents
- except (IndexError, AttributeError):
- return None
- else:
- if not callable(func):
- return None
- try:
- filename = func.__code__.co_filename
- except AttributeError:
- return None
- else:
- try:
- lineno = func.__code__.co_firstlineno - 1
- except AttributeError:
- return (filename, None)
- else:
- return filename, lineno
-
-
-def _parse_node_id(
- testid,
- kind,
- # *,
- _iter_nodes=(lambda *a: _iter_nodes(*a)),
-):
- """Return the components of the given node ID, in heirarchical order."""
- nodes = iter(_iter_nodes(testid, kind))
-
- testid, name, kind = next(nodes)
- parents = []
- parameterized = None
- if kind == "doctest":
- parents = list(nodes)
- fileid, _, _ = parents[0]
- return testid, parents, fileid, name, parameterized
- elif kind is None:
- fullname = None
- else:
- if kind == "subtest":
- node = next(nodes)
- parents.append(node)
- funcid, funcname, _ = node
- parameterized = testid[len(funcid) :]
- elif kind == "function":
- funcname = name
- else:
- raise should_never_reach_here(
- testid,
- kind=kind,
- # ...
- )
- fullname = funcname
-
- for node in nodes:
- parents.append(node)
- parentid, name, kind = node
- if kind == "file":
- fileid = parentid
- break
- elif fullname is None:
- # We don't guess how to interpret the node ID for these tests.
- continue
- elif kind == "suite":
- fullname = name + "." + fullname
- else:
- raise should_never_reach_here(
- testid,
- node=node,
- # ...
- )
- else:
- fileid = None
- parents.extend(nodes) # Add the rest in as-is.
-
- return (
- testid,
- parents,
- fileid,
- fullname,
- parameterized or "",
- )
-
-
-def _iter_nodes(
- testid,
- kind,
- # *,
- _normalize_test_id=(lambda *a: _normalize_test_id(*a)),
- _normcase=NORMCASE,
- _pathsep=PATH_SEP,
-):
- """Yield (nodeid, name, kind) for the given node ID and its parents."""
- nodeid, testid = _normalize_test_id(testid, kind)
- if len(nodeid) > len(testid):
- testid = "." + _pathsep + testid
-
- parentid, _, name = nodeid.rpartition("::")
- if not parentid:
- if kind is None:
- # This assumes that plugins can generate nodes that do not
- # have a parent. All the builtin nodes have one.
- yield (nodeid, name, kind)
- return
- # We expect at least a filename and a name.
- raise should_never_reach_here(
- nodeid,
- # ...
- )
- yield (nodeid, name, kind)
-
- # Extract the suites.
- while "::" in parentid:
- suiteid = parentid
- parentid, _, name = parentid.rpartition("::")
- yield (suiteid, name, "suite")
-
- # Extract the file and folders.
- fileid = parentid
- raw = testid[: len(fileid)]
- _parentid, _, filename = _normcase(fileid).rpartition(_pathsep)
- parentid = fileid[: len(_parentid)]
- raw, name = raw[: len(_parentid)], raw[-len(filename) :]
- yield (fileid, name, "file")
- # We're guaranteed at least one (the test root).
- while _pathsep in _normcase(parentid):
- folderid = parentid
- _parentid, _, foldername = _normcase(folderid).rpartition(_pathsep)
- parentid = folderid[: len(_parentid)]
- raw, name = raw[: len(parentid)], raw[-len(foldername) :]
- yield (folderid, name, "folder")
- # We set the actual test root later at the bottom of parse_item().
- testroot = None
- yield (parentid, testroot, "folder")
-
-
-def _normalize_test_id(
- testid,
- kind,
- # *,
- _fix_fileid=fix_fileid,
- _pathsep=PATH_SEP,
-):
- """Return the canonical form for the given node ID."""
- while "::()::" in testid:
- testid = testid.replace("::()::", "::")
- while ":::" in testid:
- testid = testid.replace(":::", "::")
- if kind is None:
- return testid, testid
- orig = testid
-
- # We need to keep the testid as-is, or else pytest won't recognize
- # it when we try to use it later (e.g. to run a test). The only
- # exception is that we add a "./" prefix for relative paths.
- # Note that pytest always uses "/" as the path separator in IDs.
- fileid, sep, remainder = testid.partition("::")
- fileid = _fix_fileid(fileid)
- if not fileid.startswith("./"): # Absolute "paths" not expected.
- raise should_never_reach_here(
- testid,
- fileid=fileid,
- # ...
- )
- testid = fileid + sep + remainder
-
- return testid, orig
-
-
-def _get_item_kind(item):
- """Return (kind, isunittest) for the given item."""
- if isinstance(item, _pytest.doctest.DoctestItem):
- return "doctest", False
- elif isinstance(item, _pytest.unittest.TestCaseFunction):
- return "function", True
- elif isinstance(item, pytest.Function):
- # We *could* be more specific, e.g. "method", "subtest".
- return "function", False
- else:
- return None, False
-
-
-#############################
-# useful for debugging
-
-_FIELDS = [
- "nodeid",
- "kind",
- "class",
- "name",
- "fspath",
- "location",
- "function",
- "markers",
- "user_properties",
- "attrnames",
-]
-
-
-def _summarize_item(item):
- if not hasattr(item, "nodeid"):
- yield "nodeid", item
- return
-
- for field in _FIELDS:
- try:
- if field == "kind":
- yield field, _get_item_kind(item)
- elif field == "class":
- yield field, item.__class__.__name__
- elif field == "markers":
- yield field, item.own_markers
- # yield field, list(item.iter_markers())
- elif field == "attrnames":
- yield field, dir(item)
- else:
- yield field, getattr(item, field, "??>")
- except Exception as exc:
- yield field, "".format(exc)
-
-
-def _debug_item(item, showsummary=False):
- item._debugging = True
- try:
- summary = dict(_summarize_item(item))
- finally:
- item._debugging = False
-
- if showsummary:
- print(item.nodeid)
- for key in (
- "kind",
- "class",
- "name",
- "fspath",
- "location",
- "func",
- "markers",
- "props",
- ):
- print(" {:12} {}".format(key, summary[key]))
- print()
-
- return summary
diff --git a/pythonFiles/testing_tools/adapter/report.py b/pythonFiles/testing_tools/adapter/report.py
deleted file mode 100644
index bacdef7b9a00..000000000000
--- a/pythonFiles/testing_tools/adapter/report.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import print_function
-
-import json
-
-
-def report_discovered(
- tests,
- parents,
- # *,
- pretty=False,
- simple=False,
- _send=print,
- **_ignored
-):
- """Serialize the discovered tests and write to stdout."""
- if simple:
- data = [
- {
- "id": test.id,
- "name": test.name,
- "testroot": test.path.root,
- "relfile": test.path.relfile,
- "lineno": test.lineno,
- "testfunc": test.path.func,
- "subtest": test.path.sub or None,
- "markers": test.markers or [],
- }
- for test in tests
- ]
- else:
- byroot = {}
- for parent in parents:
- rootdir = parent.name if parent.root is None else parent.root
- try:
- root = byroot[rootdir]
- except KeyError:
- root = byroot[rootdir] = {
- "id": rootdir,
- "parents": [],
- "tests": [],
- }
- if not parent.root:
- root["id"] = parent.id
- continue
- root["parents"].append(
- {
- # "id" must match what the testing framework recognizes.
- "id": parent.id,
- "kind": parent.kind,
- "name": parent.name,
- "parentid": parent.parentid,
- }
- )
- if parent.relpath is not None:
- root["parents"][-1]["relpath"] = parent.relpath
- for test in tests:
- # We are guaranteed that the parent was added.
- root = byroot[test.path.root]
- testdata = {
- # "id" must match what the testing framework recognizes.
- "id": test.id,
- "name": test.name,
- # TODO: Add a "kind" field
- # (e.g. "unittest", "function", "doctest")
- "source": test.source,
- "markers": test.markers or [],
- "parentid": test.parentid,
- }
- root["tests"].append(testdata)
- data = [
- {
- "rootid": byroot[root]["id"],
- "root": root,
- "parents": byroot[root]["parents"],
- "tests": byroot[root]["tests"],
- }
- for root in sorted(byroot)
- ]
-
- kwargs = {}
- if pretty:
- # human-formatted
- kwargs = dict(
- sort_keys=True,
- indent=4,
- separators=(",", ": "),
- # ...
- )
- serialized = json.dumps(data, **kwargs)
-
- _send(serialized)
diff --git a/pythonFiles/testing_tools/adapter/util.py b/pythonFiles/testing_tools/adapter/util.py
deleted file mode 100644
index c7a178311b8b..000000000000
--- a/pythonFiles/testing_tools/adapter/util.py
+++ /dev/null
@@ -1,289 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import contextlib
-import io
-
-try:
- from io import StringIO
-except ImportError:
- from StringIO import StringIO # 2.7
-
-import os
-import os.path
-import sys
-import tempfile
-
-
-@contextlib.contextmanager
-def noop_cm():
- yield
-
-
-def group_attr_names(attrnames):
- grouped = {
- "dunder": [],
- "private": [],
- "constants": [],
- "classes": [],
- "vars": [],
- "other": [],
- }
- for name in attrnames:
- if name.startswith("__") and name.endswith("__"):
- group = "dunder"
- elif name.startswith("_"):
- group = "private"
- elif name.isupper():
- group = "constants"
- elif name.islower():
- group = "vars"
- elif name == name.capitalize():
- group = "classes"
- else:
- group = "other"
- grouped[group].append(name)
- return grouped
-
-
-if sys.version_info < (3,):
- _str_to_lower = lambda val: val.decode().lower()
-else:
- _str_to_lower = str.lower
-
-
-#############################
-# file paths
-
-_os_path = os.path
-# Uncomment to test Windows behavior on non-windows OS:
-# import ntpath as _os_path
-PATH_SEP = _os_path.sep
-NORMCASE = _os_path.normcase
-DIRNAME = _os_path.dirname
-BASENAME = _os_path.basename
-IS_ABS_PATH = _os_path.isabs
-PATH_JOIN = _os_path.join
-ABS_PATH = _os_path.abspath
-
-
-def fix_path(
- path,
- # *,
- _pathsep=PATH_SEP,
-):
- """Return a platform-appropriate path for the given path."""
- if not path:
- return "."
- return path.replace("/", _pathsep)
-
-
-def fix_relpath(
- path,
- # *,
- _fix_path=fix_path,
- _path_isabs=IS_ABS_PATH,
- _pathsep=PATH_SEP,
-):
- """Return a ./-prefixed, platform-appropriate path for the given path."""
- path = _fix_path(path)
- if path in (".", ".."):
- return path
- if not _path_isabs(path):
- if not path.startswith("." + _pathsep):
- path = "." + _pathsep + path
- return path
-
-
-def _resolve_relpath(
- path,
- rootdir=None,
- # *,
- _path_isabs=IS_ABS_PATH,
- _normcase=NORMCASE,
- _pathsep=PATH_SEP,
-):
- # "path" is expected to use "/" for its path separator, regardless
- # of the provided "_pathsep".
-
- if path.startswith("./"):
- return path[2:]
- if not _path_isabs(path):
- return path
-
- # Deal with root-dir-as-fileid.
- _, sep, relpath = path.partition("/")
- if sep and not relpath.replace("/", ""):
- return ""
-
- if rootdir is None:
- return None
- rootdir = _normcase(rootdir)
- if not rootdir.endswith(_pathsep):
- rootdir += _pathsep
-
- if not _normcase(path).startswith(rootdir):
- return None
- return path[len(rootdir) :]
-
-
-def fix_fileid(
- fileid,
- rootdir=None,
- # *,
- normalize=False,
- strictpathsep=None,
- _pathsep=PATH_SEP,
- **kwargs
-):
- """Return a pathsep-separated file ID ("./"-prefixed) for the given value.
-
- The file ID may be absolute. If so and "rootdir" is
- provided then make the file ID relative. If absolute but "rootdir"
- is not provided then leave it absolute.
- """
- if not fileid or fileid == ".":
- return fileid
-
- # We default to "/" (forward slash) as the final path sep, since
- # that gives us a consistent, cross-platform result. (Windows does
- # actually support "/" as a path separator.) Most notably, node IDs
- # from pytest use "/" as the path separator by default.
- _fileid = fileid.replace(_pathsep, "/")
-
- relpath = _resolve_relpath(
- _fileid,
- rootdir,
- _pathsep=_pathsep,
- # ...
- **kwargs
- )
- if relpath: # Note that we treat "" here as an absolute path.
- _fileid = "./" + relpath
-
- if normalize:
- if strictpathsep:
- raise ValueError("cannot normalize *and* keep strict path separator")
- _fileid = _str_to_lower(_fileid)
- elif strictpathsep:
- # We do not use _normcase since we want to preserve capitalization.
- _fileid = _fileid.replace("/", _pathsep)
- return _fileid
-
-
-#############################
-# stdio
-
-
-@contextlib.contextmanager
-def _replace_fd(file, target):
- """
- Temporarily replace the file descriptor for `file`,
- for which sys.stdout or sys.stderr is passed.
- """
- try:
- fd = file.fileno()
- except (AttributeError, io.UnsupportedOperation):
- # `file` does not have fileno() so it's been replaced from the
- # default sys.stdout, etc. Return with noop.
- yield
- return
- target_fd = target.fileno()
-
- # Keep the original FD to be restored in the finally clause.
- dup_fd = os.dup(fd)
- try:
- # Point the FD at the target.
- os.dup2(target_fd, fd)
- try:
- yield
- finally:
- # Point the FD back at the original.
- os.dup2(dup_fd, fd)
- finally:
- os.close(dup_fd)
-
-
-@contextlib.contextmanager
-def _replace_stdout(target):
- orig = sys.stdout
- sys.stdout = target
- try:
- yield orig
- finally:
- sys.stdout = orig
-
-
-@contextlib.contextmanager
-def _replace_stderr(target):
- orig = sys.stderr
- sys.stderr = target
- try:
- yield orig
- finally:
- sys.stderr = orig
-
-
-if sys.version_info < (3,):
- _coerce_unicode = lambda s: unicode(s)
-else:
- _coerce_unicode = lambda s: s
-
-
-@contextlib.contextmanager
-def _temp_io():
- sio = StringIO()
- with tempfile.TemporaryFile("r+") as tmp:
- try:
- yield sio, tmp
- finally:
- tmp.seek(0)
- buff = tmp.read()
- sio.write(_coerce_unicode(buff))
-
-
-@contextlib.contextmanager
-def hide_stdio():
- """Swallow stdout and stderr."""
- with _temp_io() as (sio, fileobj):
- with _replace_fd(sys.stdout, fileobj):
- with _replace_stdout(fileobj):
- with _replace_fd(sys.stderr, fileobj):
- with _replace_stderr(fileobj):
- yield sio
-
-
-#############################
-# shell
-
-
-def shlex_unsplit(argv):
- """Return the shell-safe string for the given arguments.
-
- This effectively the equivalent of reversing shlex.split().
- """
- argv = [_quote_arg(a) for a in argv]
- return " ".join(argv)
-
-
-try:
- from shlex import quote as _quote_arg
-except ImportError:
-
- def _quote_arg(arg):
- parts = None
- for i, c in enumerate(arg):
- if c.isspace():
- pass
- elif c == '"':
- pass
- elif c == "'":
- c = "'\"'\"'"
- else:
- continue
- if parts is None:
- parts = list(arg)
- parts[i] = c
- if parts is not None:
- arg = "'" + "".join(parts) + "'"
- return arg
diff --git a/pythonFiles/testing_tools/process_json_util.py b/pythonFiles/testing_tools/process_json_util.py
deleted file mode 100644
index f116b0d9a8f3..000000000000
--- a/pythonFiles/testing_tools/process_json_util.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-import io
-import json
-from typing import List
-
-CONTENT_LENGTH: str = "Content-Length:"
-
-
-def process_rpc_json(data: str) -> List[str]:
- """Process the JSON data which comes from the server."""
- str_stream: io.StringIO = io.StringIO(data)
-
- length: int = 0
-
- while True:
- line: str = str_stream.readline()
- if CONTENT_LENGTH.lower() in line.lower():
- length = int(line[len(CONTENT_LENGTH) :])
- break
-
- if not line or line.isspace():
- raise ValueError("Header does not contain Content-Length")
-
- while True:
- line: str = str_stream.readline()
- if not line or line.isspace():
- break
-
- raw_json: str = str_stream.read(length)
- return json.loads(raw_json)
diff --git a/pythonFiles/testing_tools/run_adapter.py b/pythonFiles/testing_tools/run_adapter.py
deleted file mode 100644
index 1eeef194f8f5..000000000000
--- a/pythonFiles/testing_tools/run_adapter.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-# Replace the "." entry.
-import os.path
-import sys
-
-sys.path.insert(
- 1,
- os.path.dirname( # pythonFiles
- os.path.dirname( # pythonFiles/testing_tools
- os.path.abspath(__file__) # this file
- )
- ),
-)
-
-from testing_tools.adapter.__main__ import parse_args, main
-
-
-if __name__ == "__main__":
- tool, cmd, subargs, toolargs = parse_args()
- main(tool, cmd, subargs, toolargs)
diff --git a/pythonFiles/testing_tools/socket_manager.py b/pythonFiles/testing_tools/socket_manager.py
deleted file mode 100644
index b2afbf0e5a17..000000000000
--- a/pythonFiles/testing_tools/socket_manager.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import socket
-import sys
-
-
-class SocketManager(object):
- """Create a socket and connect to the given address.
-
- The address is a (host: str, port: int) tuple.
- Example usage:
-
- ```
- with SocketManager(("localhost", 6767)) as sock:
- request = json.dumps(payload)
- result = s.socket.sendall(request.encode("utf-8"))
- ```
- """
-
- def __init__(self, addr):
- self.addr = addr
- self.socket = None
-
- def __enter__(self):
- return self.connect()
-
- def __exit__(self, *_):
- self.close()
-
- def connect(self):
- self.socket = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP
- )
- if sys.platform == "win32":
- addr_use = socket.SO_EXCLUSIVEADDRUSE
- else:
- addr_use = socket.SO_REUSEADDR
- self.socket.setsockopt(socket.SOL_SOCKET, addr_use, 1)
- self.socket.connect(self.addr)
-
- return self
-
- def close(self):
- if self.socket:
- try:
- self.socket.shutdown(socket.SHUT_RDWR)
- except Exception:
- pass
- self.socket.close()
diff --git a/pythonFiles/testing_tools/unittest_discovery.py b/pythonFiles/testing_tools/unittest_discovery.py
deleted file mode 100644
index 2988092c387c..000000000000
--- a/pythonFiles/testing_tools/unittest_discovery.py
+++ /dev/null
@@ -1,65 +0,0 @@
-import inspect
-import os
-import sys
-import traceback
-import unittest
-
-start_dir = sys.argv[1]
-pattern = sys.argv[2]
-top_level_dir = sys.argv[3] if len(sys.argv) >= 4 else None
-sys.path.insert(0, os.getcwd())
-
-
-def get_sourceline(obj):
- try:
- s, n = inspect.getsourcelines(obj)
- except:
- try:
- # this handles `tornado` case we need a better
- # way to get to the wrapped function.
- # This is a temporary solution
- s, n = inspect.getsourcelines(obj.orig_method)
- except:
- return "*"
-
- for i, v in enumerate(s):
- if v.strip().startswith(("def", "async def")):
- return str(n + i)
- return "*"
-
-
-def generate_test_cases(suite):
- for test in suite:
- if isinstance(test, unittest.TestCase):
- yield test
- else:
- for test_case in generate_test_cases(test):
- yield test_case
-
-
-try:
- loader = unittest.TestLoader()
- suite = loader.discover(start_dir, pattern=pattern, top_level_dir=top_level_dir)
-
- print("start") # Don't remove this line
- loader_errors = []
- for s in generate_test_cases(suite):
- tm = getattr(s, s._testMethodName)
- testId = s.id()
- if testId.startswith("unittest.loader._FailedTest"):
- loader_errors.append(s._exception)
- else:
- print(testId.replace(".", ":") + ":" + get_sourceline(tm))
-except:
- print("=== exception start ===")
- traceback.print_exc()
- print("=== exception end ===")
-
-
-for error in loader_errors:
- try:
- print("=== exception start ===")
- print(error.msg)
- print("=== exception end ===")
- except:
- pass
diff --git a/pythonFiles/tests/debug_adapter/test_install_debugpy.py b/pythonFiles/tests/debug_adapter/test_install_debugpy.py
deleted file mode 100644
index 8e2ed33a1daf..000000000000
--- a/pythonFiles/tests/debug_adapter/test_install_debugpy.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import os
-import pytest
-import subprocess
-import sys
-
-
-def _check_binaries(dir_path):
- expected_endswith = (
- "win_amd64.pyd",
- "win32.pyd",
- "darwin.so",
- "x86_64-linux-gnu.so",
- )
-
- binaries = list(p for p in os.listdir(dir_path) if p.endswith(expected_endswith))
-
- assert len(binaries) == len(expected_endswith)
-
-
-def test_install_debugpy(tmpdir):
- import install_debugpy
-
- install_debugpy.main(str(tmpdir))
- dir_path = os.path.join(
- str(tmpdir), "debugpy", "_vendored", "pydevd", "_pydevd_bundle"
- )
- _check_binaries(dir_path)
-
- dir_path = os.path.join(
- str(tmpdir), "debugpy", "_vendored", "pydevd", "_pydevd_frame_eval"
- )
- _check_binaries(dir_path)
diff --git a/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py b/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py
deleted file mode 100644
index d4e91f56b5fe..000000000000
--- a/pythonFiles/tests/pytestadapter/expected_discovery_test_output.py
+++ /dev/null
@@ -1,996 +0,0 @@
-import os
-
-
-from .helpers import TEST_DATA_PATH, find_test_line_number, get_absolute_test_id
-
-# This file contains the expected output dictionaries for tests discovery and is used in test_discovery.py.
-
-# This is the expected output for the empty_discovery.py file.
-# βββ
-TEST_DATA_PATH_STR = os.fspath(TEST_DATA_PATH)
-empty_discovery_pytest_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the simple_pytest.py file.
-# βββ simple_pytest.py
-# βββ test_function
-simple_test_file_path = TEST_DATA_PATH / "simple_pytest.py"
-simple_discovery_pytest_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "simple_pytest.py",
- "path": os.fspath(simple_test_file_path),
- "type_": "file",
- "id_": os.fspath(simple_test_file_path),
- "children": [
- {
- "name": "test_function",
- "path": os.fspath(simple_test_file_path),
- "lineno": find_test_line_number(
- "test_function",
- simple_test_file_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "simple_pytest.py::test_function", simple_test_file_path
- ),
- "runID": get_absolute_test_id(
- "simple_pytest.py::test_function", simple_test_file_path
- ),
- }
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the unittest_pytest_same_file.py file.
-# βββ unittest_pytest_same_file.py
-# βββ TestExample
-# β βββ test_true_unittest
-# βββ test_true_pytest
-unit_pytest_same_file_path = TEST_DATA_PATH / "unittest_pytest_same_file.py"
-unit_pytest_same_file_discovery_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "unittest_pytest_same_file.py",
- "path": os.fspath(unit_pytest_same_file_path),
- "type_": "file",
- "id_": os.fspath(unit_pytest_same_file_path),
- "children": [
- {
- "name": "TestExample",
- "path": os.fspath(unit_pytest_same_file_path),
- "type_": "class",
- "children": [
- {
- "name": "test_true_unittest",
- "path": os.fspath(unit_pytest_same_file_path),
- "lineno": find_test_line_number(
- "test_true_unittest",
- os.fspath(unit_pytest_same_file_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_pytest_same_file.py::TestExample::test_true_unittest",
- unit_pytest_same_file_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_pytest_same_file.py::TestExample::test_true_unittest",
- unit_pytest_same_file_path,
- ),
- }
- ],
- "id_": "unittest_pytest_same_file.py::TestExample",
- },
- {
- "name": "test_true_pytest",
- "path": os.fspath(unit_pytest_same_file_path),
- "lineno": find_test_line_number(
- "test_true_pytest",
- unit_pytest_same_file_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_pytest_same_file.py::test_true_pytest",
- unit_pytest_same_file_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_pytest_same_file.py::test_true_pytest",
- unit_pytest_same_file_path,
- ),
- },
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the unittest_skip_file_level test.
-# βββ unittest_skiptest_file_level.py
-unittest_skip_file_level_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the unittest_folder tests
-# βββ unittest_folder
-# βββ test_add.py
-# β βββ TestAddFunction
-# β βββ test_add_negative_numbers
-# β βββ test_add_positive_numbers
-# β βββ TestDuplicateFunction
-# β βββ test_dup_a
-# βββ test_subtract.py
-# βββ TestSubtractFunction
-# βββ test_subtract_negative_numbers
-# βββ test_subtract_positive_numbers
-# β βββ TestDuplicateFunction
-# β βββ test_dup_s
-unittest_folder_path = TEST_DATA_PATH / "unittest_folder"
-test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
-test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py"
-unittest_folder_discovery_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "unittest_folder",
- "path": os.fspath(unittest_folder_path),
- "type_": "folder",
- "id_": os.fspath(unittest_folder_path),
- "children": [
- {
- "name": "test_add.py",
- "path": os.fspath(test_add_path),
- "type_": "file",
- "id_": os.fspath(test_add_path),
- "children": [
- {
- "name": "TestAddFunction",
- "path": os.fspath(test_add_path),
- "type_": "class",
- "children": [
- {
- "name": "test_add_negative_numbers",
- "path": os.fspath(test_add_path),
- "lineno": find_test_line_number(
- "test_add_negative_numbers",
- os.fspath(test_add_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers",
- test_add_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers",
- test_add_path,
- ),
- },
- {
- "name": "test_add_positive_numbers",
- "path": os.fspath(test_add_path),
- "lineno": find_test_line_number(
- "test_add_positive_numbers",
- os.fspath(test_add_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
- test_add_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
- test_add_path,
- ),
- },
- ],
- "id_": "unittest_folder/test_add.py::TestAddFunction",
- },
- {
- "name": "TestDuplicateFunction",
- "path": os.fspath(test_add_path),
- "type_": "class",
- "children": [
- {
- "name": "test_dup_a",
- "path": os.fspath(test_add_path),
- "lineno": find_test_line_number(
- "test_dup_a",
- os.fspath(test_add_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a",
- test_add_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a",
- test_add_path,
- ),
- },
- ],
- "id_": "unittest_folder/test_add.py::TestDuplicateFunction",
- },
- ],
- },
- {
- "name": "test_subtract.py",
- "path": os.fspath(test_subtract_path),
- "type_": "file",
- "id_": os.fspath(test_subtract_path),
- "children": [
- {
- "name": "TestSubtractFunction",
- "path": os.fspath(test_subtract_path),
- "type_": "class",
- "children": [
- {
- "name": "test_subtract_negative_numbers",
- "path": os.fspath(test_subtract_path),
- "lineno": find_test_line_number(
- "test_subtract_negative_numbers",
- os.fspath(test_subtract_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
- test_subtract_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
- test_subtract_path,
- ),
- },
- {
- "name": "test_subtract_positive_numbers",
- "path": os.fspath(test_subtract_path),
- "lineno": find_test_line_number(
- "test_subtract_positive_numbers",
- os.fspath(test_subtract_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
- test_subtract_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
- test_subtract_path,
- ),
- },
- ],
- "id_": "unittest_folder/test_subtract.py::TestSubtractFunction",
- },
- {
- "name": "TestDuplicateFunction",
- "path": os.fspath(test_subtract_path),
- "type_": "class",
- "children": [
- {
- "name": "test_dup_s",
- "path": os.fspath(test_subtract_path),
- "lineno": find_test_line_number(
- "test_dup_s",
- os.fspath(test_subtract_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s",
- test_subtract_path,
- ),
- "runID": get_absolute_test_id(
- "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s",
- test_subtract_path,
- ),
- },
- ],
- "id_": "unittest_folder/test_subtract.py::TestDuplicateFunction",
- },
- ],
- },
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-
-# This is the expected output for the dual_level_nested_folder tests
-# βββ dual_level_nested_folder
-# βββ test_top_folder.py
-# βββ test_top_function_t
-# βββ test_top_function_f
-# βββ z_nested_folder_one
-# βββ test_bottom_folder.py
-# βββ test_bottom_function_t
-# βββ test_bottom_function_f
-dual_level_nested_folder_path = TEST_DATA_PATH / "dual_level_nested_folder"
-test_top_folder_path = (
- TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
-)
-
-test_z_nested_folder_one_path = (
- TEST_DATA_PATH / "dual_level_nested_folder" / "z_nested_folder_one"
-)
-
-test_bottom_folder_path = (
- TEST_DATA_PATH
- / "dual_level_nested_folder"
- / "z_nested_folder_one"
- / "test_bottom_folder.py"
-)
-
-
-dual_level_nested_folder_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "dual_level_nested_folder",
- "path": os.fspath(dual_level_nested_folder_path),
- "type_": "folder",
- "id_": os.fspath(dual_level_nested_folder_path),
- "children": [
- {
- "name": "test_top_folder.py",
- "path": os.fspath(test_top_folder_path),
- "type_": "file",
- "id_": os.fspath(test_top_folder_path),
- "children": [
- {
- "name": "test_top_function_t",
- "path": os.fspath(test_top_folder_path),
- "lineno": find_test_line_number(
- "test_top_function_t",
- test_top_folder_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "dual_level_nested_folder/test_top_folder.py::test_top_function_t",
- test_top_folder_path,
- ),
- "runID": get_absolute_test_id(
- "dual_level_nested_folder/test_top_folder.py::test_top_function_t",
- test_top_folder_path,
- ),
- },
- {
- "name": "test_top_function_f",
- "path": os.fspath(test_top_folder_path),
- "lineno": find_test_line_number(
- "test_top_function_f",
- test_top_folder_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "dual_level_nested_folder/test_top_folder.py::test_top_function_f",
- test_top_folder_path,
- ),
- "runID": get_absolute_test_id(
- "dual_level_nested_folder/test_top_folder.py::test_top_function_f",
- test_top_folder_path,
- ),
- },
- ],
- },
- {
- "name": "z_nested_folder_one",
- "path": os.fspath(test_z_nested_folder_one_path),
- "type_": "folder",
- "id_": os.fspath(test_z_nested_folder_one_path),
- "children": [
- {
- "name": "test_bottom_folder.py",
- "path": os.fspath(test_bottom_folder_path),
- "type_": "file",
- "id_": os.fspath(test_bottom_folder_path),
- "children": [
- {
- "name": "test_bottom_function_t",
- "path": os.fspath(test_bottom_folder_path),
- "lineno": find_test_line_number(
- "test_bottom_function_t",
- test_bottom_folder_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
- test_bottom_folder_path,
- ),
- "runID": get_absolute_test_id(
- "dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
- test_bottom_folder_path,
- ),
- },
- {
- "name": "test_bottom_function_f",
- "path": os.fspath(test_bottom_folder_path),
- "lineno": find_test_line_number(
- "test_bottom_function_f",
- test_bottom_folder_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
- test_bottom_folder_path,
- ),
- "runID": get_absolute_test_id(
- "dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
- test_bottom_folder_path,
- ),
- },
- ],
- }
- ],
- },
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the double_nested_folder tests.
-# βββ folder_a
-# βββ folder_b
-# βββ folder_a
-# βββ test_nest.py
-# βββ test_function
-
-folder_a_path = TEST_DATA_PATH / "folder_a"
-folder_b_path = TEST_DATA_PATH / "folder_a" / "folder_b"
-folder_a_nested_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a"
-test_nest_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py"
-double_nested_folder_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "folder_a",
- "path": os.fspath(folder_a_path),
- "type_": "folder",
- "id_": os.fspath(folder_a_path),
- "children": [
- {
- "name": "folder_b",
- "path": os.fspath(folder_b_path),
- "type_": "folder",
- "id_": os.fspath(folder_b_path),
- "children": [
- {
- "name": "folder_a",
- "path": os.fspath(folder_a_nested_path),
- "type_": "folder",
- "id_": os.fspath(folder_a_nested_path),
- "children": [
- {
- "name": "test_nest.py",
- "path": os.fspath(test_nest_path),
- "type_": "file",
- "id_": os.fspath(test_nest_path),
- "children": [
- {
- "name": "test_function",
- "path": os.fspath(test_nest_path),
- "lineno": find_test_line_number(
- "test_function",
- test_nest_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "folder_a/folder_b/folder_a/test_nest.py::test_function",
- test_nest_path,
- ),
- "runID": get_absolute_test_id(
- "folder_a/folder_b/folder_a/test_nest.py::test_function",
- test_nest_path,
- ),
- }
- ],
- }
- ],
- }
- ],
- }
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the nested_folder tests.
-# βββ parametrize_tests.py
-# βββ test_adding
-# βββ [3+5-8]
-# βββ [2+4-6]
-# βββ [6+9-16]
-parameterize_tests_path = TEST_DATA_PATH / "parametrize_tests.py"
-parametrize_tests_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "parametrize_tests.py",
- "path": os.fspath(parameterize_tests_path),
- "type_": "file",
- "id_": os.fspath(parameterize_tests_path),
- "children": [
- {
- "name": "test_adding",
- "path": os.fspath(parameterize_tests_path),
- "type_": "function",
- "id_": "parametrize_tests.py::test_adding",
- "children": [
- {
- "name": "[3+5-8]",
- "path": os.fspath(parameterize_tests_path),
- "lineno": find_test_line_number(
- "test_adding[3+5-8]",
- parameterize_tests_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]",
- parameterize_tests_path,
- ),
- "runID": get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]",
- parameterize_tests_path,
- ),
- },
- {
- "name": "[2+4-6]",
- "path": os.fspath(parameterize_tests_path),
- "lineno": find_test_line_number(
- "test_adding[2+4-6]",
- parameterize_tests_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "parametrize_tests.py::test_adding[2+4-6]",
- parameterize_tests_path,
- ),
- "runID": get_absolute_test_id(
- "parametrize_tests.py::test_adding[2+4-6]",
- parameterize_tests_path,
- ),
- },
- {
- "name": "[6+9-16]",
- "path": os.fspath(parameterize_tests_path),
- "lineno": find_test_line_number(
- "test_adding[6+9-16]",
- parameterize_tests_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "parametrize_tests.py::test_adding[6+9-16]",
- parameterize_tests_path,
- ),
- "runID": get_absolute_test_id(
- "parametrize_tests.py::test_adding[6+9-16]",
- parameterize_tests_path,
- ),
- },
- ],
- },
- {
- "name": "test_string",
- "path": os.fspath(parameterize_tests_path),
- "type_": "function",
- "children": [
- {
- "name": "[hello]",
- "path": os.fspath(parameterize_tests_path),
- "lineno": find_test_line_number(
- "test_string[hello]",
- parameterize_tests_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "parametrize_tests.py::test_string[hello]",
- parameterize_tests_path,
- ),
- "runID": get_absolute_test_id(
- "parametrize_tests.py::test_string[hello]",
- parameterize_tests_path,
- ),
- },
- {
- "name": "[complicated split [] ()]",
- "path": os.fspath(parameterize_tests_path),
- "lineno": find_test_line_number(
- "test_string[1]",
- parameterize_tests_path,
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "parametrize_tests.py::test_string[complicated split [] ()]",
- parameterize_tests_path,
- ),
- "runID": get_absolute_test_id(
- "parametrize_tests.py::test_string[complicated split [] ()]",
- parameterize_tests_path,
- ),
- },
- ],
- "id_": "parametrize_tests.py::test_string",
- },
- ],
- },
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the text_docstring.txt tests.
-# βββ text_docstring.txt
-text_docstring_path = TEST_DATA_PATH / "text_docstring.txt"
-doctest_pytest_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "text_docstring.txt",
- "path": os.fspath(text_docstring_path),
- "type_": "file",
- "id_": os.fspath(text_docstring_path),
- "children": [
- {
- "name": "text_docstring.txt",
- "path": os.fspath(text_docstring_path),
- "lineno": find_test_line_number(
- "text_docstring.txt",
- os.fspath(text_docstring_path),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "text_docstring.txt::text_docstring.txt", text_docstring_path
- ),
- "runID": get_absolute_test_id(
- "text_docstring.txt::text_docstring.txt", text_docstring_path
- ),
- }
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-# This is the expected output for the param_same_name tests.
-# βββ param_same_name
-# βββ test_param1.py
-# βββ test_odd_even
-# βββ [a]
-# βββ [b]
-# βββ [c]
-# βββ test_param2.py
-# βββ test_odd_even
-# βββ [1]
-# βββ [2]
-# βββ [3]
-param1_path = TEST_DATA_PATH / "param_same_name" / "test_param1.py"
-param2_path = TEST_DATA_PATH / "param_same_name" / "test_param2.py"
-param_same_name_expected_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "param_same_name",
- "path": os.fspath(TEST_DATA_PATH / "param_same_name"),
- "type_": "folder",
- "id_": os.fspath(TEST_DATA_PATH / "param_same_name"),
- "children": [
- {
- "name": "test_param1.py",
- "path": os.fspath(param1_path),
- "type_": "file",
- "id_": os.fspath(param1_path),
- "children": [
- {
- "name": "test_odd_even",
- "path": os.fspath(param1_path),
- "type_": "function",
- "children": [
- {
- "name": "[a]",
- "path": os.fspath(param1_path),
- "lineno": "6",
- "type_": "test",
- "id_": get_absolute_test_id(
- "param_same_name/test_param1.py::test_odd_even[a]",
- param1_path,
- ),
- "runID": get_absolute_test_id(
- "param_same_name/test_param1.py::test_odd_even[a]",
- param1_path,
- ),
- },
- {
- "name": "[b]",
- "path": os.fspath(param1_path),
- "lineno": "6",
- "type_": "test",
- "id_": get_absolute_test_id(
- "param_same_name/test_param1.py::test_odd_even[b]",
- param1_path,
- ),
- "runID": get_absolute_test_id(
- "param_same_name/test_param1.py::test_odd_even[b]",
- param1_path,
- ),
- },
- {
- "name": "[c]",
- "path": os.fspath(param1_path),
- "lineno": "6",
- "type_": "test",
- "id_": get_absolute_test_id(
- "param_same_name/test_param1.py::test_odd_even[c]",
- param1_path,
- ),
- "runID": get_absolute_test_id(
- "param_same_name/test_param1.py::test_odd_even[c]",
- param1_path,
- ),
- },
- ],
- "id_": "param_same_name/test_param1.py::test_odd_even",
- }
- ],
- },
- {
- "name": "test_param2.py",
- "path": os.fspath(param2_path),
- "type_": "file",
- "id_": os.fspath(param2_path),
- "children": [
- {
- "name": "test_odd_even",
- "path": os.fspath(param2_path),
- "type_": "function",
- "children": [
- {
- "name": "[1]",
- "path": os.fspath(param2_path),
- "lineno": "6",
- "type_": "test",
- "id_": get_absolute_test_id(
- "param_same_name/test_param2.py::test_odd_even[1]",
- param2_path,
- ),
- "runID": get_absolute_test_id(
- "param_same_name/test_param2.py::test_odd_even[1]",
- param2_path,
- ),
- },
- {
- "name": "[2]",
- "path": os.fspath(param2_path),
- "lineno": "6",
- "type_": "test",
- "id_": get_absolute_test_id(
- "param_same_name/test_param2.py::test_odd_even[2]",
- param2_path,
- ),
- "runID": get_absolute_test_id(
- "param_same_name/test_param2.py::test_odd_even[2]",
- param2_path,
- ),
- },
- {
- "name": "[3]",
- "path": os.fspath(param2_path),
- "lineno": "6",
- "type_": "test",
- "id_": get_absolute_test_id(
- "param_same_name/test_param2.py::test_odd_even[3]",
- param2_path,
- ),
- "runID": get_absolute_test_id(
- "param_same_name/test_param2.py::test_odd_even[3]",
- param2_path,
- ),
- },
- ],
- "id_": "param_same_name/test_param2.py::test_odd_even",
- }
- ],
- },
- ],
- }
- ],
- "id_": TEST_DATA_PATH_STR,
-}
-
-tests_path = TEST_DATA_PATH / "root" / "tests"
-tests_a_path = TEST_DATA_PATH / "root" / "tests" / "test_a.py"
-tests_b_path = TEST_DATA_PATH / "root" / "tests" / "test_b.py"
-# This is the expected output for the root folder tests.
-# βββ tests
-# βββ test_a.py
-# βββ test_a_function
-# βββ test_b.py
-# βββ test_b_function
-root_with_config_expected_output = {
- "name": "tests",
- "path": os.fspath(tests_path),
- "type_": "folder",
- "children": [
- {
- "name": "test_a.py",
- "path": os.fspath(tests_a_path),
- "type_": "file",
- "id_": os.fspath(tests_a_path),
- "children": [
- {
- "name": "test_a_function",
- "path": os.fspath(os.path.join(tests_path, "test_a.py")),
- "lineno": find_test_line_number(
- "test_a_function",
- os.path.join(tests_path, "test_a.py"),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "tests/test_a.py::test_a_function", tests_a_path
- ),
- "runID": get_absolute_test_id(
- "tests/test_a.py::test_a_function", tests_a_path
- ),
- }
- ],
- },
- {
- "name": "test_b.py",
- "path": os.fspath(tests_b_path),
- "type_": "file",
- "id_": os.fspath(tests_b_path),
- "children": [
- {
- "name": "test_b_function",
- "path": os.fspath(os.path.join(tests_path, "test_b.py")),
- "lineno": find_test_line_number(
- "test_b_function",
- os.path.join(tests_path, "test_b.py"),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "tests/test_b.py::test_b_function", tests_b_path
- ),
- "runID": get_absolute_test_id(
- "tests/test_b.py::test_b_function", tests_b_path
- ),
- }
- ],
- },
- ],
- "id_": os.fspath(tests_path),
-}
-TEST_MULTI_CLASS_NEST_PATH = TEST_DATA_PATH / "test_multi_class_nest.py"
-
-nested_classes_expected_test_output = {
- "name": ".data",
- "path": TEST_DATA_PATH_STR,
- "type_": "folder",
- "children": [
- {
- "name": "test_multi_class_nest.py",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "type_": "file",
- "id_": str(TEST_MULTI_CLASS_NEST_PATH),
- "children": [
- {
- "name": "TestFirstClass",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "type_": "class",
- "id_": "test_multi_class_nest.py::TestFirstClass",
- "children": [
- {
- "name": "TestSecondClass",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "type_": "class",
- "id_": "test_multi_class_nest.py::TestFirstClass::TestSecondClass",
- "children": [
- {
- "name": "test_second",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "lineno": find_test_line_number(
- "test_second",
- str(TEST_MULTI_CLASS_NEST_PATH),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "test_multi_class_nest.py::TestFirstClass::TestSecondClass::test_second",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- "runID": get_absolute_test_id(
- "test_multi_class_nest.py::TestFirstClass::TestSecondClass::test_second",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- }
- ],
- },
- {
- "name": "test_first",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "lineno": find_test_line_number(
- "test_first", str(TEST_MULTI_CLASS_NEST_PATH)
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "test_multi_class_nest.py::TestFirstClass::test_first",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- "runID": get_absolute_test_id(
- "test_multi_class_nest.py::TestFirstClass::test_first",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- },
- {
- "name": "TestSecondClass2",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "type_": "class",
- "id_": "test_multi_class_nest.py::TestFirstClass::TestSecondClass2",
- "children": [
- {
- "name": "test_second2",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "lineno": find_test_line_number(
- "test_second2",
- str(TEST_MULTI_CLASS_NEST_PATH),
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "test_multi_class_nest.py::TestFirstClass::TestSecondClass2::test_second2",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- "runID": get_absolute_test_id(
- "test_multi_class_nest.py::TestFirstClass::TestSecondClass2::test_second2",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- }
- ],
- },
- ],
- },
- {
- "name": "test_independent",
- "path": str(TEST_MULTI_CLASS_NEST_PATH),
- "lineno": find_test_line_number(
- "test_independent", str(TEST_MULTI_CLASS_NEST_PATH)
- ),
- "type_": "test",
- "id_": get_absolute_test_id(
- "test_multi_class_nest.py::test_independent",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- "runID": get_absolute_test_id(
- "test_multi_class_nest.py::test_independent",
- TEST_MULTI_CLASS_NEST_PATH,
- ),
- },
- ],
- }
- ],
- "id_": str(TEST_DATA_PATH),
-}
diff --git a/pythonFiles/tests/pytestadapter/helpers.py b/pythonFiles/tests/pytestadapter/helpers.py
deleted file mode 100644
index 2d36da59956b..000000000000
--- a/pythonFiles/tests/pytestadapter/helpers.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import io
-import json
-import os
-import pathlib
-import socket
-import subprocess
-import sys
-import threading
-import uuid
-from typing import Any, Dict, List, Optional, Tuple
-
-script_dir = pathlib.Path(__file__).parent.parent.parent
-sys.path.append(os.fspath(script_dir))
-sys.path.append(os.fspath(script_dir / "lib" / "python"))
-
-TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
-from typing_extensions import TypedDict
-
-
-def get_absolute_test_id(test_id: str, testPath: pathlib.Path) -> str:
- split_id = test_id.split("::")[1:]
- absolute_test_id = "::".join([str(testPath), *split_id])
- print("absolute path", absolute_test_id)
- return absolute_test_id
-
-
-def create_server(
- host: str = "127.0.0.1",
- port: int = 0,
- backlog: int = socket.SOMAXCONN,
- timeout: int = 1000,
-) -> socket.socket:
- """Return a local server socket listening on the given port."""
- server: socket.socket = _new_sock()
- if port:
- # If binding to a specific port, make sure that the user doesn't have
- # to wait until the OS times out waiting for socket in order to use
- # that port again if the server or the adapter crash or are force-killed.
- if sys.platform == "win32":
- server.setsockopt(socket.SOL_SOCKET, socket.SO_EXCLUSIVEADDRUSE, 1)
- else:
- try:
- server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- except (AttributeError, OSError):
- pass # Not available everywhere
- server.bind((host, port))
- if timeout:
- server.settimeout(timeout)
- server.listen(backlog)
- return server
-
-
-def _new_sock() -> socket.socket:
- sock: socket.socket = socket.socket(
- socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP
- )
- options = [
- ("SOL_SOCKET", "SO_KEEPALIVE", 1),
- ("IPPROTO_TCP", "TCP_KEEPIDLE", 1),
- ("IPPROTO_TCP", "TCP_KEEPINTVL", 3),
- ("IPPROTO_TCP", "TCP_KEEPCNT", 5),
- ]
-
- for level, name, value in options:
- try:
- sock.setsockopt(getattr(socket, level), getattr(socket, name), value)
- except (AttributeError, OSError):
- pass # May not be available everywhere.
-
- return sock
-
-
-CONTENT_LENGTH: str = "Content-Length:"
-Env_Dict = TypedDict(
- "Env_Dict", {"TEST_UUID": str, "TEST_PORT": str, "PYTHONPATH": str}
-)
-
-
-def process_rpc_message(data: str) -> Tuple[Dict[str, Any], str]:
- """Process the JSON data which comes from the server which runs the pytest discovery."""
- str_stream: io.StringIO = io.StringIO(data)
-
- length: int = 0
-
- while True:
- line: str = str_stream.readline()
- if CONTENT_LENGTH.lower() in line.lower():
- length = int(line[len(CONTENT_LENGTH) :])
- break
-
- if not line or line.isspace():
- raise ValueError("Header does not contain Content-Length")
-
- while True:
- line: str = str_stream.readline()
- if not line or line.isspace():
- break
-
- raw_json: str = str_stream.read(length)
- return json.loads(raw_json), str_stream.read()
-
-
-def process_rpc_json(data: str) -> List[Dict[str, Any]]:
- """Process the JSON data which comes from the server which runs the pytest discovery."""
- json_messages = []
- remaining = data
- while remaining:
- json_data, remaining = process_rpc_message(remaining)
- json_messages.append(json_data)
-
- return json_messages
-
-
-def runner(args: List[str]) -> Optional[List[Dict[str, Any]]]:
- """Run the pytest discovery and return the JSON data from the server."""
- return runner_with_cwd(args, TEST_DATA_PATH)
-
-
-def runner_with_cwd(
- args: List[str], path: pathlib.Path
-) -> Optional[List[Dict[str, Any]]]:
- """Run the pytest discovery and return the JSON data from the server."""
- process_args: List[str] = [
- sys.executable,
- "-m",
- "pytest",
- "-p",
- "vscode_pytest",
- "-s",
- ] + args
- listener: socket.socket = create_server()
- _, port = listener.getsockname()
- listener.listen()
-
- env = os.environ.copy()
- env.update(
- {
- "TEST_UUID": str(uuid.uuid4()),
- "TEST_PORT": str(port),
- "PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
- }
- )
- completed = threading.Event()
-
- result = []
- t1: threading.Thread = threading.Thread(
- target=_listen_on_socket, args=(listener, result, completed)
- )
- t1.start()
-
- t2 = threading.Thread(
- target=_run_test_code,
- args=(process_args, env, path, completed),
- )
- t2.start()
-
- t1.join()
- t2.join()
-
- return process_rpc_json(result[0]) if result else None
-
-
-def _listen_on_socket(
- listener: socket.socket, result: List[str], completed: threading.Event
-):
- """Listen on the socket for the JSON data from the server.
- Created as a separate function for clarity in threading.
- """
- sock, (other_host, other_port) = listener.accept()
- listener.settimeout(1)
- all_data: list = []
- while True:
- data: bytes = sock.recv(1024 * 1024)
- if not data:
- if completed.is_set():
- break
- else:
- try:
- sock, (other_host, other_port) = listener.accept()
- except socket.timeout:
- result.append("".join(all_data))
- return
- all_data.append(data.decode("utf-8"))
- result.append("".join(all_data))
-
-
-def _run_test_code(
- proc_args: List[str], proc_env, proc_cwd: str, completed: threading.Event
-):
- result = subprocess.run(proc_args, env=proc_env, cwd=proc_cwd)
- completed.set()
- return result
-
-
-def find_test_line_number(test_name: str, test_file_path) -> str:
- """Function which finds the correct line number for a test by looking for the "test_marker--[test_name]" string.
-
- The test_name is split on the "[" character to remove the parameterization information.
-
- Args:
- test_name: The name of the test to find the line number for, will be unique per file.
- test_file_path: The path to the test file where the test is located.
- """
- test_file_unique_id: str = "test_marker--" + test_name.split("[")[0]
- with open(test_file_path) as f:
- for i, line in enumerate(f):
- if test_file_unique_id in line:
- return str(i + 1)
- error_str: str = f"Test {test_name!r} not found on any line in {test_file_path}"
- raise ValueError(error_str)
diff --git a/pythonFiles/tests/pytestadapter/test_discovery.py b/pythonFiles/tests/pytestadapter/test_discovery.py
deleted file mode 100644
index 2630ddef68b0..000000000000
--- a/pythonFiles/tests/pytestadapter/test_discovery.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-import os
-import shutil
-from typing import Any, Dict, List, Optional
-
-import pytest
-
-from . import expected_discovery_test_output
-from .helpers import TEST_DATA_PATH, runner, runner_with_cwd
-
-
-def test_import_error(tmp_path):
- """Test pytest discovery on a file that has a pytest marker but does not import pytest.
-
- Copies the contents of a .txt file to a .py file in the temporary directory
- to then run pytest discovery on.
-
- The json should still be returned but the errors list should be present.
-
- Keyword arguments:
- tmp_path -- pytest fixture that creates a temporary directory.
- """
- # Saving some files as .txt to avoid that file displaying a syntax error for
- # the extension as a whole. Instead, rename it before running this test
- # in order to test the error handling.
- file_path = TEST_DATA_PATH / "error_pytest_import.txt"
- temp_dir = tmp_path / "temp_data"
- temp_dir.mkdir()
- p = temp_dir / "error_pytest_import.py"
- shutil.copyfile(file_path, p)
- actual: Optional[List[Dict[str, Any]]] = runner(["--collect-only", os.fspath(p)])
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- if actual_list is not None:
- assert actual_list.pop(-1).get("eot")
- for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
- assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
-
- # Ensure that 'error' is a list and then check its length
- error_content = actual_item.get("error")
- if error_content is not None and isinstance(
- error_content, (list, tuple, str)
- ): # You can add other types if needed
- assert len(error_content) == 2
- else:
- assert False
-
-
-def test_syntax_error(tmp_path):
- """Test pytest discovery on a file that has a syntax error.
-
- Copies the contents of a .txt file to a .py file in the temporary directory
- to then run pytest discovery on.
-
- The json should still be returned but the errors list should be present.
-
- Keyword arguments:
- tmp_path -- pytest fixture that creates a temporary directory.
- """
- # Saving some files as .txt to avoid that file displaying a syntax error for
- # the extension as a whole. Instead, rename it before running this test
- # in order to test the error handling.
- file_path = TEST_DATA_PATH / "error_syntax_discovery.txt"
- temp_dir = tmp_path / "temp_data"
- temp_dir.mkdir()
- p = temp_dir / "error_syntax_discovery.py"
- shutil.copyfile(file_path, p)
- actual = runner(["--collect-only", os.fspath(p)])
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- if actual_list is not None:
- assert actual_list.pop(-1).get("eot")
- for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
- assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
-
- # Ensure that 'error' is a list and then check its length
- error_content = actual_item.get("error")
- if error_content is not None and isinstance(
- error_content, (list, tuple, str)
- ): # You can add other types if needed
- assert len(error_content) == 2
- else:
- assert False
-
-
-def test_parameterized_error_collect():
- """Tests pytest discovery on specific file that incorrectly uses parametrize.
-
- The json should still be returned but the errors list should be present.
- """
- file_path_str = "error_parametrize_discovery.py"
- actual = runner(["--collect-only", file_path_str])
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- if actual_list is not None:
- assert actual_list.pop(-1).get("eot")
- for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
- assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
-
- # Ensure that 'error' is a list and then check its length
- error_content = actual_item.get("error")
- if error_content is not None and isinstance(
- error_content, (list, tuple, str)
- ): # You can add other types if needed
- assert len(error_content) == 2
- else:
- assert False
-
-
-@pytest.mark.parametrize(
- "file, expected_const",
- [
- (
- "test_multi_class_nest.py",
- expected_discovery_test_output.nested_classes_expected_test_output,
- ),
- (
- "unittest_skiptest_file_level.py",
- expected_discovery_test_output.unittest_skip_file_level_expected_output,
- ),
- (
- "param_same_name",
- expected_discovery_test_output.param_same_name_expected_output,
- ),
- (
- "parametrize_tests.py",
- expected_discovery_test_output.parametrize_tests_expected_output,
- ),
- (
- "empty_discovery.py",
- expected_discovery_test_output.empty_discovery_pytest_expected_output,
- ),
- (
- "simple_pytest.py",
- expected_discovery_test_output.simple_discovery_pytest_expected_output,
- ),
- (
- "unittest_pytest_same_file.py",
- expected_discovery_test_output.unit_pytest_same_file_discovery_expected_output,
- ),
- (
- "unittest_folder",
- expected_discovery_test_output.unittest_folder_discovery_expected_output,
- ),
- (
- "dual_level_nested_folder",
- expected_discovery_test_output.dual_level_nested_folder_expected_output,
- ),
- (
- "folder_a",
- expected_discovery_test_output.double_nested_folder_expected_output,
- ),
- (
- "text_docstring.txt",
- expected_discovery_test_output.doctest_pytest_expected_output,
- ),
- ],
-)
-def test_pytest_collect(file, expected_const):
- """
- Test to test pytest discovery on a variety of test files/ folder structures.
- Uses variables from expected_discovery_test_output.py to store the expected dictionary return.
- Only handles discovery and therefore already contains the arg --collect-only.
- All test discovery will succeed, be in the correct cwd, and match expected test output.
-
- Keyword arguments:
- file -- a string with the file or folder to run pytest discovery on.
- expected_const -- the expected output from running pytest discovery on the file.
- """
- actual = runner(
- [
- "--collect-only",
- os.fspath(TEST_DATA_PATH / file),
- ]
- )
-
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- if actual_list is not None:
- assert actual_list.pop(-1).get("eot")
- actual_item = actual_list.pop(0)
- assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
- assert actual_item.get("status") == "success"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
- assert actual_item.get("tests") == expected_const
-
-
-def test_pytest_root_dir():
- """
- Test to test pytest discovery with the command line arg --rootdir specified to be a subfolder
- of the workspace root. Discovery should succeed and testids should be relative to workspace root.
- """
- rd = f"--rootdir={TEST_DATA_PATH / 'root' / 'tests'}"
- actual = runner_with_cwd(
- [
- "--collect-only",
- rd,
- ],
- TEST_DATA_PATH / "root",
- )
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- if actual_list is not None:
- assert actual_list.pop(-1).get("eot")
- actual_item = actual_list.pop(0)
- assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
- assert actual_item.get("status") == "success"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH / "root")
- assert (
- actual_item.get("tests")
- == expected_discovery_test_output.root_with_config_expected_output
- )
-
-
-def test_pytest_config_file():
- """
- Test to test pytest discovery with the command line arg -c with a specified config file which
- changes the workspace root. Discovery should succeed and testids should be relative to workspace root.
- """
- actual = runner_with_cwd(
- [
- "--collect-only",
- "tests/",
- ],
- TEST_DATA_PATH / "root",
- )
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- if actual_list is not None:
- assert actual_list.pop(-1).get("eot")
- actual_item = actual_list.pop(0)
- assert all(item in actual_item.keys() for item in ("status", "cwd", "error"))
- assert actual_item.get("status") == "success"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH / "root")
- assert (
- actual_item.get("tests")
- == expected_discovery_test_output.root_with_config_expected_output
- )
diff --git a/pythonFiles/tests/test_shell_integration.py b/pythonFiles/tests/test_shell_integration.py
deleted file mode 100644
index 896df416eced..000000000000
--- a/pythonFiles/tests/test_shell_integration.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import importlib
-import sys
-from unittest.mock import Mock
-import pythonrc
-
-
-def test_decoration_success():
- importlib.reload(pythonrc)
- ps1 = pythonrc.ps1()
-
- ps1.hooks.failure_flag = False
- result = str(ps1)
- if sys.platform != "win32":
- assert (
- result
- == "\x1b]633;D;0\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07\x1b]633;E;None\x07"
- )
- else:
- pass
-
-
-def test_decoration_failure():
- importlib.reload(pythonrc)
- ps1 = pythonrc.ps1()
-
- ps1.hooks.failure_flag = True
- result = str(ps1)
- if sys.platform != "win32":
- assert (
- result
- == "\x1b]633;D;1\x07\x1b]633;A\x07>>> \x1b]633;B\x07\x1b]633;C\x07\x1b]633;E;None\x07"
- )
- else:
- pass
-
-
-def test_displayhook_call():
- importlib.reload(pythonrc)
- pythonrc.ps1()
- mock_displayhook = Mock()
-
- hooks = pythonrc.repl_hooks()
- hooks.original_displayhook = mock_displayhook
-
- hooks.my_displayhook("mock_value")
-
- mock_displayhook.assert_called_once_with("mock_value")
-
-
-def test_excepthook_call():
- importlib.reload(pythonrc)
- pythonrc.ps1()
- mock_excepthook = Mock()
-
- hooks = pythonrc.repl_hooks()
- hooks.original_excepthook = mock_excepthook
-
- hooks.my_excepthook("mock_type", "mock_value", "mock_traceback")
- mock_excepthook.assert_called_once_with("mock_type", "mock_value", "mock_traceback")
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py b/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py
deleted file mode 100644
index 3501b9e118e5..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/test_Spam.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_okay():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/README.md b/pythonFiles/tests/testing_tools/adapter/.data/complex/README.md
deleted file mode 100644
index e30e96142d02..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/README.md
+++ /dev/null
@@ -1,156 +0,0 @@
-## Directory Structure
-
-```
-pythonFiles/tests/testing_tools/adapter/.data/
- tests/ # test root
- test_doctest.txt
- test_pytest.py
- test_unittest.py
- test_mixed.py
- spam.py # note: no "test_" prefix, but contains tests
- test_foo.py
- test_42.py
- test_42-43.py # note the hyphen
- testspam.py
- v/
- __init__.py
- spam.py
- test_eggs.py
- test_ham.py
- test_spam.py
- w/
- # no __init__.py
- test_spam.py
- test_spam_ex.py
- x/y/z/ # each with a __init__.py
- test_ham.py
- a/
- __init__.py
- test_spam.py
- b/
- __init__.py
- test_spam.py
-```
-
-## Tests (and Suites)
-
-basic:
-
-- `./test_foo.py::test_simple`
-- `./test_pytest.py::test_simple`
-- `./test_pytest.py::TestSpam::test_simple`
-- `./test_pytest.py::TestSpam::TestHam::TestEggs::test_simple`
-- `./test_pytest.py::TestEggs::test_simple`
-- `./test_pytest.py::TestParam::test_simple`
-- `./test_mixed.py::test_top_level`
-- `./test_mixed.py::MyTests::test_simple`
-- `./test_mixed.py::TestMySuite::test_simple`
-- `./test_unittest.py::MyTests::test_simple`
-- `./test_unittest.py::OtherTests::test_simple`
-- `./x/y/z/test_ham.py::test_simple`
-- `./x/y/z/a/test_spam.py::test_simple`
-- `./x/y/z/b/test_spam.py::test_simple`
-
-failures:
-
-- `./test_pytest.py::test_failure`
-- `./test_pytest.py::test_runtime_failed`
-- `./test_pytest.py::test_raises`
-
-skipped:
-
-- `./test_mixed.py::test_skipped`
-- `./test_mixed.py::MyTests::test_skipped`
-- `./test_pytest.py::test_runtime_skipped`
-- `./test_pytest.py::test_skipped`
-- `./test_pytest.py::test_maybe_skipped`
-- `./test_pytest.py::SpamTests::test_skipped`
-- `./test_pytest.py::test_param_13_markers[???]`
-- `./test_pytest.py::test_param_13_skipped[*]`
-- `./test_unittest.py::MyTests::test_skipped`
-- (`./test_unittest.py::MyTests::test_maybe_skipped`)
-- (`./test_unittest.py::MyTests::test_maybe_not_skipped`)
-
-in namespace package:
-
-- `./w/test_spam.py::test_simple`
-- `./w/test_spam_ex.py::test_simple`
-
-filename oddities:
-
-- `./test_42.py::test_simple`
-- `./test_42-43.py::test_simple`
-- (`./testspam.py::test_simple` not discovered by default)
-- (`./spam.py::test_simple` not discovered)
-
-imports discovered:
-
-- `./v/test_eggs.py::test_simple`
-- `./v/test_eggs.py::TestSimple::test_simple`
-- `./v/test_ham.py::test_simple`
-- `./v/test_ham.py::test_not_hard`
-- `./v/test_spam.py::test_simple`
-- `./v/test_spam.py::test_simpler`
-
-subtests:
-
-- `./test_pytest.py::test_dynamic_*`
-- `./test_pytest.py::test_param_01[]`
-- `./test_pytest.py::test_param_11[1]`
-- `./test_pytest.py::test_param_13[*]`
-- `./test_pytest.py::test_param_13_markers[*]`
-- `./test_pytest.py::test_param_13_repeat[*]`
-- `./test_pytest.py::test_param_13_skipped[*]`
-- `./test_pytest.py::test_param_23_13[*]`
-- `./test_pytest.py::test_param_23_raises[*]`
-- `./test_pytest.py::test_param_33[*]`
-- `./test_pytest.py::test_param_33_ids[*]`
-- `./test_pytest.py::TestParam::test_param_13[*]`
-- `./test_pytest.py::TestParamAll::test_param_13[*]`
-- `./test_pytest.py::TestParamAll::test_spam_13[*]`
-- `./test_pytest.py::test_fixture_param[*]`
-- `./test_pytest.py::test_param_fixture[*]`
-- `./test_pytest_param.py::test_param_13[*]`
-- `./test_pytest_param.py::TestParamAll::test_param_13[*]`
-- `./test_pytest_param.py::TestParamAll::test_spam_13[*]`
-- (`./test_unittest.py::MyTests::test_with_subtests`)
-- (`./test_unittest.py::MyTests::test_with_nested_subtests`)
-- (`./test_unittest.py::MyTests::test_dynamic_*`)
-
-For more options for pytests's parametrize(), see
-https://docs.pytest.org/en/latest/example/parametrize.html#paramexamples.
-
-using fixtures:
-
-- `./test_pytest.py::test_fixture`
-- `./test_pytest.py::test_fixture_param[*]`
-- `./test_pytest.py::test_param_fixture[*]`
-- `./test_pytest.py::test_param_mark_fixture[*]`
-
-other markers:
-
-- `./test_pytest.py::test_known_failure`
-- `./test_pytest.py::test_param_markers[2]`
-- `./test_pytest.py::test_warned`
-- `./test_pytest.py::test_custom_marker`
-- `./test_pytest.py::test_multiple_markers`
-- (`./test_unittest.py::MyTests::test_known_failure`)
-
-others not discovered:
-
-- (`./test_pytest.py::TestSpam::TestHam::TestEggs::TestNoop1`)
-- (`./test_pytest.py::TestSpam::TestNoop2`)
-- (`./test_pytest.py::TestNoop3`)
-- (`./test_pytest.py::MyTests::test_simple`)
-- (`./test_unittest.py::MyTests::TestSub1`)
-- (`./test_unittest.py::MyTests::TestSub2`)
-- (`./test_unittest.py::NoTests`)
-
-doctests:
-
-- `./test_doctest.txt::test_doctest.txt`
-- (`./test_doctest.py::test_doctest.py`)
-- (`../mod.py::mod`)
-- (`../mod.py::mod.square`)
-- (`../mod.py::mod.Spam`)
-- (`../mod.py::mod.spam.eggs`)
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/mod.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/mod.py
deleted file mode 100644
index b8c495503895..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/mod.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""
-
-Examples:
-
->>> square(1)
-1
->>> square(2)
-4
->>> square(3)
-9
->>> spam = Spam()
->>> spam.eggs()
-42
-"""
-
-
-def square(x):
- """
-
- Examples:
-
- >>> square(1)
- 1
- >>> square(2)
- 4
- >>> square(3)
- 9
- """
- return x * x
-
-
-class Spam(object):
- """
-
- Examples:
-
- >>> spam = Spam()
- >>> spam.eggs()
- 42
- """
-
- def eggs(self):
- """
-
- Examples:
-
- >>> spam = Spam()
- >>> spam.eggs()
- 42
- """
- return 42
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/spam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/spam.py
deleted file mode 100644
index 4c4134d75584..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/spam.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py
deleted file mode 100644
index 4c4134d75584..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42-43.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42.py
deleted file mode 100644
index 4c4134d75584..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_42.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py
deleted file mode 100644
index 27cccbdb77cc..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.py
+++ /dev/null
@@ -1,6 +0,0 @@
-"""
-Doctests:
-
->>> 1 == 1
-True
-"""
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt
deleted file mode 100644
index 4b51fde5667e..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_doctest.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-assignment & lookup:
-
->>> x = 3
->>> x
-3
-
-deletion:
-
->>> del x
->>> x
-Traceback (most recent call last):
- ...
-NameError: name 'x' is not defined
-
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_foo.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_foo.py
deleted file mode 100644
index e752106f503a..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_foo.py
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py
deleted file mode 100644
index e9c675647f13..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_mixed.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import pytest
-import unittest
-
-
-def test_top_level():
- assert True
-
-
-@pytest.mark.skip
-def test_skipped():
- assert False
-
-
-class TestMySuite(object):
-
- def test_simple(self):
- assert True
-
-
-class MyTests(unittest.TestCase):
-
- def test_simple(self):
- assert True
-
- @pytest.mark.skip
- def test_skipped(self):
- assert False
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py
deleted file mode 100644
index 39d3ece9c0ba..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# ...
-
-import pytest
-
-
-def test_simple():
- assert True
-
-
-def test_failure():
- assert False
-
-
-def test_runtime_skipped():
- pytest.skip('???')
-
-
-def test_runtime_failed():
- pytest.fail('???')
-
-
-def test_raises():
- raise Exception
-
-
-@pytest.mark.skip
-def test_skipped():
- assert False
-
-
-@pytest.mark.skipif(True)
-def test_maybe_skipped():
- assert False
-
-
-@pytest.mark.xfail
-def test_known_failure():
- assert False
-
-
-@pytest.mark.filterwarnings
-def test_warned():
- assert False
-
-
-@pytest.mark.spam
-def test_custom_marker():
- assert False
-
-
-@pytest.mark.filterwarnings
-@pytest.mark.skip
-@pytest.mark.xfail
-@pytest.mark.skipif(True)
-@pytest.mark.skip
-@pytest.mark.spam
-def test_multiple_markers():
- assert False
-
-
-for i in range(3):
- def func():
- assert True
- globals()['test_dynamic_{}'.format(i + 1)] = func
-del func
-
-
-class TestSpam(object):
-
- def test_simple():
- assert True
-
- @pytest.mark.skip
- def test_skipped(self):
- assert False
-
- class TestHam(object):
-
- class TestEggs(object):
-
- def test_simple():
- assert True
-
- class TestNoop1(object):
- pass
-
- class TestNoop2(object):
- pass
-
-
-class TestEggs(object):
-
- def test_simple():
- assert True
-
-
-# legend for parameterized test names:
-# "test_param_XY[_XY]*"
-# X - # params
-# Y - # cases
-# [_XY]* - extra decorators
-
-@pytest.mark.parametrize('', [()])
-def test_param_01():
- assert True
-
-
-@pytest.mark.parametrize('x', [(1,)])
-def test_param_11(x):
- assert x == 1
-
-
-@pytest.mark.parametrize('x', [(1,), (1.0,), (1+0j,)])
-def test_param_13(x):
- assert x == 1
-
-
-@pytest.mark.parametrize('x', [(1,), (1,), (1,)])
-def test_param_13_repeat(x):
- assert x == 1
-
-
-@pytest.mark.parametrize('x,y,z', [(1, 1, 1), (3, 4, 5), (0, 0, 0)])
-def test_param_33(x, y, z):
- assert x*x + y*y == z*z
-
-
-@pytest.mark.parametrize('x,y,z', [(1, 1, 1), (3, 4, 5), (0, 0, 0)],
- ids=['v1', 'v2', 'v3'])
-def test_param_33_ids(x, y, z):
- assert x*x + y*y == z*z
-
-
-@pytest.mark.parametrize('z', [(1,), (5,), (0,)])
-@pytest.mark.parametrize('x,y', [(1, 1), (3, 4), (0, 0)])
-def test_param_23_13(x, y, z):
- assert x*x + y*y == z*z
-
-
-@pytest.mark.parametrize('x', [
- (1,),
- pytest.param(1.0, marks=[pytest.mark.skip, pytest.mark.spam], id='???'),
- pytest.param(2, marks=[pytest.mark.xfail]),
- ])
-def test_param_13_markers(x):
- assert x == 1
-
-
-@pytest.mark.skip
-@pytest.mark.parametrize('x', [(1,), (1.0,), (1+0j,)])
-def test_param_13_skipped(x):
- assert x == 1
-
-
-@pytest.mark.parametrize('x,catch', [(1, None), (1.0, None), (2, pytest.raises(Exception))])
-def test_param_23_raises(x, catch):
- if x != 1:
- with catch:
- raise Exception
-
-
-class TestParam(object):
-
- def test_simple():
- assert True
-
- @pytest.mark.parametrize('x', [(1,), (1.0,), (1+0j,)])
- def test_param_13(self, x):
- assert x == 1
-
-
-@pytest.mark.parametrize('x', [(1,), (1.0,), (1+0j,)])
-class TestParamAll(object):
-
- def test_param_13(self, x):
- assert x == 1
-
- def test_spam_13(self, x):
- assert x == 1
-
-
-@pytest.fixture
-def spamfix(request):
- yield 'spam'
-
-
-@pytest.fixture(params=['spam', 'eggs'])
-def paramfix(request):
- return request.param
-
-
-def test_fixture(spamfix):
- assert spamfix == 'spam'
-
-
-@pytest.mark.usefixtures('spamfix')
-def test_mark_fixture():
- assert True
-
-
-@pytest.mark.parametrize('x', [(1,), (1.0,), (1+0j,)])
-def test_param_fixture(spamfix, x):
- assert spamfix == 'spam'
- assert x == 1
-
-
-@pytest.mark.parametrize('x', [
- (1,),
- (1.0,),
- pytest.param(1+0j, marks=[pytest.mark.usefixtures('spamfix')]),
- ])
-def test_param_mark_fixture(x):
- assert x == 1
-
-
-def test_fixture_param(paramfix):
- assert paramfix == 'spam'
-
-
-class TestNoop3(object):
- pass
-
-
-class MyTests(object): # does not match default name pattern
-
- def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py
deleted file mode 100644
index bd22d89f42bd..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_pytest_param.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import pytest
-
-
-# module-level parameterization
-pytestmark = pytest.mark.parametrize('x', [(1,), (1.0,), (1+0j,)])
-
-
-def test_param_13(x):
- assert x == 1
-
-
-class TestParamAll(object):
-
- def test_param_13(self, x):
- assert x == 1
-
- def test_spam_13(self, x):
- assert x == 1
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py
deleted file mode 100644
index dd3e82535739..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/test_unittest.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import unittest
-
-
-class MyTests(unittest.TestCase):
-
- def test_simple(self):
- self.assertTrue(True)
-
- @unittest.skip('???')
- def test_skipped(self):
- self.assertTrue(False)
-
- @unittest.skipIf(True, '???')
- def test_maybe_skipped(self):
- self.assertTrue(False)
-
- @unittest.skipUnless(False, '???')
- def test_maybe_not_skipped(self):
- self.assertTrue(False)
-
- def test_skipped_inside(self):
- raise unittest.SkipTest('???')
-
- class TestSub1(object):
-
- def test_simple(self):
- self.assertTrue(True)
-
- class TestSub2(unittest.TestCase):
-
- def test_simple(self):
- self.assertTrue(True)
-
- def test_failure(self):
- raise Exception
-
- @unittest.expectedFailure
- def test_known_failure(self):
- raise Exception
-
- def test_with_subtests(self):
- for i in range(3):
- with self.subtest(i): # This is invalid under Py2.
- self.assertTrue(True)
-
- def test_with_nested_subtests(self):
- for i in range(3):
- with self.subtest(i): # This is invalid under Py2.
- for j in range(3):
- with self.subtest(i): # This is invalid under Py2.
- self.assertTrue(True)
-
- for i in range(3):
- def test_dynamic_(self, i=i):
- self.assertEqual(True)
- test_dynamic_.__name__ += str(i)
-
-
-class OtherTests(unittest.TestCase):
-
- def test_simple(self):
- self.assertTrue(True)
-
-
-class NoTests(unittest.TestCase):
- pass
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/testspam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/testspam.py
deleted file mode 100644
index 7ec91c783e2c..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/testspam.py
+++ /dev/null
@@ -1,9 +0,0 @@
-'''
-...
-...
-...
-'''
-
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/spam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/spam.py
deleted file mode 100644
index 18c92c09306e..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/spam.py
+++ /dev/null
@@ -1,9 +0,0 @@
-
-def test_simple(self):
- assert True
-
-
-class TestSimple(object):
-
- def test_simple(self):
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py
deleted file mode 100644
index f3e7d9517631..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_eggs.py
+++ /dev/null
@@ -1 +0,0 @@
-from .spam import *
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py
deleted file mode 100644
index 6b6a01f87ec5..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_ham.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from .spam import test_simple
-from .spam import test_simple as test_not_hard
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py
deleted file mode 100644
index 18cf56f90533..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/v/test_spam.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from .spam import test_simple
-
-
-def test_simpler(self):
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py
deleted file mode 100644
index 6a0b60d1d5bd..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam.py
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py
deleted file mode 100644
index 6a0b60d1d5bd..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/w/test_spam_ex.py
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py
deleted file mode 100644
index bdb7e4fec3a5..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/a/test_spam.py
+++ /dev/null
@@ -1,12 +0,0 @@
-"""
-...
-"""
-
-
-# ...
-
-ANSWER = 42
-
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py
deleted file mode 100644
index 4923c556c29a..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/b/test_spam.py
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-# ?!?
-CHORUS = 'spamspamspamspamspam...'
-
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py b/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py
deleted file mode 100644
index 4c4134d75584..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/x/y/z/test_ham.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/test_spam.py b/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/test_spam.py
deleted file mode 100644
index 4c4134d75584..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/simple/tests/test_spam.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-def test_simple():
- assert True
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py b/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py
deleted file mode 100644
index 54d6400a3465..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/.data/syntax-error/tests/test_spam.py
+++ /dev/null
@@ -1,7 +0,0 @@
-
-def test_simple():
- assert True
-
-
-# A syntax error:
-:
diff --git a/pythonFiles/tests/testing_tools/adapter/pytest/test_cli.py b/pythonFiles/tests/testing_tools/adapter/pytest/test_cli.py
deleted file mode 100644
index 6f590a31fa56..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/pytest/test_cli.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import unittest
-
-from ....util import Stub, StubProxy
-from testing_tools.adapter.errors import UnsupportedCommandError
-from testing_tools.adapter.pytest._cli import add_subparser
-
-
-class StubSubparsers(StubProxy):
- def __init__(self, stub=None, name="subparsers"):
- super(StubSubparsers, self).__init__(stub, name)
-
- def add_parser(self, name):
- self.add_call("add_parser", None, {"name": name})
- return self.return_add_parser
-
-
-class StubArgParser(StubProxy):
- def __init__(self, stub=None):
- super(StubArgParser, self).__init__(stub, "argparser")
-
- def add_argument(self, *args, **kwargs):
- self.add_call("add_argument", args, kwargs)
-
-
-class AddCLISubparserTests(unittest.TestCase):
- def test_discover(self):
- stub = Stub()
- subparsers = StubSubparsers(stub)
- parser = StubArgParser(stub)
- subparsers.return_add_parser = parser
-
- add_subparser("discover", "pytest", subparsers)
-
- self.assertEqual(
- stub.calls,
- [
- ("subparsers.add_parser", None, {"name": "pytest"}),
- ],
- )
-
- def test_unsupported_command(self):
- subparsers = StubSubparsers(name=None)
- subparsers.return_add_parser = None
-
- with self.assertRaises(UnsupportedCommandError):
- add_subparser("run", "pytest", subparsers)
- with self.assertRaises(UnsupportedCommandError):
- add_subparser("debug", "pytest", subparsers)
- with self.assertRaises(UnsupportedCommandError):
- add_subparser("???", "pytest", subparsers)
- self.assertEqual(
- subparsers.calls,
- [
- ("add_parser", None, {"name": "pytest"}),
- ("add_parser", None, {"name": "pytest"}),
- ("add_parser", None, {"name": "pytest"}),
- ],
- )
diff --git a/pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py b/pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py
deleted file mode 100644
index 83eeaa1f9062..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/pytest/test_discovery.py
+++ /dev/null
@@ -1,1645 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import print_function, unicode_literals
-
-try:
- from io import StringIO
-except ImportError:
- from StringIO import StringIO # type: ignore (for Pylance)
-
-import os
-import sys
-import tempfile
-import unittest
-
-import _pytest.doctest
-import pytest
-from testing_tools.adapter import info
-from testing_tools.adapter import util as adapter_util
-from testing_tools.adapter.pytest import _discovery
-from testing_tools.adapter.pytest import _pytest_item as pytest_item
-
-from .... import util
-
-
-def unique(collection, key):
- result = []
- keys = []
- for item in collection:
- k = key(item)
- if k in keys:
- continue
- result.append(item)
- keys.append(k)
- return result
-
-
-class StubPyTest(util.StubProxy):
- def __init__(self, stub=None):
- super(StubPyTest, self).__init__(stub, "pytest")
- self.return_main = 0
-
- def main(self, args, plugins):
- self.add_call("main", None, {"args": args, "plugins": plugins})
- return self.return_main
-
-
-class StubPlugin(util.StubProxy):
- _started = True
-
- def __init__(self, stub=None, tests=None):
- super(StubPlugin, self).__init__(stub, "plugin")
- if tests is None:
- tests = StubDiscoveredTests(self.stub)
- self._tests = tests
-
- def __getattr__(self, name):
- if not name.startswith("pytest_"):
- raise AttributeError(name)
-
- def func(*args, **kwargs):
- self.add_call(name, args or None, kwargs or None)
-
- return func
-
-
-class StubDiscoveredTests(util.StubProxy):
- NOT_FOUND = object()
-
- def __init__(self, stub=None):
- super(StubDiscoveredTests, self).__init__(stub, "discovered")
- self.return_items = []
- self.return_parents = []
-
- def __len__(self):
- self.add_call("__len__", None, None)
- return len(self.return_items)
-
- def __getitem__(self, index):
- self.add_call("__getitem__", (index,), None)
- return self.return_items[index]
-
- @property
- def parents(self):
- self.add_call("parents", None, None)
- return self.return_parents
-
- def reset(self):
- self.add_call("reset", None, None)
-
- def add_test(self, test, parents):
- self.add_call("add_test", None, {"test": test, "parents": parents})
-
-
-class FakeFunc(object):
- def __init__(self, name):
- self.__name__ = name
-
-
-class FakeMarker(object):
- def __init__(self, name):
- self.name = name
-
-
-class StubPytestItem(util.StubProxy):
- _debugging = False
- _hasfunc = True
-
- def __init__(self, stub=None, **attrs):
- super(StubPytestItem, self).__init__(stub, "pytest.Item")
- if attrs.get("function") is None:
- attrs.pop("function", None)
- self._hasfunc = False
-
- attrs.setdefault("user_properties", [])
-
- slots = getattr(type(self), "__slots__", None)
- if slots:
- for name, value in attrs.items():
- if name in self.__slots__:
- setattr(self, name, value)
- else:
- self.__dict__[name] = value
- else:
- self.__dict__.update(attrs)
-
- if "own_markers" not in attrs:
- self.own_markers = ()
-
- def __repr__(self):
- return object.__repr__(self)
-
- def __getattr__(self, name):
- if not self._debugging:
- self.add_call(name + " (attr)", None, None)
- if name == "function":
- if not self._hasfunc:
- raise AttributeError(name)
-
- def func(*args, **kwargs):
- self.add_call(name, args or None, kwargs or None)
-
- return func
-
-
-class StubSubtypedItem(StubPytestItem):
- @classmethod
- def from_args(cls, *args, **kwargs):
- if not hasattr(cls, "from_parent"):
- return cls(*args, **kwargs)
- self = cls.from_parent(None, name=kwargs["name"], runner=None, dtest=None)
- self.__init__(*args, **kwargs)
- return self
-
- def __init__(self, *args, **kwargs):
- super(StubSubtypedItem, self).__init__(*args, **kwargs)
- if "nodeid" in self.__dict__:
- self._nodeid = self.__dict__.pop("nodeid")
-
- @property
- def location(self):
- return self.__dict__.get("location")
-
-
-class StubFunctionItem(StubSubtypedItem, pytest.Function):
- @property
- def function(self):
- return self.__dict__.get("function")
-
-
-def create_stub_function_item(*args, **kwargs):
- return StubFunctionItem.from_args(*args, **kwargs)
-
-
-class StubDoctestItem(StubSubtypedItem, _pytest.doctest.DoctestItem):
- pass
-
-
-def create_stub_doctest_item(*args, **kwargs):
- return StubDoctestItem.from_args(*args, **kwargs)
-
-
-class StubPytestSession(util.StubProxy):
- def __init__(self, stub=None):
- super(StubPytestSession, self).__init__(stub, "pytest.Session")
-
- def __getattr__(self, name):
- self.add_call(name + " (attr)", None, None)
-
- def func(*args, **kwargs):
- self.add_call(name, args or None, kwargs or None)
-
- return func
-
-
-class StubPytestConfig(util.StubProxy):
- def __init__(self, stub=None):
- super(StubPytestConfig, self).__init__(stub, "pytest.Config")
-
- def __getattr__(self, name):
- self.add_call(name + " (attr)", None, None)
-
- def func(*args, **kwargs):
- self.add_call(name, args or None, kwargs or None)
-
- return func
-
-
-def generate_parse_item(pathsep):
- if pathsep == "\\":
-
- def normcase(path):
- path = path.lower()
- return path.replace("/", "\\")
-
- else:
- raise NotImplementedError
-
- ##########
- def _fix_fileid(*args):
- return adapter_util.fix_fileid(
- *args,
- **dict(
- # dependency injection
- _normcase=normcase,
- _pathsep=pathsep,
- )
- )
-
- def _normalize_test_id(*args):
- return pytest_item._normalize_test_id(
- *args,
- **dict(
- # dependency injection
- _fix_fileid=_fix_fileid,
- _pathsep=pathsep,
- )
- )
-
- def _iter_nodes(*args):
- return pytest_item._iter_nodes(
- *args,
- **dict(
- # dependency injection
- _normalize_test_id=_normalize_test_id,
- _normcase=normcase,
- _pathsep=pathsep,
- )
- )
-
- def _parse_node_id(*args):
- return pytest_item._parse_node_id(
- *args,
- **dict(
- # dependency injection
- _iter_nodes=_iter_nodes,
- )
- )
-
- ##########
- def _split_fspath(*args):
- return pytest_item._split_fspath(
- *args,
- **dict(
- # dependency injection
- _normcase=normcase,
- )
- )
-
- ##########
- def _matches_relfile(*args):
- return pytest_item._matches_relfile(
- *args,
- **dict(
- # dependency injection
- _normcase=normcase,
- _pathsep=pathsep,
- )
- )
-
- def _is_legacy_wrapper(*args):
- return pytest_item._is_legacy_wrapper(
- *args,
- **dict(
- # dependency injection
- _pathsep=pathsep,
- )
- )
-
- def _get_location(*args):
- return pytest_item._get_location(
- *args,
- **dict(
- # dependency injection
- _matches_relfile=_matches_relfile,
- _is_legacy_wrapper=_is_legacy_wrapper,
- _pathsep=pathsep,
- )
- )
-
- ##########
- def _parse_item(item):
- return pytest_item.parse_item(
- item,
- **dict(
- # dependency injection
- _parse_node_id=_parse_node_id,
- _split_fspath=_split_fspath,
- _get_location=_get_location,
- )
- )
-
- return _parse_item
-
-
-##################################
-# tests
-
-
-def fake_pytest_main(stub, use_fd, pytest_stdout):
- def ret(args, plugins):
- stub.add_call("pytest.main", None, {"args": args, "plugins": plugins})
- if use_fd:
- os.write(sys.stdout.fileno(), pytest_stdout.encode())
- else:
- print(pytest_stdout, end="")
- return 0
-
- return ret
-
-
-class DiscoverTests(unittest.TestCase):
- DEFAULT_ARGS = [
- "--collect-only",
- ]
-
- def test_basic(self):
- stub = util.Stub()
- stubpytest = StubPyTest(stub)
- plugin = StubPlugin(stub)
- expected = []
- plugin.discovered = expected
- calls = [
- ("pytest.main", None, {"args": self.DEFAULT_ARGS, "plugins": [plugin]}),
- ("discovered.parents", None, None),
- ("discovered.__len__", None, None),
- ("discovered.__getitem__", (0,), None),
- ]
-
- parents, tests = _discovery.discover(
- [], _pytest_main=stubpytest.main, _plugin=plugin
- )
-
- actual_calls = unique(stub.calls, lambda k: k[0])
- expected_calls = unique(calls, lambda k: k[0])
-
- self.assertEqual(parents, [])
- self.assertEqual(tests, expected)
- self.assertEqual(actual_calls, expected_calls)
-
- def test_failure(self):
- stub = util.Stub()
- pytest = StubPyTest(stub)
- pytest.return_main = 2
- plugin = StubPlugin(stub)
-
- with self.assertRaises(Exception):
- _discovery.discover([], _pytest_main=pytest.main, _plugin=plugin)
-
- self.assertEqual(
- stub.calls,
- [
- # There's only one call.
- ("pytest.main", None, {"args": self.DEFAULT_ARGS, "plugins": [plugin]}),
- ],
- )
-
- def test_no_tests_found(self):
- stub = util.Stub()
- pytest = StubPyTest(stub)
- pytest.return_main = 5
- plugin = StubPlugin(stub)
- expected = []
- plugin.discovered = expected
- calls = [
- ("pytest.main", None, {"args": self.DEFAULT_ARGS, "plugins": [plugin]}),
- ("discovered.parents", None, None),
- ("discovered.__len__", None, None),
- ("discovered.__getitem__", (0,), None),
- ]
-
- parents, tests = _discovery.discover(
- [], _pytest_main=pytest.main, _plugin=plugin
- )
-
- actual_calls = unique(stub.calls, lambda k: k[0])
- expected_calls = unique(calls, lambda k: k[0])
-
- self.assertEqual(parents, [])
- self.assertEqual(tests, expected)
- self.assertEqual(actual_calls, expected_calls)
-
- def test_found_with_collection_error(self):
- stub = util.Stub()
- pytest = StubPyTest(stub)
- pytest.return_main = 1
- plugin = StubPlugin(stub)
- expected = []
- plugin.discovered = expected
- calls = [
- ("pytest.main", None, {"args": self.DEFAULT_ARGS, "plugins": [plugin]}),
- ("discovered.parents", None, None),
- ("discovered.__len__", None, None),
- ("discovered.__getitem__", (0,), None),
- ]
-
- parents, tests = _discovery.discover(
- [], _pytest_main=pytest.main, _plugin=plugin
- )
-
- actual_calls = unique(stub.calls, lambda k: k[0])
- expected_calls = unique(calls, lambda k: k[0])
-
- self.assertEqual(parents, [])
- self.assertEqual(tests, expected)
- self.assertEqual(actual_calls, expected_calls)
-
- def test_stdio_hidden_file(self):
- stub = util.Stub()
-
- plugin = StubPlugin(stub)
- plugin.discovered = []
- calls = [
- ("pytest.main", None, {"args": self.DEFAULT_ARGS, "plugins": [plugin]}),
- ("discovered.parents", None, None),
- ("discovered.__len__", None, None),
- ("discovered.__getitem__", (0,), None),
- ]
- pytest_stdout = "spamspamspamspamspamspamspammityspam"
-
- # to simulate stdio behavior in methods like os.dup,
- # use actual files (rather than StringIO)
- with tempfile.TemporaryFile("r+") as mock:
- sys.stdout = mock
- try:
- _discovery.discover(
- [],
- hidestdio=True,
- _pytest_main=fake_pytest_main(stub, False, pytest_stdout),
- _plugin=plugin,
- )
- finally:
- sys.stdout = sys.__stdout__
-
- mock.seek(0)
- captured = mock.read()
-
- actual_calls = unique(stub.calls, lambda k: k[0])
- expected_calls = unique(calls, lambda k: k[0])
-
- self.assertEqual(captured, "")
- self.assertEqual(actual_calls, expected_calls)
-
- def test_stdio_hidden_fd(self):
- # simulate cases where stdout comes from the lower layer than sys.stdout
- # via file descriptors (e.g., from cython)
- stub = util.Stub()
- plugin = StubPlugin(stub)
- pytest_stdout = "spamspamspamspamspamspamspammityspam"
-
- # Replace with contextlib.redirect_stdout() once Python 2.7 support is dropped.
- sys.stdout = StringIO()
- try:
- _discovery.discover(
- [],
- hidestdio=True,
- _pytest_main=fake_pytest_main(stub, True, pytest_stdout),
- _plugin=plugin,
- )
- captured = sys.stdout.read()
- self.assertEqual(captured, "")
- finally:
- sys.stdout = sys.__stdout__
-
- def test_stdio_not_hidden_file(self):
- stub = util.Stub()
-
- plugin = StubPlugin(stub)
- plugin.discovered = []
- calls = [
- ("pytest.main", None, {"args": self.DEFAULT_ARGS, "plugins": [plugin]}),
- ("discovered.parents", None, None),
- ("discovered.__len__", None, None),
- ("discovered.__getitem__", (0,), None),
- ]
- pytest_stdout = "spamspamspamspamspamspamspammityspam"
-
- buf = StringIO()
-
- sys.stdout = buf
- try:
- _discovery.discover(
- [],
- hidestdio=False,
- _pytest_main=fake_pytest_main(stub, False, pytest_stdout),
- _plugin=plugin,
- )
- finally:
- sys.stdout = sys.__stdout__
- captured = buf.getvalue()
-
- actual_calls = unique(stub.calls, lambda k: k[0])
- expected_calls = unique(calls, lambda k: k[0])
-
- self.assertEqual(captured, pytest_stdout)
- self.assertEqual(actual_calls, expected_calls)
-
- def test_stdio_not_hidden_fd(self):
- # simulate cases where stdout comes from the lower layer than sys.stdout
- # via file descriptors (e.g., from cython)
- stub = util.Stub()
- plugin = StubPlugin(stub)
- pytest_stdout = "spamspamspamspamspamspamspammityspam"
- stub.calls = []
- with tempfile.TemporaryFile("r+") as mock:
- sys.stdout = mock
- try:
- _discovery.discover(
- [],
- hidestdio=False,
- _pytest_main=fake_pytest_main(stub, True, pytest_stdout),
- _plugin=plugin,
- )
- finally:
- mock.seek(0)
- captured = sys.stdout.read()
- sys.stdout = sys.__stdout__
- self.assertEqual(captured, pytest_stdout)
-
-
-class CollectorTests(unittest.TestCase):
- def test_modifyitems(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- config = StubPytestConfig(stub)
- collector = _discovery.TestCollector(tests=discovered)
-
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile1 = adapter_util.fix_path("./test_spam.py")
- relfile2 = adapter_util.fix_path("x/y/z/test_eggs.py")
-
- collector.pytest_collection_modifyitems(
- session,
- config,
- [
- create_stub_function_item(
- stub,
- nodeid="test_spam.py::SpamTests::test_one",
- name="test_one",
- originalname=None,
- location=("test_spam.py", 12, "SpamTests.test_one"),
- path=adapter_util.PATH_JOIN(testroot, "test_spam.py"),
- function=FakeFunc("test_one"),
- ),
- create_stub_function_item(
- stub,
- nodeid="test_spam.py::SpamTests::test_other",
- name="test_other",
- originalname=None,
- location=("test_spam.py", 19, "SpamTests.test_other"),
- path=adapter_util.PATH_JOIN(testroot, "test_spam.py"),
- function=FakeFunc("test_other"),
- ),
- create_stub_function_item(
- stub,
- nodeid="test_spam.py::test_all",
- name="test_all",
- originalname=None,
- location=("test_spam.py", 144, "test_all"),
- path=adapter_util.PATH_JOIN(testroot, "test_spam.py"),
- function=FakeFunc("test_all"),
- ),
- create_stub_function_item(
- stub,
- nodeid="test_spam.py::test_each[10-10]",
- name="test_each[10-10]",
- originalname="test_each",
- location=("test_spam.py", 273, "test_each[10-10]"),
- path=adapter_util.PATH_JOIN(testroot, "test_spam.py"),
- function=FakeFunc("test_each"),
- ),
- create_stub_function_item(
- stub,
- nodeid=relfile2 + "::All::BasicTests::test_first",
- name="test_first",
- originalname=None,
- location=(relfile2, 31, "All.BasicTests.test_first"),
- path=adapter_util.PATH_JOIN(testroot, relfile2),
- function=FakeFunc("test_first"),
- ),
- create_stub_function_item(
- stub,
- nodeid=relfile2 + "::All::BasicTests::test_each[1+2-3]",
- name="test_each[1+2-3]",
- originalname="test_each",
- location=(relfile2, 62, "All.BasicTests.test_each[1+2-3]"),
- path=adapter_util.PATH_JOIN(testroot, relfile2),
- function=FakeFunc("test_each"),
- own_markers=[
- FakeMarker(v)
- for v in [
- # supported
- "skip",
- "skipif",
- "xfail",
- # duplicate
- "skip",
- # ignored (pytest-supported)
- "parameterize",
- "usefixtures",
- "filterwarnings",
- # ignored (custom)
- "timeout",
- ]
- ],
- ),
- ],
- )
-
- self.maxDiff = None
- expected = [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./test_spam.py::SpamTests", "SpamTests", "suite"),
- ("./test_spam.py", "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./test_spam.py::SpamTests::test_one",
- name="test_one",
- path=info.SingleTestPath(
- root=testroot,
- relfile=relfile1,
- func="SpamTests.test_one",
- sub=None,
- ),
- source="{}:{}".format(relfile1, 13),
- markers=None,
- parentid="./test_spam.py::SpamTests",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./test_spam.py::SpamTests", "SpamTests", "suite"),
- ("./test_spam.py", "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./test_spam.py::SpamTests::test_other",
- name="test_other",
- path=info.SingleTestPath(
- root=testroot,
- relfile=relfile1,
- func="SpamTests.test_other",
- sub=None,
- ),
- source="{}:{}".format(relfile1, 20),
- markers=None,
- parentid="./test_spam.py::SpamTests",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./test_spam.py", "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./test_spam.py::test_all",
- name="test_all",
- path=info.SingleTestPath(
- root=testroot,
- relfile=relfile1,
- func="test_all",
- sub=None,
- ),
- source="{}:{}".format(relfile1, 145),
- markers=None,
- parentid="./test_spam.py",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./test_spam.py::test_each", "test_each", "function"),
- ("./test_spam.py", "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./test_spam.py::test_each[10-10]",
- name="10-10",
- path=info.SingleTestPath(
- root=testroot,
- relfile=relfile1,
- func="test_each",
- sub=["[10-10]"],
- ),
- source="{}:{}".format(relfile1, 274),
- markers=None,
- parentid="./test_spam.py::test_each",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (
- "./x/y/z/test_eggs.py::All::BasicTests",
- "BasicTests",
- "suite",
- ),
- ("./x/y/z/test_eggs.py::All", "All", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::All::BasicTests::test_first",
- name="test_first",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile2),
- func="All.BasicTests.test_first",
- sub=None,
- ),
- source="{}:{}".format(adapter_util.fix_relpath(relfile2), 32),
- markers=None,
- parentid="./x/y/z/test_eggs.py::All::BasicTests",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (
- "./x/y/z/test_eggs.py::All::BasicTests::test_each",
- "test_each",
- "function",
- ),
- (
- "./x/y/z/test_eggs.py::All::BasicTests",
- "BasicTests",
- "suite",
- ),
- ("./x/y/z/test_eggs.py::All", "All", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::All::BasicTests::test_each[1+2-3]",
- name="1+2-3",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile2),
- func="All.BasicTests.test_each",
- sub=["[1+2-3]"],
- ),
- source="{}:{}".format(adapter_util.fix_relpath(relfile2), 63),
- markers=["expected-failure", "skip", "skip-if"],
- parentid="./x/y/z/test_eggs.py::All::BasicTests::test_each",
- ),
- ),
- ),
- ]
- self.assertEqual(stub.calls, expected)
-
- def test_finish(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- session.items = [
- create_stub_function_item(
- stub,
- nodeid=relfile + "::SpamTests::test_spam",
- name="test_spam",
- originalname=None,
- location=(relfile, 12, "SpamTests.test_spam"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py::SpamTests", "SpamTests", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::SpamTests::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="SpamTests.test_spam",
- sub=None,
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
- markers=None,
- parentid="./x/y/z/test_eggs.py::SpamTests",
- ),
- ),
- ),
- ],
- )
-
- def test_doctest(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- doctestfile = adapter_util.fix_path("x/test_doctest.txt")
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- session.items = [
- create_stub_doctest_item(
- stub,
- nodeid=doctestfile + "::test_doctest.txt",
- name="test_doctest.txt",
- location=(doctestfile, 0, "[doctest] test_doctest.txt"),
- path=adapter_util.PATH_JOIN(testroot, doctestfile),
- ),
- # With --doctest-modules
- create_stub_doctest_item(
- stub,
- nodeid=relfile + "::test_eggs",
- name="test_eggs",
- location=(relfile, 0, "[doctest] test_eggs"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- ),
- create_stub_doctest_item(
- stub,
- nodeid=relfile + "::test_eggs.TestSpam",
- name="test_eggs.TestSpam",
- location=(relfile, 12, "[doctest] test_eggs.TestSpam"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- ),
- create_stub_doctest_item(
- stub,
- nodeid=relfile + "::test_eggs.TestSpam.TestEggs",
- name="test_eggs.TestSpam.TestEggs",
- location=(relfile, 27, "[doctest] test_eggs.TestSpam.TestEggs"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/test_doctest.txt", "test_doctest.txt", "file"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/test_doctest.txt::test_doctest.txt",
- name="test_doctest.txt",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(doctestfile),
- func=None,
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(doctestfile), 1
- ),
- markers=[],
- parentid="./x/test_doctest.txt",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::test_eggs",
- name="test_eggs",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func=None,
- ),
- source="{}:{}".format(adapter_util.fix_relpath(relfile), 1),
- markers=[],
- parentid="./x/y/z/test_eggs.py",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::test_eggs.TestSpam",
- name="test_eggs.TestSpam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func=None,
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
- markers=[],
- parentid="./x/y/z/test_eggs.py",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::test_eggs.TestSpam.TestEggs",
- name="test_eggs.TestSpam.TestEggs",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func=None,
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 28
- ),
- markers=[],
- parentid="./x/y/z/test_eggs.py",
- ),
- ),
- ),
- ],
- )
-
- def test_nested_brackets(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- session.items = [
- create_stub_function_item(
- stub,
- nodeid=relfile + "::SpamTests::test_spam[a-[b]-c]",
- name="test_spam[a-[b]-c]",
- originalname="test_spam",
- location=(relfile, 12, "SpamTests.test_spam[a-[b]-c]"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (
- "./x/y/z/test_eggs.py::SpamTests::test_spam",
- "test_spam",
- "function",
- ),
- ("./x/y/z/test_eggs.py::SpamTests", "SpamTests", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::SpamTests::test_spam[a-[b]-c]",
- name="a-[b]-c",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="SpamTests.test_spam",
- sub=["[a-[b]-c]"],
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
- markers=None,
- parentid="./x/y/z/test_eggs.py::SpamTests::test_spam",
- ),
- ),
- ),
- ],
- )
-
- def test_nested_suite(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- session.items = [
- create_stub_function_item(
- stub,
- nodeid=relfile + "::SpamTests::Ham::Eggs::test_spam",
- name="test_spam",
- originalname=None,
- location=(relfile, 12, "SpamTests.Ham.Eggs.test_spam"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (
- "./x/y/z/test_eggs.py::SpamTests::Ham::Eggs",
- "Eggs",
- "suite",
- ),
- ("./x/y/z/test_eggs.py::SpamTests::Ham", "Ham", "suite"),
- ("./x/y/z/test_eggs.py::SpamTests", "SpamTests", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::SpamTests::Ham::Eggs::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="SpamTests.Ham.Eggs.test_spam",
- sub=None,
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
- markers=None,
- parentid="./x/y/z/test_eggs.py::SpamTests::Ham::Eggs",
- ),
- ),
- ),
- ],
- )
-
- @pytest.mark.skipif(sys.platform != "win32", reason="Windows specific test.")
- def test_windows(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = r"C:\A\B\C"
- relfile = r"X\Y\Z\test_Eggs.py"
- session.items = [
- # typical:
- create_stub_function_item(
- stub,
- # pytest always uses "/" as the path separator in node IDs:
- nodeid="X/Y/Z/test_Eggs.py::SpamTests::test_spam",
- name="test_spam",
- originalname=None,
- # normal path separator (contrast with nodeid):
- location=(relfile, 12, "SpamTests.test_spam"),
- # path separator matches location:
- path=testroot + "\\" + relfile,
- function=FakeFunc("test_spam"),
- ),
- ]
- tests = [
- # permutations of path separators
- (r"X/test_a.py", "\\", "\\"), # typical
- (r"X/test_b.py", "\\", "/"),
- (r"X/test_c.py", "/", "\\"),
- (r"X/test_d.py", "/", "/"),
- (r"X\test_e.py", "\\", "\\"),
- (r"X\test_f.py", "\\", "/"),
- (r"X\test_g.py", "/", "\\"),
- (r"X\test_h.py", "/", "/"),
- ]
- for fileid, locfile, fspath in tests:
- if locfile == "/":
- locfile = fileid.replace("\\", "/")
- elif locfile == "\\":
- locfile = fileid.replace("/", "\\")
- if fspath == "/":
- fspath = (testroot + "/" + fileid).replace("\\", "/")
- elif fspath == "\\":
- fspath = (testroot + "/" + fileid).replace("/", "\\")
- session.items.append(
- create_stub_function_item(
- stub,
- nodeid=fileid + "::test_spam",
- name="test_spam",
- originalname=None,
- location=(locfile, 12, "test_spam"),
- path=fspath,
- function=FakeFunc("test_spam"),
- )
- )
- collector = _discovery.TestCollector(tests=discovered)
- if os.name != "nt":
- collector.parse_item = generate_parse_item("\\")
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- expected = [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/Y/Z/test_Eggs.py::SpamTests", "SpamTests", "suite"),
- (r"./X/Y/Z/test_Eggs.py", "test_Eggs.py", "file"),
- (r"./X/Y/Z", "Z", "folder"),
- (r"./X/Y", "Y", "folder"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/Y/Z/test_Eggs.py::SpamTests::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot, # not normalized
- relfile=r".\X\Y\Z\test_Eggs.py", # not normalized
- func="SpamTests.test_spam",
- sub=None,
- ),
- source=r".\X\Y\Z\test_Eggs.py:13", # not normalized
- markers=None,
- parentid=r"./X/Y/Z/test_Eggs.py::SpamTests",
- ),
- ),
- ),
- # permutations
- # (*all* the IDs use "/")
- # (source path separator should match relfile, not location)
- # /, \, \
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_a.py", "test_a.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_a.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_a.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_a.py:13",
- markers=None,
- parentid=r"./X/test_a.py",
- ),
- ),
- ),
- # /, \, /
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_b.py", "test_b.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_b.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_b.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_b.py:13",
- markers=None,
- parentid=r"./X/test_b.py",
- ),
- ),
- ),
- # /, /, \
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_c.py", "test_c.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_c.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_c.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_c.py:13",
- markers=None,
- parentid=r"./X/test_c.py",
- ),
- ),
- ),
- # /, /, /
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_d.py", "test_d.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_d.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_d.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_d.py:13",
- markers=None,
- parentid=r"./X/test_d.py",
- ),
- ),
- ),
- # \, \, \
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_e.py", "test_e.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_e.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_e.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_e.py:13",
- markers=None,
- parentid=r"./X/test_e.py",
- ),
- ),
- ),
- # \, \, /
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_f.py", "test_f.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_f.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_f.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_f.py:13",
- markers=None,
- parentid=r"./X/test_f.py",
- ),
- ),
- ),
- # \, /, \
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_g.py", "test_g.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_g.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_g.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_g.py:13",
- markers=None,
- parentid=r"./X/test_g.py",
- ),
- ),
- ),
- # \, /, /
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- (r"./X/test_h.py", "test_h.py", "file"),
- (r"./X", "X", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id=r"./X/test_h.py::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=r".\X\test_h.py",
- func="test_spam",
- sub=None,
- ),
- source=r".\X\test_h.py:13",
- markers=None,
- parentid=r"./X/test_h.py",
- ),
- ),
- ),
- ]
- self.assertEqual(stub.calls, expected)
-
- def test_mysterious_parens(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- session.items = [
- create_stub_function_item(
- stub,
- nodeid=relfile + "::SpamTests::()::()::test_spam",
- name="test_spam",
- originalname=None,
- location=(relfile, 12, "SpamTests.test_spam"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py::SpamTests", "SpamTests", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::SpamTests::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="SpamTests.test_spam",
- sub=[],
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
- markers=None,
- parentid="./x/y/z/test_eggs.py::SpamTests",
- ),
- ),
- ),
- ],
- )
-
- def test_mysterious_colons(self):
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- session.items = [
- create_stub_function_item(
- stub,
- nodeid=relfile + "::SpamTests:::()::test_spam",
- name="test_spam",
- originalname=None,
- location=(relfile, 12, "SpamTests.test_spam"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py::SpamTests", "SpamTests", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::SpamTests::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="SpamTests.test_spam",
- sub=[],
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(relfile), 13
- ),
- markers=None,
- parentid="./x/y/z/test_eggs.py::SpamTests",
- ),
- ),
- ),
- ],
- )
-
- def test_imported_test(self):
- # pytest will even discover tests that were imported from
- # another module!
- stub = util.Stub()
- discovered = StubDiscoveredTests(stub)
- session = StubPytestSession(stub)
- testroot = adapter_util.ABS_PATH(adapter_util.fix_path("/a/b/c"))
- relfile = adapter_util.fix_path("x/y/z/test_eggs.py")
- srcfile = adapter_util.fix_path("x/y/z/_extern.py")
- session.items = [
- create_stub_function_item(
- stub,
- nodeid=relfile + "::SpamTests::test_spam",
- name="test_spam",
- originalname=None,
- location=(srcfile, 12, "SpamTests.test_spam"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- create_stub_function_item(
- stub,
- nodeid=relfile + "::test_ham",
- name="test_ham",
- originalname=None,
- location=(srcfile, 3, "test_ham"),
- path=adapter_util.PATH_JOIN(testroot, relfile),
- function=FakeFunc("test_spam"),
- ),
- ]
- collector = _discovery.TestCollector(tests=discovered)
-
- collector.pytest_collection_finish(session)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("discovered.reset", None, None),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py::SpamTests", "SpamTests", "suite"),
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::SpamTests::test_spam",
- name="test_spam",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="SpamTests.test_spam",
- sub=None,
- ),
- source="{}:{}".format(
- adapter_util.fix_relpath(srcfile), 13
- ),
- markers=None,
- parentid="./x/y/z/test_eggs.py::SpamTests",
- ),
- ),
- ),
- (
- "discovered.add_test",
- None,
- dict(
- parents=[
- ("./x/y/z/test_eggs.py", "test_eggs.py", "file"),
- ("./x/y/z", "z", "folder"),
- ("./x/y", "y", "folder"),
- ("./x", "x", "folder"),
- (".", testroot, "folder"),
- ],
- test=info.SingleTestInfo(
- id="./x/y/z/test_eggs.py::test_ham",
- name="test_ham",
- path=info.SingleTestPath(
- root=testroot,
- relfile=adapter_util.fix_relpath(relfile),
- func="test_ham",
- sub=None,
- ),
- source="{}:{}".format(adapter_util.fix_relpath(srcfile), 4),
- markers=None,
- parentid="./x/y/z/test_eggs.py",
- ),
- ),
- ),
- ],
- )
diff --git a/pythonFiles/tests/testing_tools/adapter/test___main__.py b/pythonFiles/tests/testing_tools/adapter/test___main__.py
deleted file mode 100644
index 5ff0ec30c947..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/test___main__.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import unittest
-
-from testing_tools.adapter.__main__ import (
- UnsupportedCommandError,
- UnsupportedToolError,
- main,
- parse_args,
-)
-
-from ...util import Stub, StubProxy
-
-
-class StubTool(StubProxy):
- def __init__(self, name, stub=None):
- super(StubTool, self).__init__(stub, name)
- self.return_discover = None
-
- def discover(self, args, **kwargs):
- self.add_call("discover", (args,), kwargs)
- if self.return_discover is None:
- raise NotImplementedError
- return self.return_discover
-
-
-class StubReporter(StubProxy):
- def __init__(self, stub=None):
- super(StubReporter, self).__init__(stub, "reporter")
-
- def report(self, tests, parents, **kwargs):
- self.add_call("report", (tests, parents), kwargs or None)
-
-
-##################################
-# tests
-
-
-class ParseGeneralTests(unittest.TestCase):
- def test_unsupported_command(self):
- with self.assertRaises(SystemExit):
- parse_args(["run", "pytest"])
- with self.assertRaises(SystemExit):
- parse_args(["debug", "pytest"])
- with self.assertRaises(SystemExit):
- parse_args(["???", "pytest"])
-
-
-class ParseDiscoverTests(unittest.TestCase):
- def test_pytest_default(self):
- tool, cmd, args, toolargs = parse_args(
- [
- "discover",
- "pytest",
- ]
- )
-
- self.assertEqual(tool, "pytest")
- self.assertEqual(cmd, "discover")
- self.assertEqual(args, {"pretty": False, "hidestdio": True, "simple": False})
- self.assertEqual(toolargs, [])
-
- def test_pytest_full(self):
- tool, cmd, args, toolargs = parse_args(
- [
- "discover",
- "pytest",
- # no adapter-specific options yet
- "--",
- "--strict",
- "--ignore",
- "spam,ham,eggs",
- "--pastebin=xyz",
- "--no-cov",
- "-d",
- ]
- )
-
- self.assertEqual(tool, "pytest")
- self.assertEqual(cmd, "discover")
- self.assertEqual(args, {"pretty": False, "hidestdio": True, "simple": False})
- self.assertEqual(
- toolargs,
- [
- "--strict",
- "--ignore",
- "spam,ham,eggs",
- "--pastebin=xyz",
- "--no-cov",
- "-d",
- ],
- )
-
- def test_pytest_opts(self):
- tool, cmd, args, toolargs = parse_args(
- [
- "discover",
- "pytest",
- "--simple",
- "--no-hide-stdio",
- "--pretty",
- ]
- )
-
- self.assertEqual(tool, "pytest")
- self.assertEqual(cmd, "discover")
- self.assertEqual(args, {"pretty": True, "hidestdio": False, "simple": True})
- self.assertEqual(toolargs, [])
-
- def test_unsupported_tool(self):
- with self.assertRaises(SystemExit):
- parse_args(["discover", "unittest"])
- with self.assertRaises(SystemExit):
- parse_args(["discover", "???"])
-
-
-class MainTests(unittest.TestCase):
- # TODO: We could use an integration test for pytest.discover().
-
- def test_discover(self):
- stub = Stub()
- tool = StubTool("spamspamspam", stub)
- tests, parents = object(), object()
- tool.return_discover = (parents, tests)
- reporter = StubReporter(stub)
- main(
- tool.name,
- "discover",
- {"spam": "eggs"},
- [],
- _tools={
- tool.name: {
- "discover": tool.discover,
- }
- },
- _reporters={
- "discover": reporter.report,
- },
- )
-
- self.assertEqual(
- tool.calls,
- [
- ("spamspamspam.discover", ([],), {"spam": "eggs"}),
- ("reporter.report", (tests, parents), {"spam": "eggs"}),
- ],
- )
-
- def test_unsupported_tool(self):
- with self.assertRaises(UnsupportedToolError):
- main(
- "unittest",
- "discover",
- {"spam": "eggs"},
- [],
- _tools={"pytest": None},
- _reporters=None,
- )
- with self.assertRaises(UnsupportedToolError):
- main(
- "???",
- "discover",
- {"spam": "eggs"},
- [],
- _tools={"pytest": None},
- _reporters=None,
- )
-
- def test_unsupported_command(self):
- tool = StubTool("pytest")
- with self.assertRaises(UnsupportedCommandError):
- main(
- "pytest",
- "run",
- {"spam": "eggs"},
- [],
- _tools={"pytest": {"discover": tool.discover}},
- _reporters=None,
- )
- with self.assertRaises(UnsupportedCommandError):
- main(
- "pytest",
- "debug",
- {"spam": "eggs"},
- [],
- _tools={"pytest": {"discover": tool.discover}},
- _reporters=None,
- )
- with self.assertRaises(UnsupportedCommandError):
- main(
- "pytest",
- "???",
- {"spam": "eggs"},
- [],
- _tools={"pytest": {"discover": tool.discover}},
- _reporters=None,
- )
- self.assertEqual(tool.calls, [])
diff --git a/pythonFiles/tests/testing_tools/adapter/test_discovery.py b/pythonFiles/tests/testing_tools/adapter/test_discovery.py
deleted file mode 100644
index cf3b8fb3139b..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/test_discovery.py
+++ /dev/null
@@ -1,674 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import, print_function
-
-import unittest
-
-from testing_tools.adapter.discovery import DiscoveredTests, fix_nodeid
-from testing_tools.adapter.info import ParentInfo, SingleTestInfo, SingleTestPath
-from testing_tools.adapter.util import fix_path, fix_relpath
-
-
-def _fix_nodeid(nodeid):
- nodeid = nodeid.replace("\\", "/")
- if not nodeid.startswith("./"):
- nodeid = "./" + nodeid
- return nodeid
-
-
-class DiscoveredTestsTests(unittest.TestCase):
- def test_list(self):
- testroot = fix_path("/a/b/c")
- relfile = fix_path("./test_spam.py")
- tests = [
- SingleTestInfo(
- # missing "./":
- id="test_spam.py::test_each[10-10]",
- name="test_each[10-10]",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func="test_each",
- sub=["[10-10]"],
- ),
- source="{}:{}".format(relfile, 10),
- markers=None,
- # missing "./":
- parentid="test_spam.py::test_each",
- ),
- SingleTestInfo(
- id="test_spam.py::All::BasicTests::test_first",
- name="test_first",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func="All.BasicTests.test_first",
- sub=None,
- ),
- source="{}:{}".format(relfile, 62),
- markers=None,
- parentid="test_spam.py::All::BasicTests",
- ),
- ]
- allparents = [
- [
- (fix_path("./test_spam.py::test_each"), "test_each", "function"),
- (fix_path("./test_spam.py"), "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- [
- (fix_path("./test_spam.py::All::BasicTests"), "BasicTests", "suite"),
- (fix_path("./test_spam.py::All"), "All", "suite"),
- (fix_path("./test_spam.py"), "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- ]
- expected = [
- test._replace(id=_fix_nodeid(test.id), parentid=_fix_nodeid(test.parentid))
- for test in tests
- ]
- discovered = DiscoveredTests()
- for test, parents in zip(tests, allparents):
- discovered.add_test(test, parents)
- size = len(discovered)
- items = [discovered[0], discovered[1]]
- snapshot = list(discovered)
-
- self.maxDiff = None
- self.assertEqual(size, 2)
- self.assertEqual(items, expected)
- self.assertEqual(snapshot, expected)
-
- def test_reset(self):
- testroot = fix_path("/a/b/c")
- discovered = DiscoveredTests()
- discovered.add_test(
- SingleTestInfo(
- id="./test_spam.py::test_each",
- name="test_each",
- path=SingleTestPath(
- root=testroot,
- relfile="test_spam.py",
- func="test_each",
- ),
- source="test_spam.py:11",
- markers=[],
- parentid="./test_spam.py",
- ),
- [
- ("./test_spam.py", "test_spam.py", "file"),
- (".", testroot, "folder"),
- ],
- )
-
- before = len(discovered), len(discovered.parents)
- discovered.reset()
- after = len(discovered), len(discovered.parents)
-
- self.assertEqual(before, (1, 2))
- self.assertEqual(after, (0, 0))
-
- def test_parents(self):
- testroot = fix_path("/a/b/c")
- relfile = fix_path("x/y/z/test_spam.py")
- tests = [
- SingleTestInfo(
- # missing "./", using pathsep:
- id=relfile + "::test_each[10-10]",
- name="test_each[10-10]",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_relpath(relfile),
- func="test_each",
- sub=["[10-10]"],
- ),
- source="{}:{}".format(relfile, 10),
- markers=None,
- # missing "./", using pathsep:
- parentid=relfile + "::test_each",
- ),
- SingleTestInfo(
- # missing "./", using pathsep:
- id=relfile + "::All::BasicTests::test_first",
- name="test_first",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_relpath(relfile),
- func="All.BasicTests.test_first",
- sub=None,
- ),
- source="{}:{}".format(relfile, 61),
- markers=None,
- # missing "./", using pathsep:
- parentid=relfile + "::All::BasicTests",
- ),
- ]
- allparents = [
- # missing "./", using pathsep:
- [
- (relfile + "::test_each", "test_each", "function"),
- (relfile, relfile, "file"),
- (".", testroot, "folder"),
- ],
- # missing "./", using pathsep:
- [
- (relfile + "::All::BasicTests", "BasicTests", "suite"),
- (relfile + "::All", "All", "suite"),
- (relfile, "test_spam.py", "file"),
- (fix_path("x/y/z"), "z", "folder"),
- (fix_path("x/y"), "y", "folder"),
- (fix_path("./x"), "x", "folder"),
- (".", testroot, "folder"),
- ],
- ]
- discovered = DiscoveredTests()
- for test, parents in zip(tests, allparents):
- discovered.add_test(test, parents)
-
- parents = discovered.parents
-
- self.maxDiff = None
- self.assertEqual(
- parents,
- [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot,
- ),
- ParentInfo(
- id="./x",
- kind="folder",
- name="x",
- root=testroot,
- relpath=fix_path("./x"),
- parentid=".",
- ),
- ParentInfo(
- id="./x/y",
- kind="folder",
- name="y",
- root=testroot,
- relpath=fix_path("./x/y"),
- parentid="./x",
- ),
- ParentInfo(
- id="./x/y/z",
- kind="folder",
- name="z",
- root=testroot,
- relpath=fix_path("./x/y/z"),
- parentid="./x/y",
- ),
- ParentInfo(
- id="./x/y/z/test_spam.py",
- kind="file",
- name="test_spam.py",
- root=testroot,
- relpath=fix_relpath(relfile),
- parentid="./x/y/z",
- ),
- ParentInfo(
- id="./x/y/z/test_spam.py::All",
- kind="suite",
- name="All",
- root=testroot,
- parentid="./x/y/z/test_spam.py",
- ),
- ParentInfo(
- id="./x/y/z/test_spam.py::All::BasicTests",
- kind="suite",
- name="BasicTests",
- root=testroot,
- parentid="./x/y/z/test_spam.py::All",
- ),
- ParentInfo(
- id="./x/y/z/test_spam.py::test_each",
- kind="function",
- name="test_each",
- root=testroot,
- parentid="./x/y/z/test_spam.py",
- ),
- ],
- )
-
- def test_add_test_simple(self):
- testroot = fix_path("/a/b/c")
- relfile = "test_spam.py"
- test = SingleTestInfo(
- # missing "./":
- id=relfile + "::test_spam",
- name="test_spam",
- path=SingleTestPath(
- root=testroot,
- # missing "./":
- relfile=relfile,
- func="test_spam",
- ),
- # missing "./":
- source="{}:{}".format(relfile, 11),
- markers=[],
- # missing "./":
- parentid=relfile,
- )
- expected = test._replace(
- id=_fix_nodeid(test.id), parentid=_fix_nodeid(test.parentid)
- )
- discovered = DiscoveredTests()
-
- before = list(discovered), discovered.parents
- discovered.add_test(
- test,
- [
- (relfile, relfile, "file"),
- (".", testroot, "folder"),
- ],
- )
- after = list(discovered), discovered.parents
-
- self.maxDiff = None
- self.assertEqual(before, ([], []))
- self.assertEqual(
- after,
- (
- [expected],
- [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot,
- ),
- ParentInfo(
- id="./test_spam.py",
- kind="file",
- name=relfile,
- root=testroot,
- relpath=relfile,
- parentid=".",
- ),
- ],
- ),
- )
-
- def test_multiroot(self):
- # the first root
- testroot1 = fix_path("/a/b/c")
- relfile1 = "test_spam.py"
- alltests = [
- SingleTestInfo(
- # missing "./":
- id=relfile1 + "::test_spam",
- name="test_spam",
- path=SingleTestPath(
- root=testroot1,
- relfile=fix_relpath(relfile1),
- func="test_spam",
- ),
- source="{}:{}".format(relfile1, 10),
- markers=[],
- # missing "./":
- parentid=relfile1,
- ),
- ]
- allparents = [
- # missing "./":
- [
- (relfile1, "test_spam.py", "file"),
- (".", testroot1, "folder"),
- ],
- ]
- # the second root
- testroot2 = fix_path("/x/y/z")
- relfile2 = fix_path("w/test_eggs.py")
- alltests.extend(
- [
- SingleTestInfo(
- id=relfile2 + "::BasicTests::test_first",
- name="test_first",
- path=SingleTestPath(
- root=testroot2,
- relfile=fix_relpath(relfile2),
- func="BasicTests.test_first",
- ),
- source="{}:{}".format(relfile2, 61),
- markers=[],
- parentid=relfile2 + "::BasicTests",
- ),
- ]
- )
- allparents.extend(
- [
- # missing "./", using pathsep:
- [
- (relfile2 + "::BasicTests", "BasicTests", "suite"),
- (relfile2, "test_eggs.py", "file"),
- (fix_path("./w"), "w", "folder"),
- (".", testroot2, "folder"),
- ],
- ]
- )
-
- discovered = DiscoveredTests()
- for test, parents in zip(alltests, allparents):
- discovered.add_test(test, parents)
- tests = list(discovered)
- parents = discovered.parents
-
- self.maxDiff = None
- self.assertEqual(
- tests,
- [
- # the first root
- SingleTestInfo(
- id="./test_spam.py::test_spam",
- name="test_spam",
- path=SingleTestPath(
- root=testroot1,
- relfile=fix_relpath(relfile1),
- func="test_spam",
- ),
- source="{}:{}".format(relfile1, 10),
- markers=[],
- parentid="./test_spam.py",
- ),
- # the secondroot
- SingleTestInfo(
- id="./w/test_eggs.py::BasicTests::test_first",
- name="test_first",
- path=SingleTestPath(
- root=testroot2,
- relfile=fix_relpath(relfile2),
- func="BasicTests.test_first",
- ),
- source="{}:{}".format(relfile2, 61),
- markers=[],
- parentid="./w/test_eggs.py::BasicTests",
- ),
- ],
- )
- self.assertEqual(
- parents,
- [
- # the first root
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot1,
- ),
- ParentInfo(
- id="./test_spam.py",
- kind="file",
- name="test_spam.py",
- root=testroot1,
- relpath=fix_relpath(relfile1),
- parentid=".",
- ),
- # the secondroot
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot2,
- ),
- ParentInfo(
- id="./w",
- kind="folder",
- name="w",
- root=testroot2,
- relpath=fix_path("./w"),
- parentid=".",
- ),
- ParentInfo(
- id="./w/test_eggs.py",
- kind="file",
- name="test_eggs.py",
- root=testroot2,
- relpath=fix_relpath(relfile2),
- parentid="./w",
- ),
- ParentInfo(
- id="./w/test_eggs.py::BasicTests",
- kind="suite",
- name="BasicTests",
- root=testroot2,
- parentid="./w/test_eggs.py",
- ),
- ],
- )
-
- def test_doctest(self):
- testroot = fix_path("/a/b/c")
- doctestfile = fix_path("./x/test_doctest.txt")
- relfile = fix_path("./x/y/z/test_eggs.py")
- alltests = [
- SingleTestInfo(
- id=doctestfile + "::test_doctest.txt",
- name="test_doctest.txt",
- path=SingleTestPath(
- root=testroot,
- relfile=doctestfile,
- func=None,
- ),
- source="{}:{}".format(doctestfile, 0),
- markers=[],
- parentid=doctestfile,
- ),
- # With --doctest-modules
- SingleTestInfo(
- id=relfile + "::test_eggs",
- name="test_eggs",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func=None,
- ),
- source="{}:{}".format(relfile, 0),
- markers=[],
- parentid=relfile,
- ),
- SingleTestInfo(
- id=relfile + "::test_eggs.TestSpam",
- name="test_eggs.TestSpam",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func=None,
- ),
- source="{}:{}".format(relfile, 12),
- markers=[],
- parentid=relfile,
- ),
- SingleTestInfo(
- id=relfile + "::test_eggs.TestSpam.TestEggs",
- name="test_eggs.TestSpam.TestEggs",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func=None,
- ),
- source="{}:{}".format(relfile, 27),
- markers=[],
- parentid=relfile,
- ),
- ]
- allparents = [
- [
- (doctestfile, "test_doctest.txt", "file"),
- (fix_path("./x"), "x", "folder"),
- (".", testroot, "folder"),
- ],
- [
- (relfile, "test_eggs.py", "file"),
- (fix_path("./x/y/z"), "z", "folder"),
- (fix_path("./x/y"), "y", "folder"),
- (fix_path("./x"), "x", "folder"),
- (".", testroot, "folder"),
- ],
- [
- (relfile, "test_eggs.py", "file"),
- (fix_path("./x/y/z"), "z", "folder"),
- (fix_path("./x/y"), "y", "folder"),
- (fix_path("./x"), "x", "folder"),
- (".", testroot, "folder"),
- ],
- [
- (relfile, "test_eggs.py", "file"),
- (fix_path("./x/y/z"), "z", "folder"),
- (fix_path("./x/y"), "y", "folder"),
- (fix_path("./x"), "x", "folder"),
- (".", testroot, "folder"),
- ],
- ]
- expected = [
- test._replace(id=_fix_nodeid(test.id), parentid=_fix_nodeid(test.parentid))
- for test in alltests
- ]
-
- discovered = DiscoveredTests()
-
- for test, parents in zip(alltests, allparents):
- discovered.add_test(test, parents)
- tests = list(discovered)
- parents = discovered.parents
-
- self.maxDiff = None
- self.assertEqual(tests, expected)
- self.assertEqual(
- parents,
- [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot,
- ),
- ParentInfo(
- id="./x",
- kind="folder",
- name="x",
- root=testroot,
- relpath=fix_path("./x"),
- parentid=".",
- ),
- ParentInfo(
- id="./x/test_doctest.txt",
- kind="file",
- name="test_doctest.txt",
- root=testroot,
- relpath=fix_path(doctestfile),
- parentid="./x",
- ),
- ParentInfo(
- id="./x/y",
- kind="folder",
- name="y",
- root=testroot,
- relpath=fix_path("./x/y"),
- parentid="./x",
- ),
- ParentInfo(
- id="./x/y/z",
- kind="folder",
- name="z",
- root=testroot,
- relpath=fix_path("./x/y/z"),
- parentid="./x/y",
- ),
- ParentInfo(
- id="./x/y/z/test_eggs.py",
- kind="file",
- name="test_eggs.py",
- root=testroot,
- relpath=fix_relpath(relfile),
- parentid="./x/y/z",
- ),
- ],
- )
-
- def test_nested_suite_simple(self):
- testroot = fix_path("/a/b/c")
- relfile = fix_path("./test_eggs.py")
- alltests = [
- SingleTestInfo(
- id=relfile + "::TestOuter::TestInner::test_spam",
- name="test_spam",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func="TestOuter.TestInner.test_spam",
- ),
- source="{}:{}".format(relfile, 10),
- markers=None,
- parentid=relfile + "::TestOuter::TestInner",
- ),
- SingleTestInfo(
- id=relfile + "::TestOuter::TestInner::test_eggs",
- name="test_eggs",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func="TestOuter.TestInner.test_eggs",
- ),
- source="{}:{}".format(relfile, 21),
- markers=None,
- parentid=relfile + "::TestOuter::TestInner",
- ),
- ]
- allparents = [
- [
- (relfile + "::TestOuter::TestInner", "TestInner", "suite"),
- (relfile + "::TestOuter", "TestOuter", "suite"),
- (relfile, "test_eggs.py", "file"),
- (".", testroot, "folder"),
- ],
- [
- (relfile + "::TestOuter::TestInner", "TestInner", "suite"),
- (relfile + "::TestOuter", "TestOuter", "suite"),
- (relfile, "test_eggs.py", "file"),
- (".", testroot, "folder"),
- ],
- ]
- expected = [
- test._replace(id=_fix_nodeid(test.id), parentid=_fix_nodeid(test.parentid))
- for test in alltests
- ]
-
- discovered = DiscoveredTests()
- for test, parents in zip(alltests, allparents):
- discovered.add_test(test, parents)
- tests = list(discovered)
- parents = discovered.parents
-
- self.maxDiff = None
- self.assertEqual(tests, expected)
- self.assertEqual(
- parents,
- [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot,
- ),
- ParentInfo(
- id="./test_eggs.py",
- kind="file",
- name="test_eggs.py",
- root=testroot,
- relpath=fix_relpath(relfile),
- parentid=".",
- ),
- ParentInfo(
- id="./test_eggs.py::TestOuter",
- kind="suite",
- name="TestOuter",
- root=testroot,
- parentid="./test_eggs.py",
- ),
- ParentInfo(
- id="./test_eggs.py::TestOuter::TestInner",
- kind="suite",
- name="TestInner",
- root=testroot,
- parentid="./test_eggs.py::TestOuter",
- ),
- ],
- )
diff --git a/pythonFiles/tests/testing_tools/adapter/test_functional.py b/pythonFiles/tests/testing_tools/adapter/test_functional.py
deleted file mode 100644
index a78d36a5fdcf..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/test_functional.py
+++ /dev/null
@@ -1,1536 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import, unicode_literals
-
-import json
-import os
-import os.path
-import subprocess
-import sys
-import unittest
-
-from testing_tools.adapter.util import PATH_SEP, fix_path
-
-from ...__main__ import TESTING_TOOLS_ROOT
-
-# Pytest 3.7 and later uses pathlib/pathlib2 for path resolution.
-try:
- from pathlib import Path
-except ImportError:
- from pathlib2 import Path # type: ignore (for Pylance)
-
-
-CWD = os.getcwd()
-DATA_DIR = os.path.join(os.path.dirname(__file__), ".data")
-SCRIPT = os.path.join(TESTING_TOOLS_ROOT, "run_adapter.py")
-
-
-def resolve_testroot(name):
- projroot = os.path.join(DATA_DIR, name)
- testroot = os.path.join(projroot, "tests")
- return str(Path(projroot).resolve()), str(Path(testroot).resolve())
-
-
-def run_adapter(cmd, tool, *cliargs):
- try:
- return _run_adapter(cmd, tool, *cliargs)
- except subprocess.CalledProcessError as exc:
- print(exc.output)
-
-
-def _run_adapter(cmd, tool, *cliargs, **kwargs):
- hidestdio = kwargs.pop("hidestdio", True)
- assert not kwargs or tuple(kwargs) == ("stderr",)
- kwds = kwargs
- argv = [sys.executable, SCRIPT, cmd, tool, "--"] + list(cliargs)
- if not hidestdio:
- argv.insert(4, "--no-hide-stdio")
- kwds["stderr"] = subprocess.STDOUT
- argv.append("--cache-clear")
- print(
- "running {!r}".format(" ".join(arg.rpartition(CWD + "/")[-1] for arg in argv))
- )
- output = subprocess.check_output(argv, universal_newlines=True, **kwds)
- return output
-
-
-def fix_test_order(tests):
- if sys.version_info >= (3, 6):
- return tests
- fixed = []
- curfile = None
- group = []
- for test in tests:
- if (curfile or "???") not in test["id"]:
- fixed.extend(sorted(group, key=lambda t: t["id"]))
- group = []
- curfile = test["id"].partition(".py::")[0] + ".py"
- group.append(test)
- fixed.extend(sorted(group, key=lambda t: t["id"]))
- return fixed
-
-
-def fix_source(tests, testid, srcfile, lineno):
- for test in tests:
- if test["id"] == testid:
- break
- else:
- raise KeyError("test {!r} not found".format(testid))
- if not srcfile:
- srcfile = test["source"].rpartition(":")[0]
- test["source"] = fix_path("{}:{}".format(srcfile, lineno))
-
-
-def sorted_object(obj):
- if isinstance(obj, dict):
- return sorted((key, sorted_object(obj[key])) for key in obj.keys())
- if isinstance(obj, list):
- return sorted((sorted_object(x) for x in obj))
- else:
- return obj
-
-
-# Note that these tests are skipped if util.PATH_SEP is not os.path.sep.
-# This is because the functional tests should reflect the actual
-# operating environment.
-
-
-class PytestTests(unittest.TestCase):
- def setUp(self):
- if PATH_SEP is not os.path.sep:
- raise unittest.SkipTest("functional tests require unmodified env")
- super(PytestTests, self).setUp()
-
- def complex(self, testroot):
- results = COMPLEX.copy()
- results["root"] = testroot
- return [results]
-
- def test_discover_simple(self):
- projroot, testroot = resolve_testroot("simple")
-
- out = run_adapter("discover", "pytest", "--rootdir", projroot, testroot)
- result = json.loads(out)
-
- self.maxDiff = None
- self.assertEqual(
- result,
- [
- {
- "root": projroot,
- "rootid": ".",
- "parents": [
- {
- "id": "./tests",
- "kind": "folder",
- "name": "tests",
- "relpath": fix_path("./tests"),
- "parentid": ".",
- },
- {
- "id": "./tests/test_spam.py",
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path("./tests/test_spam.py"),
- "parentid": "./tests",
- },
- ],
- "tests": [
- {
- "id": "./tests/test_spam.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_spam.py:2"),
- "markers": [],
- "parentid": "./tests/test_spam.py",
- },
- ],
- }
- ],
- )
-
- def test_discover_complex_default(self):
- projroot, testroot = resolve_testroot("complex")
- expected = self.complex(projroot)
- expected[0]["tests"] = fix_test_order(expected[0]["tests"])
- if sys.version_info < (3,):
- decorated = [
- "./tests/test_unittest.py::MyTests::test_skipped",
- "./tests/test_unittest.py::MyTests::test_maybe_skipped",
- "./tests/test_unittest.py::MyTests::test_maybe_not_skipped",
- ]
- for testid in decorated:
- fix_source(expected[0]["tests"], testid, None, 0)
-
- out = run_adapter("discover", "pytest", "--rootdir", projroot, testroot)
- result = json.loads(out)
- result[0]["tests"] = fix_test_order(result[0]["tests"])
-
- self.maxDiff = None
- self.assertEqual(sorted_object(result), sorted_object(expected))
-
- def test_discover_complex_doctest(self):
- projroot, _ = resolve_testroot("complex")
- expected = self.complex(projroot)
- # add in doctests from test suite
- expected[0]["parents"].insert(
- 3,
- {
- "id": "./tests/test_doctest.py",
- "kind": "file",
- "name": "test_doctest.py",
- "relpath": fix_path("./tests/test_doctest.py"),
- "parentid": "./tests",
- },
- )
- expected[0]["tests"].insert(
- 2,
- {
- "id": "./tests/test_doctest.py::tests.test_doctest",
- "name": "tests.test_doctest",
- "source": fix_path("./tests/test_doctest.py:1"),
- "markers": [],
- "parentid": "./tests/test_doctest.py",
- },
- )
- # add in doctests from non-test module
- expected[0]["parents"].insert(
- 0,
- {
- "id": "./mod.py",
- "kind": "file",
- "name": "mod.py",
- "relpath": fix_path("./mod.py"),
- "parentid": ".",
- },
- )
- expected[0]["tests"] = [
- {
- "id": "./mod.py::mod",
- "name": "mod",
- "source": fix_path("./mod.py:1"),
- "markers": [],
- "parentid": "./mod.py",
- },
- {
- "id": "./mod.py::mod.Spam",
- "name": "mod.Spam",
- "source": fix_path("./mod.py:33"),
- "markers": [],
- "parentid": "./mod.py",
- },
- {
- "id": "./mod.py::mod.Spam.eggs",
- "name": "mod.Spam.eggs",
- "source": fix_path("./mod.py:43"),
- "markers": [],
- "parentid": "./mod.py",
- },
- {
- "id": "./mod.py::mod.square",
- "name": "mod.square",
- "source": fix_path("./mod.py:18"),
- "markers": [],
- "parentid": "./mod.py",
- },
- ] + expected[0]["tests"]
- expected[0]["tests"] = fix_test_order(expected[0]["tests"])
- if sys.version_info < (3,):
- decorated = [
- "./tests/test_unittest.py::MyTests::test_skipped",
- "./tests/test_unittest.py::MyTests::test_maybe_skipped",
- "./tests/test_unittest.py::MyTests::test_maybe_not_skipped",
- ]
- for testid in decorated:
- fix_source(expected[0]["tests"], testid, None, 0)
-
- out = run_adapter(
- "discover", "pytest", "--rootdir", projroot, "--doctest-modules", projroot
- )
- result = json.loads(out)
- result[0]["tests"] = fix_test_order(result[0]["tests"])
-
- self.maxDiff = None
- self.assertEqual(sorted_object(result), sorted_object(expected))
-
- def test_discover_not_found(self):
- projroot, testroot = resolve_testroot("notests")
-
- out = run_adapter("discover", "pytest", "--rootdir", projroot, testroot)
- result = json.loads(out)
-
- self.maxDiff = None
- self.assertEqual(result, [])
- # TODO: Expect the following instead?
- # self.assertEqual(result, [{
- # 'root': projroot,
- # 'rootid': '.',
- # 'parents': [],
- # 'tests': [],
- # }])
-
- @unittest.skip("broken in CI")
- def test_discover_bad_args(self):
- projroot, testroot = resolve_testroot("simple")
-
- with self.assertRaises(subprocess.CalledProcessError) as cm:
- _run_adapter(
- "discover",
- "pytest",
- "--spam",
- "--rootdir",
- projroot,
- testroot,
- stderr=subprocess.STDOUT,
- )
- self.assertIn("(exit code 4)", cm.exception.output)
-
- def test_discover_syntax_error(self):
- projroot, testroot = resolve_testroot("syntax-error")
-
- with self.assertRaises(subprocess.CalledProcessError) as cm:
- _run_adapter(
- "discover",
- "pytest",
- "--rootdir",
- projroot,
- testroot,
- stderr=subprocess.STDOUT,
- )
- self.assertIn("(exit code 2)", cm.exception.output)
-
- def test_discover_normcase(self):
- projroot, testroot = resolve_testroot("NormCase")
-
- out = run_adapter("discover", "pytest", "--rootdir", projroot, testroot)
- result = json.loads(out)
-
- self.maxDiff = None
- self.assertTrue(projroot.endswith("NormCase"))
- self.assertEqual(
- result,
- [
- {
- "root": projroot,
- "rootid": ".",
- "parents": [
- {
- "id": "./tests",
- "kind": "folder",
- "name": "tests",
- "relpath": fix_path("./tests"),
- "parentid": ".",
- },
- {
- "id": "./tests/A",
- "kind": "folder",
- "name": "A",
- "relpath": fix_path("./tests/A"),
- "parentid": "./tests",
- },
- {
- "id": "./tests/A/b",
- "kind": "folder",
- "name": "b",
- "relpath": fix_path("./tests/A/b"),
- "parentid": "./tests/A",
- },
- {
- "id": "./tests/A/b/C",
- "kind": "folder",
- "name": "C",
- "relpath": fix_path("./tests/A/b/C"),
- "parentid": "./tests/A/b",
- },
- {
- "id": "./tests/A/b/C/test_Spam.py",
- "kind": "file",
- "name": "test_Spam.py",
- "relpath": fix_path("./tests/A/b/C/test_Spam.py"),
- "parentid": "./tests/A/b/C",
- },
- ],
- "tests": [
- {
- "id": "./tests/A/b/C/test_Spam.py::test_okay",
- "name": "test_okay",
- "source": fix_path("./tests/A/b/C/test_Spam.py:2"),
- "markers": [],
- "parentid": "./tests/A/b/C/test_Spam.py",
- },
- ],
- }
- ],
- )
-
-
-COMPLEX = {
- "root": None,
- "rootid": ".",
- "parents": [
- #
- {
- "id": "./tests",
- "kind": "folder",
- "name": "tests",
- "relpath": fix_path("./tests"),
- "parentid": ".",
- },
- # +++
- {
- "id": "./tests/test_42-43.py",
- "kind": "file",
- "name": "test_42-43.py",
- "relpath": fix_path("./tests/test_42-43.py"),
- "parentid": "./tests",
- },
- # +++
- {
- "id": "./tests/test_42.py",
- "kind": "file",
- "name": "test_42.py",
- "relpath": fix_path("./tests/test_42.py"),
- "parentid": "./tests",
- },
- # +++
- {
- "id": "./tests/test_doctest.txt",
- "kind": "file",
- "name": "test_doctest.txt",
- "relpath": fix_path("./tests/test_doctest.txt"),
- "parentid": "./tests",
- },
- # +++
- {
- "id": "./tests/test_foo.py",
- "kind": "file",
- "name": "test_foo.py",
- "relpath": fix_path("./tests/test_foo.py"),
- "parentid": "./tests",
- },
- # +++
- {
- "id": "./tests/test_mixed.py",
- "kind": "file",
- "name": "test_mixed.py",
- "relpath": fix_path("./tests/test_mixed.py"),
- "parentid": "./tests",
- },
- {
- "id": "./tests/test_mixed.py::MyTests",
- "kind": "suite",
- "name": "MyTests",
- "parentid": "./tests/test_mixed.py",
- },
- {
- "id": "./tests/test_mixed.py::TestMySuite",
- "kind": "suite",
- "name": "TestMySuite",
- "parentid": "./tests/test_mixed.py",
- },
- # +++
- {
- "id": "./tests/test_pytest.py",
- "kind": "file",
- "name": "test_pytest.py",
- "relpath": fix_path("./tests/test_pytest.py"),
- "parentid": "./tests",
- },
- {
- "id": "./tests/test_pytest.py::TestEggs",
- "kind": "suite",
- "name": "TestEggs",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::TestParam",
- "kind": "suite",
- "name": "TestParam",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::TestParam::test_param_13",
- "kind": "function",
- "name": "test_param_13",
- "parentid": "./tests/test_pytest.py::TestParam",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll",
- "kind": "suite",
- "name": "TestParamAll",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_param_13",
- "kind": "function",
- "name": "test_param_13",
- "parentid": "./tests/test_pytest.py::TestParamAll",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_spam_13",
- "kind": "function",
- "name": "test_spam_13",
- "parentid": "./tests/test_pytest.py::TestParamAll",
- },
- {
- "id": "./tests/test_pytest.py::TestSpam",
- "kind": "suite",
- "name": "TestSpam",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::TestSpam::TestHam",
- "kind": "suite",
- "name": "TestHam",
- "parentid": "./tests/test_pytest.py::TestSpam",
- },
- {
- "id": "./tests/test_pytest.py::TestSpam::TestHam::TestEggs",
- "kind": "suite",
- "name": "TestEggs",
- "parentid": "./tests/test_pytest.py::TestSpam::TestHam",
- },
- {
- "id": "./tests/test_pytest.py::test_fixture_param",
- "kind": "function",
- "name": "test_fixture_param",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_01",
- "kind": "function",
- "name": "test_param_01",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_11",
- "kind": "function",
- "name": "test_param_11",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13",
- "kind": "function",
- "name": "test_param_13",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_markers",
- "kind": "function",
- "name": "test_param_13_markers",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_repeat",
- "kind": "function",
- "name": "test_param_13_repeat",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_skipped",
- "kind": "function",
- "name": "test_param_13_skipped",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13",
- "kind": "function",
- "name": "test_param_23_13",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_raises",
- "kind": "function",
- "name": "test_param_23_raises",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33",
- "kind": "function",
- "name": "test_param_33",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33_ids",
- "kind": "function",
- "name": "test_param_33_ids",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_fixture",
- "kind": "function",
- "name": "test_param_fixture",
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_mark_fixture",
- "kind": "function",
- "name": "test_param_mark_fixture",
- "parentid": "./tests/test_pytest.py",
- },
- # +++
- {
- "id": "./tests/test_pytest_param.py",
- "kind": "file",
- "name": "test_pytest_param.py",
- "relpath": fix_path("./tests/test_pytest_param.py"),
- "parentid": "./tests",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll",
- "kind": "suite",
- "name": "TestParamAll",
- "parentid": "./tests/test_pytest_param.py",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_param_13",
- "kind": "function",
- "name": "test_param_13",
- "parentid": "./tests/test_pytest_param.py::TestParamAll",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_spam_13",
- "kind": "function",
- "name": "test_spam_13",
- "parentid": "./tests/test_pytest_param.py::TestParamAll",
- },
- {
- "id": "./tests/test_pytest_param.py::test_param_13",
- "kind": "function",
- "name": "test_param_13",
- "parentid": "./tests/test_pytest_param.py",
- },
- # +++
- {
- "id": "./tests/test_unittest.py",
- "kind": "file",
- "name": "test_unittest.py",
- "relpath": fix_path("./tests/test_unittest.py"),
- "parentid": "./tests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests",
- "kind": "suite",
- "name": "MyTests",
- "parentid": "./tests/test_unittest.py",
- },
- {
- "id": "./tests/test_unittest.py::OtherTests",
- "kind": "suite",
- "name": "OtherTests",
- "parentid": "./tests/test_unittest.py",
- },
- ##
- {
- "id": "./tests/v",
- "kind": "folder",
- "name": "v",
- "relpath": fix_path("./tests/v"),
- "parentid": "./tests",
- },
- ## +++
- {
- "id": "./tests/v/test_eggs.py",
- "kind": "file",
- "name": "test_eggs.py",
- "relpath": fix_path("./tests/v/test_eggs.py"),
- "parentid": "./tests/v",
- },
- {
- "id": "./tests/v/test_eggs.py::TestSimple",
- "kind": "suite",
- "name": "TestSimple",
- "parentid": "./tests/v/test_eggs.py",
- },
- ## +++
- {
- "id": "./tests/v/test_ham.py",
- "kind": "file",
- "name": "test_ham.py",
- "relpath": fix_path("./tests/v/test_ham.py"),
- "parentid": "./tests/v",
- },
- ## +++
- {
- "id": "./tests/v/test_spam.py",
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path("./tests/v/test_spam.py"),
- "parentid": "./tests/v",
- },
- ##
- {
- "id": "./tests/w",
- "kind": "folder",
- "name": "w",
- "relpath": fix_path("./tests/w"),
- "parentid": "./tests",
- },
- ## +++
- {
- "id": "./tests/w/test_spam.py",
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path("./tests/w/test_spam.py"),
- "parentid": "./tests/w",
- },
- ## +++
- {
- "id": "./tests/w/test_spam_ex.py",
- "kind": "file",
- "name": "test_spam_ex.py",
- "relpath": fix_path("./tests/w/test_spam_ex.py"),
- "parentid": "./tests/w",
- },
- ##
- {
- "id": "./tests/x",
- "kind": "folder",
- "name": "x",
- "relpath": fix_path("./tests/x"),
- "parentid": "./tests",
- },
- ###
- {
- "id": "./tests/x/y",
- "kind": "folder",
- "name": "y",
- "relpath": fix_path("./tests/x/y"),
- "parentid": "./tests/x",
- },
- ####
- {
- "id": "./tests/x/y/z",
- "kind": "folder",
- "name": "z",
- "relpath": fix_path("./tests/x/y/z"),
- "parentid": "./tests/x/y",
- },
- #####
- {
- "id": "./tests/x/y/z/a",
- "kind": "folder",
- "name": "a",
- "relpath": fix_path("./tests/x/y/z/a"),
- "parentid": "./tests/x/y/z",
- },
- ##### +++
- {
- "id": "./tests/x/y/z/a/test_spam.py",
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path("./tests/x/y/z/a/test_spam.py"),
- "parentid": "./tests/x/y/z/a",
- },
- #####
- {
- "id": "./tests/x/y/z/b",
- "kind": "folder",
- "name": "b",
- "relpath": fix_path("./tests/x/y/z/b"),
- "parentid": "./tests/x/y/z",
- },
- ##### +++
- {
- "id": "./tests/x/y/z/b/test_spam.py",
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path("./tests/x/y/z/b/test_spam.py"),
- "parentid": "./tests/x/y/z/b",
- },
- #### +++
- {
- "id": "./tests/x/y/z/test_ham.py",
- "kind": "file",
- "name": "test_ham.py",
- "relpath": fix_path("./tests/x/y/z/test_ham.py"),
- "parentid": "./tests/x/y/z",
- },
- ],
- "tests": [
- ##########
- {
- "id": "./tests/test_42-43.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_42-43.py:2"),
- "markers": [],
- "parentid": "./tests/test_42-43.py",
- },
- #####
- {
- "id": "./tests/test_42.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_42.py:2"),
- "markers": [],
- "parentid": "./tests/test_42.py",
- },
- #####
- {
- "id": "./tests/test_doctest.txt::test_doctest.txt",
- "name": "test_doctest.txt",
- "source": fix_path("./tests/test_doctest.txt:1"),
- "markers": [],
- "parentid": "./tests/test_doctest.txt",
- },
- #####
- {
- "id": "./tests/test_foo.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_foo.py:3"),
- "markers": [],
- "parentid": "./tests/test_foo.py",
- },
- #####
- {
- "id": "./tests/test_mixed.py::test_top_level",
- "name": "test_top_level",
- "source": fix_path("./tests/test_mixed.py:5"),
- "markers": [],
- "parentid": "./tests/test_mixed.py",
- },
- {
- "id": "./tests/test_mixed.py::test_skipped",
- "name": "test_skipped",
- "source": fix_path("./tests/test_mixed.py:9"),
- "markers": ["skip"],
- "parentid": "./tests/test_mixed.py",
- },
- {
- "id": "./tests/test_mixed.py::TestMySuite::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_mixed.py:16"),
- "markers": [],
- "parentid": "./tests/test_mixed.py::TestMySuite",
- },
- {
- "id": "./tests/test_mixed.py::MyTests::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_mixed.py:22"),
- "markers": [],
- "parentid": "./tests/test_mixed.py::MyTests",
- },
- {
- "id": "./tests/test_mixed.py::MyTests::test_skipped",
- "name": "test_skipped",
- "source": fix_path("./tests/test_mixed.py:25"),
- "markers": ["skip"],
- "parentid": "./tests/test_mixed.py::MyTests",
- },
- #####
- {
- "id": "./tests/test_pytest.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_pytest.py:6"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_failure",
- "name": "test_failure",
- "source": fix_path("./tests/test_pytest.py:10"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_runtime_skipped",
- "name": "test_runtime_skipped",
- "source": fix_path("./tests/test_pytest.py:14"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_runtime_failed",
- "name": "test_runtime_failed",
- "source": fix_path("./tests/test_pytest.py:18"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_raises",
- "name": "test_raises",
- "source": fix_path("./tests/test_pytest.py:22"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_skipped",
- "name": "test_skipped",
- "source": fix_path("./tests/test_pytest.py:26"),
- "markers": ["skip"],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_maybe_skipped",
- "name": "test_maybe_skipped",
- "source": fix_path("./tests/test_pytest.py:31"),
- "markers": ["skip-if"],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_known_failure",
- "name": "test_known_failure",
- "source": fix_path("./tests/test_pytest.py:36"),
- "markers": ["expected-failure"],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_warned",
- "name": "test_warned",
- "source": fix_path("./tests/test_pytest.py:41"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_custom_marker",
- "name": "test_custom_marker",
- "source": fix_path("./tests/test_pytest.py:46"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_multiple_markers",
- "name": "test_multiple_markers",
- "source": fix_path("./tests/test_pytest.py:51"),
- "markers": ["expected-failure", "skip", "skip-if"],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_dynamic_1",
- "name": "test_dynamic_1",
- "source": fix_path("./tests/test_pytest.py:62"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_dynamic_2",
- "name": "test_dynamic_2",
- "source": fix_path("./tests/test_pytest.py:62"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_dynamic_3",
- "name": "test_dynamic_3",
- "source": fix_path("./tests/test_pytest.py:62"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::TestSpam::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_pytest.py:70"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestSpam",
- },
- {
- "id": "./tests/test_pytest.py::TestSpam::test_skipped",
- "name": "test_skipped",
- "source": fix_path("./tests/test_pytest.py:73"),
- "markers": ["skip"],
- "parentid": "./tests/test_pytest.py::TestSpam",
- },
- {
- "id": "./tests/test_pytest.py::TestSpam::TestHam::TestEggs::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_pytest.py:81"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestSpam::TestHam::TestEggs",
- },
- {
- "id": "./tests/test_pytest.py::TestEggs::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_pytest.py:93"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestEggs",
- },
- {
- "id": "./tests/test_pytest.py::test_param_01[]",
- "name": "",
- "source": fix_path("./tests/test_pytest.py:103"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_01",
- },
- {
- "id": "./tests/test_pytest.py::test_param_11[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:108"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_11",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:113"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:113"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:113"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_repeat[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:118"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13_repeat",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_repeat[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:118"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13_repeat",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_repeat[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:118"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13_repeat",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33[1-1-1]",
- "name": "1-1-1",
- "source": fix_path("./tests/test_pytest.py:123"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_33",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33[3-4-5]",
- "name": "3-4-5",
- "source": fix_path("./tests/test_pytest.py:123"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_33",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33[0-0-0]",
- "name": "0-0-0",
- "source": fix_path("./tests/test_pytest.py:123"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_33",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33_ids[v1]",
- "name": "v1",
- "source": fix_path("./tests/test_pytest.py:128"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_33_ids",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33_ids[v2]",
- "name": "v2",
- "source": fix_path("./tests/test_pytest.py:128"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_33_ids",
- },
- {
- "id": "./tests/test_pytest.py::test_param_33_ids[v3]",
- "name": "v3",
- "source": fix_path("./tests/test_pytest.py:128"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_33_ids",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[1-1-z0]",
- "name": "1-1-z0",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[1-1-z1]",
- "name": "1-1-z1",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[1-1-z2]",
- "name": "1-1-z2",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[3-4-z0]",
- "name": "3-4-z0",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[3-4-z1]",
- "name": "3-4-z1",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[3-4-z2]",
- "name": "3-4-z2",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[0-0-z0]",
- "name": "0-0-z0",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[0-0-z1]",
- "name": "0-0-z1",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_13[0-0-z2]",
- "name": "0-0-z2",
- "source": fix_path("./tests/test_pytest.py:134"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_13",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_markers[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:140"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_13_markers",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_markers[???]",
- "name": "???",
- "source": fix_path("./tests/test_pytest.py:140"),
- "markers": ["skip"],
- "parentid": "./tests/test_pytest.py::test_param_13_markers",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_markers[2]",
- "name": "2",
- "source": fix_path("./tests/test_pytest.py:140"),
- "markers": ["expected-failure"],
- "parentid": "./tests/test_pytest.py::test_param_13_markers",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_skipped[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:149"),
- "markers": ["skip"],
- "parentid": "./tests/test_pytest.py::test_param_13_skipped",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_skipped[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:149"),
- "markers": ["skip"],
- "parentid": "./tests/test_pytest.py::test_param_13_skipped",
- },
- {
- "id": "./tests/test_pytest.py::test_param_13_skipped[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:149"),
- "markers": ["skip"],
- "parentid": "./tests/test_pytest.py::test_param_13_skipped",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_raises[1-None]",
- "name": "1-None",
- "source": fix_path("./tests/test_pytest.py:155"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_raises",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_raises[1.0-None]",
- "name": "1.0-None",
- "source": fix_path("./tests/test_pytest.py:155"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_raises",
- },
- {
- "id": "./tests/test_pytest.py::test_param_23_raises[2-catch2]",
- "name": "2-catch2",
- "source": fix_path("./tests/test_pytest.py:155"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_23_raises",
- },
- {
- "id": "./tests/test_pytest.py::TestParam::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_pytest.py:164"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParam",
- },
- {
- "id": "./tests/test_pytest.py::TestParam::test_param_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:167"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParam::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParam::test_param_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:167"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParam::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParam::test_param_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:167"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParam::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_param_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:175"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParamAll::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_param_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:175"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParamAll::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_param_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:175"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParamAll::test_param_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_spam_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:178"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParamAll::test_spam_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_spam_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:178"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParamAll::test_spam_13",
- },
- {
- "id": "./tests/test_pytest.py::TestParamAll::test_spam_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:178"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::TestParamAll::test_spam_13",
- },
- {
- "id": "./tests/test_pytest.py::test_fixture",
- "name": "test_fixture",
- "source": fix_path("./tests/test_pytest.py:192"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_mark_fixture",
- "name": "test_mark_fixture",
- "source": fix_path("./tests/test_pytest.py:196"),
- "markers": [],
- "parentid": "./tests/test_pytest.py",
- },
- {
- "id": "./tests/test_pytest.py::test_param_fixture[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:201"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_fixture",
- },
- {
- "id": "./tests/test_pytest.py::test_param_fixture[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:201"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_fixture",
- },
- {
- "id": "./tests/test_pytest.py::test_param_fixture[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest.py:201"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_fixture",
- },
- {
- "id": "./tests/test_pytest.py::test_param_mark_fixture[(1+0j)]",
- "name": "(1+0j)",
- "source": fix_path("./tests/test_pytest.py:207"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_mark_fixture",
- },
- {
- "id": "./tests/test_pytest.py::test_param_mark_fixture[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest.py:207"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_mark_fixture",
- },
- {
- "id": "./tests/test_pytest.py::test_param_mark_fixture[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest.py:207"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_param_mark_fixture",
- },
- {
- "id": "./tests/test_pytest.py::test_fixture_param[spam]",
- "name": "spam",
- "source": fix_path("./tests/test_pytest.py:216"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_fixture_param",
- },
- {
- "id": "./tests/test_pytest.py::test_fixture_param[eggs]",
- "name": "eggs",
- "source": fix_path("./tests/test_pytest.py:216"),
- "markers": [],
- "parentid": "./tests/test_pytest.py::test_fixture_param",
- },
- ######
- {
- "id": "./tests/test_pytest_param.py::test_param_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest_param.py:8"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::test_param_13",
- },
- {
- "id": "./tests/test_pytest_param.py::test_param_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest_param.py:8"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::test_param_13",
- },
- {
- "id": "./tests/test_pytest_param.py::test_param_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest_param.py:8"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::test_param_13",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_param_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest_param.py:14"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::TestParamAll::test_param_13",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_param_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest_param.py:14"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::TestParamAll::test_param_13",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_param_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest_param.py:14"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::TestParamAll::test_param_13",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_spam_13[x0]",
- "name": "x0",
- "source": fix_path("./tests/test_pytest_param.py:17"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::TestParamAll::test_spam_13",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_spam_13[x1]",
- "name": "x1",
- "source": fix_path("./tests/test_pytest_param.py:17"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::TestParamAll::test_spam_13",
- },
- {
- "id": "./tests/test_pytest_param.py::TestParamAll::test_spam_13[x2]",
- "name": "x2",
- "source": fix_path("./tests/test_pytest_param.py:17"),
- "markers": [],
- "parentid": "./tests/test_pytest_param.py::TestParamAll::test_spam_13",
- },
- ######
- {
- "id": "./tests/test_unittest.py::MyTests::test_dynamic_",
- "name": "test_dynamic_",
- "source": fix_path("./tests/test_unittest.py:54"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_failure",
- "name": "test_failure",
- "source": fix_path("./tests/test_unittest.py:34"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_known_failure",
- "name": "test_known_failure",
- "source": fix_path("./tests/test_unittest.py:37"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_maybe_not_skipped",
- "name": "test_maybe_not_skipped",
- "source": fix_path("./tests/test_unittest.py:17"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_maybe_skipped",
- "name": "test_maybe_skipped",
- "source": fix_path("./tests/test_unittest.py:13"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_unittest.py:6"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_skipped",
- "name": "test_skipped",
- "source": fix_path("./tests/test_unittest.py:9"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_skipped_inside",
- "name": "test_skipped_inside",
- "source": fix_path("./tests/test_unittest.py:21"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_with_nested_subtests",
- "name": "test_with_nested_subtests",
- "source": fix_path("./tests/test_unittest.py:46"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::MyTests::test_with_subtests",
- "name": "test_with_subtests",
- "source": fix_path("./tests/test_unittest.py:41"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::MyTests",
- },
- {
- "id": "./tests/test_unittest.py::OtherTests::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/test_unittest.py:61"),
- "markers": [],
- "parentid": "./tests/test_unittest.py::OtherTests",
- },
- ###########
- {
- "id": "./tests/v/test_eggs.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/v/spam.py:2"),
- "markers": [],
- "parentid": "./tests/v/test_eggs.py",
- },
- {
- "id": "./tests/v/test_eggs.py::TestSimple::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/v/spam.py:8"),
- "markers": [],
- "parentid": "./tests/v/test_eggs.py::TestSimple",
- },
- ######
- {
- "id": "./tests/v/test_ham.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/v/spam.py:2"),
- "markers": [],
- "parentid": "./tests/v/test_ham.py",
- },
- {
- "id": "./tests/v/test_ham.py::test_not_hard",
- "name": "test_not_hard",
- "source": fix_path("./tests/v/spam.py:2"),
- "markers": [],
- "parentid": "./tests/v/test_ham.py",
- },
- ######
- {
- "id": "./tests/v/test_spam.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/v/spam.py:2"),
- "markers": [],
- "parentid": "./tests/v/test_spam.py",
- },
- {
- "id": "./tests/v/test_spam.py::test_simpler",
- "name": "test_simpler",
- "source": fix_path("./tests/v/test_spam.py:4"),
- "markers": [],
- "parentid": "./tests/v/test_spam.py",
- },
- ###########
- {
- "id": "./tests/w/test_spam.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/w/test_spam.py:4"),
- "markers": [],
- "parentid": "./tests/w/test_spam.py",
- },
- {
- "id": "./tests/w/test_spam_ex.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/w/test_spam_ex.py:4"),
- "markers": [],
- "parentid": "./tests/w/test_spam_ex.py",
- },
- ###########
- {
- "id": "./tests/x/y/z/test_ham.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/x/y/z/test_ham.py:2"),
- "markers": [],
- "parentid": "./tests/x/y/z/test_ham.py",
- },
- ######
- {
- "id": "./tests/x/y/z/a/test_spam.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/x/y/z/a/test_spam.py:11"),
- "markers": [],
- "parentid": "./tests/x/y/z/a/test_spam.py",
- },
- {
- "id": "./tests/x/y/z/b/test_spam.py::test_simple",
- "name": "test_simple",
- "source": fix_path("./tests/x/y/z/b/test_spam.py:7"),
- "markers": [],
- "parentid": "./tests/x/y/z/b/test_spam.py",
- },
- ],
-}
diff --git a/pythonFiles/tests/testing_tools/adapter/test_report.py b/pythonFiles/tests/testing_tools/adapter/test_report.py
deleted file mode 100644
index bb68c8a65e79..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/test_report.py
+++ /dev/null
@@ -1,1179 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import json
-import unittest
-
-from ...util import StubProxy
-from testing_tools.adapter.util import fix_path, fix_relpath
-from testing_tools.adapter.info import SingleTestInfo, SingleTestPath, ParentInfo
-from testing_tools.adapter.report import report_discovered
-
-
-class StubSender(StubProxy):
- def send(self, outstr):
- self.add_call("send", (json.loads(outstr),), None)
-
-
-##################################
-# tests
-
-
-class ReportDiscoveredTests(unittest.TestCase):
- def test_basic(self):
- stub = StubSender()
- testroot = fix_path("/a/b/c")
- relfile = "test_spam.py"
- relpath = fix_relpath(relfile)
- tests = [
- SingleTestInfo(
- id="test#1",
- name="test_spam",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func="test_spam",
- ),
- source="{}:{}".format(relfile, 10),
- markers=[],
- parentid="file#1",
- ),
- ]
- parents = [
- ParentInfo(
- id="",
- kind="folder",
- name=testroot,
- ),
- ParentInfo(
- id="file#1",
- kind="file",
- name=relfile,
- root=testroot,
- relpath=relpath,
- parentid="",
- ),
- ]
- expected = [
- {
- "rootid": "",
- "root": testroot,
- "parents": [
- {
- "id": "file#1",
- "kind": "file",
- "name": relfile,
- "relpath": relpath,
- "parentid": "",
- },
- ],
- "tests": [
- {
- "id": "test#1",
- "name": "test_spam",
- "source": "{}:{}".format(relfile, 10),
- "markers": [],
- "parentid": "file#1",
- }
- ],
- }
- ]
-
- report_discovered(tests, parents, _send=stub.send)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("send", (expected,), None),
- ],
- )
-
- def test_multiroot(self):
- stub = StubSender()
- # the first root
- testroot1 = fix_path("/a/b/c")
- relfileid1 = "./test_spam.py"
- relpath1 = fix_path(relfileid1)
- relfile1 = relpath1[2:]
- tests = [
- SingleTestInfo(
- id=relfileid1 + "::test_spam",
- name="test_spam",
- path=SingleTestPath(
- root=testroot1,
- relfile=relfile1,
- func="test_spam",
- ),
- source="{}:{}".format(relfile1, 10),
- markers=[],
- parentid=relfileid1,
- ),
- ]
- parents = [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot1,
- ),
- ParentInfo(
- id=relfileid1,
- kind="file",
- name="test_spam.py",
- root=testroot1,
- relpath=relpath1,
- parentid=".",
- ),
- ]
- expected = [
- {
- "rootid": ".",
- "root": testroot1,
- "parents": [
- {
- "id": relfileid1,
- "kind": "file",
- "name": "test_spam.py",
- "relpath": relpath1,
- "parentid": ".",
- },
- ],
- "tests": [
- {
- "id": relfileid1 + "::test_spam",
- "name": "test_spam",
- "source": "{}:{}".format(relfile1, 10),
- "markers": [],
- "parentid": relfileid1,
- }
- ],
- },
- ]
- # the second root
- testroot2 = fix_path("/x/y/z")
- relfileid2 = "./w/test_eggs.py"
- relpath2 = fix_path(relfileid2)
- relfile2 = relpath2[2:]
- tests.extend(
- [
- SingleTestInfo(
- id=relfileid2 + "::BasicTests::test_first",
- name="test_first",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile2,
- func="BasicTests.test_first",
- ),
- source="{}:{}".format(relfile2, 61),
- markers=[],
- parentid=relfileid2 + "::BasicTests",
- ),
- ]
- )
- parents.extend(
- [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot2,
- ),
- ParentInfo(
- id="./w",
- kind="folder",
- name="w",
- root=testroot2,
- relpath=fix_path("./w"),
- parentid=".",
- ),
- ParentInfo(
- id=relfileid2,
- kind="file",
- name="test_eggs.py",
- root=testroot2,
- relpath=relpath2,
- parentid="./w",
- ),
- ParentInfo(
- id=relfileid2 + "::BasicTests",
- kind="suite",
- name="BasicTests",
- root=testroot2,
- parentid=relfileid2,
- ),
- ]
- )
- expected.extend(
- [
- {
- "rootid": ".",
- "root": testroot2,
- "parents": [
- {
- "id": "./w",
- "kind": "folder",
- "name": "w",
- "relpath": fix_path("./w"),
- "parentid": ".",
- },
- {
- "id": relfileid2,
- "kind": "file",
- "name": "test_eggs.py",
- "relpath": relpath2,
- "parentid": "./w",
- },
- {
- "id": relfileid2 + "::BasicTests",
- "kind": "suite",
- "name": "BasicTests",
- "parentid": relfileid2,
- },
- ],
- "tests": [
- {
- "id": relfileid2 + "::BasicTests::test_first",
- "name": "test_first",
- "source": "{}:{}".format(relfile2, 61),
- "markers": [],
- "parentid": relfileid2 + "::BasicTests",
- }
- ],
- },
- ]
- )
-
- report_discovered(tests, parents, _send=stub.send)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("send", (expected,), None),
- ],
- )
-
- def test_complex(self):
- """
- /a/b/c/
- test_ham.py
- MySuite
- test_x1
- test_x2
- /a/b/e/f/g/
- w/
- test_ham.py
- test_ham1
- HamTests
- test_uh_oh
- test_whoa
- MoreHam
- test_yay
- sub1
- sub2
- sub3
- test_eggs.py
- SpamTests
- test_okay
- x/
- y/
- a/
- test_spam.py
- SpamTests
- test_okay
- b/
- test_spam.py
- SpamTests
- test_okay
- test_spam.py
- SpamTests
- test_okay
- """
- stub = StubSender()
- testroot = fix_path("/a/b/c")
- relfileid1 = "./test_ham.py"
- relfileid2 = "./test_spam.py"
- relfileid3 = "./w/test_ham.py"
- relfileid4 = "./w/test_eggs.py"
- relfileid5 = "./x/y/a/test_spam.py"
- relfileid6 = "./x/y/b/test_spam.py"
- tests = [
- SingleTestInfo(
- id=relfileid1 + "::MySuite::test_x1",
- name="test_x1",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid1),
- func="MySuite.test_x1",
- ),
- source="{}:{}".format(fix_path(relfileid1), 10),
- markers=None,
- parentid=relfileid1 + "::MySuite",
- ),
- SingleTestInfo(
- id=relfileid1 + "::MySuite::test_x2",
- name="test_x2",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid1),
- func="MySuite.test_x2",
- ),
- source="{}:{}".format(fix_path(relfileid1), 21),
- markers=None,
- parentid=relfileid1 + "::MySuite",
- ),
- SingleTestInfo(
- id=relfileid2 + "::SpamTests::test_okay",
- name="test_okay",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid2),
- func="SpamTests.test_okay",
- ),
- source="{}:{}".format(fix_path(relfileid2), 17),
- markers=None,
- parentid=relfileid2 + "::SpamTests",
- ),
- SingleTestInfo(
- id=relfileid3 + "::test_ham1",
- name="test_ham1",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid3),
- func="test_ham1",
- ),
- source="{}:{}".format(fix_path(relfileid3), 8),
- markers=None,
- parentid=relfileid3,
- ),
- SingleTestInfo(
- id=relfileid3 + "::HamTests::test_uh_oh",
- name="test_uh_oh",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid3),
- func="HamTests.test_uh_oh",
- ),
- source="{}:{}".format(fix_path(relfileid3), 19),
- markers=["expected-failure"],
- parentid=relfileid3 + "::HamTests",
- ),
- SingleTestInfo(
- id=relfileid3 + "::HamTests::test_whoa",
- name="test_whoa",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid3),
- func="HamTests.test_whoa",
- ),
- source="{}:{}".format(fix_path(relfileid3), 35),
- markers=None,
- parentid=relfileid3 + "::HamTests",
- ),
- SingleTestInfo(
- id=relfileid3 + "::MoreHam::test_yay[1-2]",
- name="test_yay[1-2]",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid3),
- func="MoreHam.test_yay",
- sub=["[1-2]"],
- ),
- source="{}:{}".format(fix_path(relfileid3), 57),
- markers=None,
- parentid=relfileid3 + "::MoreHam::test_yay",
- ),
- SingleTestInfo(
- id=relfileid3 + "::MoreHam::test_yay[1-2][3-4]",
- name="test_yay[1-2][3-4]",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid3),
- func="MoreHam.test_yay",
- sub=["[1-2]", "[3=4]"],
- ),
- source="{}:{}".format(fix_path(relfileid3), 72),
- markers=None,
- parentid=relfileid3 + "::MoreHam::test_yay[1-2]",
- ),
- SingleTestInfo(
- id=relfileid4 + "::SpamTests::test_okay",
- name="test_okay",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid4),
- func="SpamTests.test_okay",
- ),
- source="{}:{}".format(fix_path(relfileid4), 15),
- markers=None,
- parentid=relfileid4 + "::SpamTests",
- ),
- SingleTestInfo(
- id=relfileid5 + "::SpamTests::test_okay",
- name="test_okay",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid5),
- func="SpamTests.test_okay",
- ),
- source="{}:{}".format(fix_path(relfileid5), 12),
- markers=None,
- parentid=relfileid5 + "::SpamTests",
- ),
- SingleTestInfo(
- id=relfileid6 + "::SpamTests::test_okay",
- name="test_okay",
- path=SingleTestPath(
- root=testroot,
- relfile=fix_path(relfileid6),
- func="SpamTests.test_okay",
- ),
- source="{}:{}".format(fix_path(relfileid6), 27),
- markers=None,
- parentid=relfileid6 + "::SpamTests",
- ),
- ]
- parents = [
- ParentInfo(
- id=".",
- kind="folder",
- name=testroot,
- ),
- ParentInfo(
- id=relfileid1,
- kind="file",
- name="test_ham.py",
- root=testroot,
- relpath=fix_path(relfileid1),
- parentid=".",
- ),
- ParentInfo(
- id=relfileid1 + "::MySuite",
- kind="suite",
- name="MySuite",
- root=testroot,
- parentid=relfileid1,
- ),
- ParentInfo(
- id=relfileid2,
- kind="file",
- name="test_spam.py",
- root=testroot,
- relpath=fix_path(relfileid2),
- parentid=".",
- ),
- ParentInfo(
- id=relfileid2 + "::SpamTests",
- kind="suite",
- name="SpamTests",
- root=testroot,
- parentid=relfileid2,
- ),
- ParentInfo(
- id="./w",
- kind="folder",
- name="w",
- root=testroot,
- relpath=fix_path("./w"),
- parentid=".",
- ),
- ParentInfo(
- id=relfileid3,
- kind="file",
- name="test_ham.py",
- root=testroot,
- relpath=fix_path(relfileid3),
- parentid="./w",
- ),
- ParentInfo(
- id=relfileid3 + "::HamTests",
- kind="suite",
- name="HamTests",
- root=testroot,
- parentid=relfileid3,
- ),
- ParentInfo(
- id=relfileid3 + "::MoreHam",
- kind="suite",
- name="MoreHam",
- root=testroot,
- parentid=relfileid3,
- ),
- ParentInfo(
- id=relfileid3 + "::MoreHam::test_yay",
- kind="function",
- name="test_yay",
- root=testroot,
- parentid=relfileid3 + "::MoreHam",
- ),
- ParentInfo(
- id=relfileid3 + "::MoreHam::test_yay[1-2]",
- kind="subtest",
- name="test_yay[1-2]",
- root=testroot,
- parentid=relfileid3 + "::MoreHam::test_yay",
- ),
- ParentInfo(
- id=relfileid4,
- kind="file",
- name="test_eggs.py",
- root=testroot,
- relpath=fix_path(relfileid4),
- parentid="./w",
- ),
- ParentInfo(
- id=relfileid4 + "::SpamTests",
- kind="suite",
- name="SpamTests",
- root=testroot,
- parentid=relfileid4,
- ),
- ParentInfo(
- id="./x",
- kind="folder",
- name="x",
- root=testroot,
- relpath=fix_path("./x"),
- parentid=".",
- ),
- ParentInfo(
- id="./x/y",
- kind="folder",
- name="y",
- root=testroot,
- relpath=fix_path("./x/y"),
- parentid="./x",
- ),
- ParentInfo(
- id="./x/y/a",
- kind="folder",
- name="a",
- root=testroot,
- relpath=fix_path("./x/y/a"),
- parentid="./x/y",
- ),
- ParentInfo(
- id=relfileid5,
- kind="file",
- name="test_spam.py",
- root=testroot,
- relpath=fix_path(relfileid5),
- parentid="./x/y/a",
- ),
- ParentInfo(
- id=relfileid5 + "::SpamTests",
- kind="suite",
- name="SpamTests",
- root=testroot,
- parentid=relfileid5,
- ),
- ParentInfo(
- id="./x/y/b",
- kind="folder",
- name="b",
- root=testroot,
- relpath=fix_path("./x/y/b"),
- parentid="./x/y",
- ),
- ParentInfo(
- id=relfileid6,
- kind="file",
- name="test_spam.py",
- root=testroot,
- relpath=fix_path(relfileid6),
- parentid="./x/y/b",
- ),
- ParentInfo(
- id=relfileid6 + "::SpamTests",
- kind="suite",
- name="SpamTests",
- root=testroot,
- parentid=relfileid6,
- ),
- ]
- expected = [
- {
- "rootid": ".",
- "root": testroot,
- "parents": [
- {
- "id": relfileid1,
- "kind": "file",
- "name": "test_ham.py",
- "relpath": fix_path(relfileid1),
- "parentid": ".",
- },
- {
- "id": relfileid1 + "::MySuite",
- "kind": "suite",
- "name": "MySuite",
- "parentid": relfileid1,
- },
- {
- "id": relfileid2,
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path(relfileid2),
- "parentid": ".",
- },
- {
- "id": relfileid2 + "::SpamTests",
- "kind": "suite",
- "name": "SpamTests",
- "parentid": relfileid2,
- },
- {
- "id": "./w",
- "kind": "folder",
- "name": "w",
- "relpath": fix_path("./w"),
- "parentid": ".",
- },
- {
- "id": relfileid3,
- "kind": "file",
- "name": "test_ham.py",
- "relpath": fix_path(relfileid3),
- "parentid": "./w",
- },
- {
- "id": relfileid3 + "::HamTests",
- "kind": "suite",
- "name": "HamTests",
- "parentid": relfileid3,
- },
- {
- "id": relfileid3 + "::MoreHam",
- "kind": "suite",
- "name": "MoreHam",
- "parentid": relfileid3,
- },
- {
- "id": relfileid3 + "::MoreHam::test_yay",
- "kind": "function",
- "name": "test_yay",
- "parentid": relfileid3 + "::MoreHam",
- },
- {
- "id": relfileid3 + "::MoreHam::test_yay[1-2]",
- "kind": "subtest",
- "name": "test_yay[1-2]",
- "parentid": relfileid3 + "::MoreHam::test_yay",
- },
- {
- "id": relfileid4,
- "kind": "file",
- "name": "test_eggs.py",
- "relpath": fix_path(relfileid4),
- "parentid": "./w",
- },
- {
- "id": relfileid4 + "::SpamTests",
- "kind": "suite",
- "name": "SpamTests",
- "parentid": relfileid4,
- },
- {
- "id": "./x",
- "kind": "folder",
- "name": "x",
- "relpath": fix_path("./x"),
- "parentid": ".",
- },
- {
- "id": "./x/y",
- "kind": "folder",
- "name": "y",
- "relpath": fix_path("./x/y"),
- "parentid": "./x",
- },
- {
- "id": "./x/y/a",
- "kind": "folder",
- "name": "a",
- "relpath": fix_path("./x/y/a"),
- "parentid": "./x/y",
- },
- {
- "id": relfileid5,
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path(relfileid5),
- "parentid": "./x/y/a",
- },
- {
- "id": relfileid5 + "::SpamTests",
- "kind": "suite",
- "name": "SpamTests",
- "parentid": relfileid5,
- },
- {
- "id": "./x/y/b",
- "kind": "folder",
- "name": "b",
- "relpath": fix_path("./x/y/b"),
- "parentid": "./x/y",
- },
- {
- "id": relfileid6,
- "kind": "file",
- "name": "test_spam.py",
- "relpath": fix_path(relfileid6),
- "parentid": "./x/y/b",
- },
- {
- "id": relfileid6 + "::SpamTests",
- "kind": "suite",
- "name": "SpamTests",
- "parentid": relfileid6,
- },
- ],
- "tests": [
- {
- "id": relfileid1 + "::MySuite::test_x1",
- "name": "test_x1",
- "source": "{}:{}".format(fix_path(relfileid1), 10),
- "markers": [],
- "parentid": relfileid1 + "::MySuite",
- },
- {
- "id": relfileid1 + "::MySuite::test_x2",
- "name": "test_x2",
- "source": "{}:{}".format(fix_path(relfileid1), 21),
- "markers": [],
- "parentid": relfileid1 + "::MySuite",
- },
- {
- "id": relfileid2 + "::SpamTests::test_okay",
- "name": "test_okay",
- "source": "{}:{}".format(fix_path(relfileid2), 17),
- "markers": [],
- "parentid": relfileid2 + "::SpamTests",
- },
- {
- "id": relfileid3 + "::test_ham1",
- "name": "test_ham1",
- "source": "{}:{}".format(fix_path(relfileid3), 8),
- "markers": [],
- "parentid": relfileid3,
- },
- {
- "id": relfileid3 + "::HamTests::test_uh_oh",
- "name": "test_uh_oh",
- "source": "{}:{}".format(fix_path(relfileid3), 19),
- "markers": ["expected-failure"],
- "parentid": relfileid3 + "::HamTests",
- },
- {
- "id": relfileid3 + "::HamTests::test_whoa",
- "name": "test_whoa",
- "source": "{}:{}".format(fix_path(relfileid3), 35),
- "markers": [],
- "parentid": relfileid3 + "::HamTests",
- },
- {
- "id": relfileid3 + "::MoreHam::test_yay[1-2]",
- "name": "test_yay[1-2]",
- "source": "{}:{}".format(fix_path(relfileid3), 57),
- "markers": [],
- "parentid": relfileid3 + "::MoreHam::test_yay",
- },
- {
- "id": relfileid3 + "::MoreHam::test_yay[1-2][3-4]",
- "name": "test_yay[1-2][3-4]",
- "source": "{}:{}".format(fix_path(relfileid3), 72),
- "markers": [],
- "parentid": relfileid3 + "::MoreHam::test_yay[1-2]",
- },
- {
- "id": relfileid4 + "::SpamTests::test_okay",
- "name": "test_okay",
- "source": "{}:{}".format(fix_path(relfileid4), 15),
- "markers": [],
- "parentid": relfileid4 + "::SpamTests",
- },
- {
- "id": relfileid5 + "::SpamTests::test_okay",
- "name": "test_okay",
- "source": "{}:{}".format(fix_path(relfileid5), 12),
- "markers": [],
- "parentid": relfileid5 + "::SpamTests",
- },
- {
- "id": relfileid6 + "::SpamTests::test_okay",
- "name": "test_okay",
- "source": "{}:{}".format(fix_path(relfileid6), 27),
- "markers": [],
- "parentid": relfileid6 + "::SpamTests",
- },
- ],
- }
- ]
-
- report_discovered(tests, parents, _send=stub.send)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("send", (expected,), None),
- ],
- )
-
- def test_simple_basic(self):
- stub = StubSender()
- testroot = fix_path("/a/b/c")
- relfile = fix_path("x/y/z/test_spam.py")
- tests = [
- SingleTestInfo(
- id="test#1",
- name="test_spam_1",
- path=SingleTestPath(
- root=testroot,
- relfile=relfile,
- func="MySuite.test_spam_1",
- sub=None,
- ),
- source="{}:{}".format(relfile, 10),
- markers=None,
- parentid="suite#1",
- ),
- ]
- parents = None
- expected = [
- {
- "id": "test#1",
- "name": "test_spam_1",
- "testroot": testroot,
- "relfile": relfile,
- "lineno": 10,
- "testfunc": "MySuite.test_spam_1",
- "subtest": None,
- "markers": [],
- }
- ]
-
- report_discovered(tests, parents, simple=True, _send=stub.send)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("send", (expected,), None),
- ],
- )
-
- def test_simple_complex(self):
- """
- /a/b/c/
- test_ham.py
- MySuite
- test_x1
- test_x2
- /a/b/e/f/g/
- w/
- test_ham.py
- test_ham1
- HamTests
- test_uh_oh
- test_whoa
- MoreHam
- test_yay
- sub1
- sub2
- sub3
- test_eggs.py
- SpamTests
- test_okay
- x/
- y/
- a/
- test_spam.py
- SpamTests
- test_okay
- b/
- test_spam.py
- SpamTests
- test_okay
- test_spam.py
- SpamTests
- test_okay
- """
- stub = StubSender()
- testroot1 = fix_path("/a/b/c")
- relfile1 = fix_path("./test_ham.py")
- testroot2 = fix_path("/a/b/e/f/g")
- relfile2 = fix_path("./test_spam.py")
- relfile3 = fix_path("w/test_ham.py")
- relfile4 = fix_path("w/test_eggs.py")
- relfile5 = fix_path("x/y/a/test_spam.py")
- relfile6 = fix_path("x/y/b/test_spam.py")
- tests = [
- # under first root folder
- SingleTestInfo(
- id="test#1",
- name="test_x1",
- path=SingleTestPath(
- root=testroot1,
- relfile=relfile1,
- func="MySuite.test_x1",
- sub=None,
- ),
- source="{}:{}".format(relfile1, 10),
- markers=None,
- parentid="suite#1",
- ),
- SingleTestInfo(
- id="test#2",
- name="test_x2",
- path=SingleTestPath(
- root=testroot1,
- relfile=relfile1,
- func="MySuite.test_x2",
- sub=None,
- ),
- source="{}:{}".format(relfile1, 21),
- markers=None,
- parentid="suite#1",
- ),
- # under second root folder
- SingleTestInfo(
- id="test#3",
- name="test_okay",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile2,
- func="SpamTests.test_okay",
- sub=None,
- ),
- source="{}:{}".format(relfile2, 17),
- markers=None,
- parentid="suite#2",
- ),
- SingleTestInfo(
- id="test#4",
- name="test_ham1",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile3,
- func="test_ham1",
- sub=None,
- ),
- source="{}:{}".format(relfile3, 8),
- markers=None,
- parentid="file#3",
- ),
- SingleTestInfo(
- id="test#5",
- name="test_uh_oh",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile3,
- func="HamTests.test_uh_oh",
- sub=None,
- ),
- source="{}:{}".format(relfile3, 19),
- markers=["expected-failure"],
- parentid="suite#3",
- ),
- SingleTestInfo(
- id="test#6",
- name="test_whoa",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile3,
- func="HamTests.test_whoa",
- sub=None,
- ),
- source="{}:{}".format(relfile3, 35),
- markers=None,
- parentid="suite#3",
- ),
- SingleTestInfo(
- id="test#7",
- name="test_yay (sub1)",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile3,
- func="MoreHam.test_yay",
- sub=["sub1"],
- ),
- source="{}:{}".format(relfile3, 57),
- markers=None,
- parentid="suite#4",
- ),
- SingleTestInfo(
- id="test#8",
- name="test_yay (sub2) (sub3)",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile3,
- func="MoreHam.test_yay",
- sub=["sub2", "sub3"],
- ),
- source="{}:{}".format(relfile3, 72),
- markers=None,
- parentid="suite#3",
- ),
- SingleTestInfo(
- id="test#9",
- name="test_okay",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile4,
- func="SpamTests.test_okay",
- sub=None,
- ),
- source="{}:{}".format(relfile4, 15),
- markers=None,
- parentid="suite#5",
- ),
- SingleTestInfo(
- id="test#10",
- name="test_okay",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile5,
- func="SpamTests.test_okay",
- sub=None,
- ),
- source="{}:{}".format(relfile5, 12),
- markers=None,
- parentid="suite#6",
- ),
- SingleTestInfo(
- id="test#11",
- name="test_okay",
- path=SingleTestPath(
- root=testroot2,
- relfile=relfile6,
- func="SpamTests.test_okay",
- sub=None,
- ),
- source="{}:{}".format(relfile6, 27),
- markers=None,
- parentid="suite#7",
- ),
- ]
- expected = [
- {
- "id": "test#1",
- "name": "test_x1",
- "testroot": testroot1,
- "relfile": relfile1,
- "lineno": 10,
- "testfunc": "MySuite.test_x1",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#2",
- "name": "test_x2",
- "testroot": testroot1,
- "relfile": relfile1,
- "lineno": 21,
- "testfunc": "MySuite.test_x2",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#3",
- "name": "test_okay",
- "testroot": testroot2,
- "relfile": relfile2,
- "lineno": 17,
- "testfunc": "SpamTests.test_okay",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#4",
- "name": "test_ham1",
- "testroot": testroot2,
- "relfile": relfile3,
- "lineno": 8,
- "testfunc": "test_ham1",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#5",
- "name": "test_uh_oh",
- "testroot": testroot2,
- "relfile": relfile3,
- "lineno": 19,
- "testfunc": "HamTests.test_uh_oh",
- "subtest": None,
- "markers": ["expected-failure"],
- },
- {
- "id": "test#6",
- "name": "test_whoa",
- "testroot": testroot2,
- "relfile": relfile3,
- "lineno": 35,
- "testfunc": "HamTests.test_whoa",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#7",
- "name": "test_yay (sub1)",
- "testroot": testroot2,
- "relfile": relfile3,
- "lineno": 57,
- "testfunc": "MoreHam.test_yay",
- "subtest": ["sub1"],
- "markers": [],
- },
- {
- "id": "test#8",
- "name": "test_yay (sub2) (sub3)",
- "testroot": testroot2,
- "relfile": relfile3,
- "lineno": 72,
- "testfunc": "MoreHam.test_yay",
- "subtest": ["sub2", "sub3"],
- "markers": [],
- },
- {
- "id": "test#9",
- "name": "test_okay",
- "testroot": testroot2,
- "relfile": relfile4,
- "lineno": 15,
- "testfunc": "SpamTests.test_okay",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#10",
- "name": "test_okay",
- "testroot": testroot2,
- "relfile": relfile5,
- "lineno": 12,
- "testfunc": "SpamTests.test_okay",
- "subtest": None,
- "markers": [],
- },
- {
- "id": "test#11",
- "name": "test_okay",
- "testroot": testroot2,
- "relfile": relfile6,
- "lineno": 27,
- "testfunc": "SpamTests.test_okay",
- "subtest": None,
- "markers": [],
- },
- ]
- parents = None
-
- report_discovered(tests, parents, simple=True, _send=stub.send)
-
- self.maxDiff = None
- self.assertEqual(
- stub.calls,
- [
- ("send", (expected,), None),
- ],
- )
diff --git a/pythonFiles/tests/testing_tools/adapter/test_util.py b/pythonFiles/tests/testing_tools/adapter/test_util.py
deleted file mode 100644
index 822ba2ed1b22..000000000000
--- a/pythonFiles/tests/testing_tools/adapter/test_util.py
+++ /dev/null
@@ -1,330 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-from __future__ import absolute_import, print_function
-
-import ntpath
-import os
-import os.path
-import posixpath
-import shlex
-import sys
-import unittest
-
-import pytest
-
-# Pytest 3.7 and later uses pathlib/pathlib2 for path resolution.
-try:
- from pathlib import Path
-except ImportError:
- from pathlib2 import Path # type: ignore (for Pylance)
-
-from testing_tools.adapter.util import (
- fix_path,
- fix_relpath,
- fix_fileid,
- shlex_unsplit,
-)
-
-
-@unittest.skipIf(sys.version_info < (3,), "Python 2 does not have subTest")
-class FilePathTests(unittest.TestCase):
- def test_isolated_imports(self):
- import testing_tools.adapter
- from testing_tools.adapter import util
- from . import test_functional
-
- ignored = {
- str(Path(os.path.abspath(__file__)).resolve()),
- str(Path(os.path.abspath(util.__file__)).resolve()),
- str(Path(os.path.abspath(test_functional.__file__)).resolve()),
- }
- adapter = os.path.abspath(os.path.dirname(testing_tools.adapter.__file__))
- tests = os.path.join(
- os.path.abspath(os.path.dirname(os.path.dirname(testing_tools.__file__))),
- "tests",
- "testing_tools",
- "adapter",
- )
- found = []
- for root in [adapter, tests]:
- for dirname, _, files in os.walk(root):
- if ".data" in dirname:
- continue
- for basename in files:
- if not basename.endswith(".py"):
- continue
- filename = os.path.join(dirname, basename)
- if filename in ignored:
- continue
- with open(filename) as srcfile:
- for line in srcfile:
- if line.strip() == "import os.path":
- found.append(filename)
- break
-
- if found:
- self.fail(
- os.linesep.join(
- [
- "",
- "Please only use path-related API from testing_tools.adapter.util.",
- 'Found use of "os.path" in the following files:',
- ]
- + [" " + file for file in found]
- )
- )
-
- def test_fix_path(self):
- tests = [
- ("./spam.py", r".\spam.py"),
- ("./some-dir", r".\some-dir"),
- ("./some-dir/", ".\\some-dir\\"),
- ("./some-dir/eggs", r".\some-dir\eggs"),
- ("./some-dir/eggs/spam.py", r".\some-dir\eggs\spam.py"),
- ("X/y/Z/a.B.c.PY", r"X\y\Z\a.B.c.PY"),
- ("/", "\\"),
- ("/spam", r"\spam"),
- ("C:/spam", r"C:\spam"),
- ]
- for path, expected in tests:
- pathsep = ntpath.sep
- with self.subTest(r"fixed for \: {!r}".format(path)):
- fixed = fix_path(path, _pathsep=pathsep)
- self.assertEqual(fixed, expected)
-
- pathsep = posixpath.sep
- with self.subTest("unchanged for /: {!r}".format(path)):
- unchanged = fix_path(path, _pathsep=pathsep)
- self.assertEqual(unchanged, path)
-
- # no path -> "."
- for path in ["", None]:
- for pathsep in [ntpath.sep, posixpath.sep]:
- with self.subTest(r"fixed for {}: {!r}".format(pathsep, path)):
- fixed = fix_path(path, _pathsep=pathsep)
- self.assertEqual(fixed, ".")
-
- # no-op paths
- paths = [path for _, path in tests]
- paths.extend(
- [
- ".",
- "..",
- "some-dir",
- "spam.py",
- ]
- )
- for path in paths:
- for pathsep in [ntpath.sep, posixpath.sep]:
- with self.subTest(r"unchanged for {}: {!r}".format(pathsep, path)):
- unchanged = fix_path(path, _pathsep=pathsep)
- self.assertEqual(unchanged, path)
-
- def test_fix_relpath(self):
- tests = [
- ("spam.py", posixpath, "./spam.py"),
- ("eggs/spam.py", posixpath, "./eggs/spam.py"),
- ("eggs/spam/", posixpath, "./eggs/spam/"),
- (r"\spam.py", posixpath, r"./\spam.py"),
- ("spam.py", ntpath, r".\spam.py"),
- (r"eggs\spam.py", ntpath, r".\eggs\spam.py"),
- ("eggs\\spam\\", ntpath, ".\\eggs\\spam\\"),
- ("/spam.py", ntpath, r"\spam.py"), # Note the fixed "/".
- # absolute
- ("/", posixpath, "/"),
- ("/spam.py", posixpath, "/spam.py"),
- ("\\", ntpath, "\\"),
- (r"\spam.py", ntpath, r"\spam.py"),
- (r"C:\spam.py", ntpath, r"C:\spam.py"),
- # no-op
- ("./spam.py", posixpath, "./spam.py"),
- (r".\spam.py", ntpath, r".\spam.py"),
- ]
- # no-op
- for path in [".", ".."]:
- tests.extend(
- [
- (path, posixpath, path),
- (path, ntpath, path),
- ]
- )
- for path, _os_path, expected in tests:
- with self.subTest((path, _os_path.sep)):
- fixed = fix_relpath(
- path,
- _fix_path=(lambda p: fix_path(p, _pathsep=_os_path.sep)),
- _path_isabs=_os_path.isabs,
- _pathsep=_os_path.sep,
- )
- self.assertEqual(fixed, expected)
-
- def test_fix_fileid(self):
- common = [
- ("spam.py", "./spam.py"),
- ("eggs/spam.py", "./eggs/spam.py"),
- ("eggs/spam/", "./eggs/spam/"),
- # absolute (no-op)
- ("/", "/"),
- ("//", "//"),
- ("/spam.py", "/spam.py"),
- # no-op
- (None, None),
- ("", ""),
- (".", "."),
- ("./spam.py", "./spam.py"),
- ]
- tests = [(p, posixpath, e) for p, e in common]
- tests.extend(
- (p, posixpath, e)
- for p, e in [
- (r"\spam.py", r"./\spam.py"),
- ]
- )
- tests.extend((p, ntpath, e) for p, e in common)
- tests.extend(
- (p, ntpath, e)
- for p, e in [
- (r"eggs\spam.py", "./eggs/spam.py"),
- ("eggs\\spam\\", "./eggs/spam/"),
- (r".\spam.py", r"./spam.py"),
- # absolute
- (r"\spam.py", "/spam.py"),
- (r"C:\spam.py", "C:/spam.py"),
- ("\\", "/"),
- ("\\\\", "//"),
- ("C:\\\\", "C://"),
- ("C:/", "C:/"),
- ("C://", "C://"),
- ("C:/spam.py", "C:/spam.py"),
- ]
- )
- for fileid, _os_path, expected in tests:
- pathsep = _os_path.sep
- with self.subTest(r"for {}: {!r}".format(pathsep, fileid)):
- fixed = fix_fileid(
- fileid,
- _path_isabs=_os_path.isabs,
- _normcase=_os_path.normcase,
- _pathsep=pathsep,
- )
- self.assertEqual(fixed, expected)
-
- # with rootdir
- common = [
- ("spam.py", "/eggs", "./spam.py"),
- ("spam.py", r"\eggs", "./spam.py"),
- # absolute
- ("/spam.py", "/", "./spam.py"),
- ("/eggs/spam.py", "/eggs", "./spam.py"),
- ("/eggs/spam.py", "/eggs/", "./spam.py"),
- # no-op
- ("/spam.py", "/eggs", "/spam.py"),
- ("/spam.py", "/eggs/", "/spam.py"),
- # root-only (no-op)
- ("/", "/", "/"),
- ("/", "/spam", "/"),
- ("//", "/", "//"),
- ("//", "//", "//"),
- ("//", "//spam", "//"),
- ]
- tests = [(p, r, posixpath, e) for p, r, e in common]
- tests = [(p, r, ntpath, e) for p, r, e in common]
- tests.extend(
- (p, r, ntpath, e)
- for p, r, e in [
- ("spam.py", r"\eggs", "./spam.py"),
- # absolute
- (r"\spam.py", "\\", r"./spam.py"),
- (r"C:\spam.py", "C:\\", r"./spam.py"),
- (r"\eggs\spam.py", r"\eggs", r"./spam.py"),
- (r"\eggs\spam.py", "\\eggs\\", r"./spam.py"),
- # normcase
- (r"C:\spam.py", "c:\\", r"./spam.py"),
- (r"\Eggs\Spam.py", "\\eggs", r"./Spam.py"),
- (r"\eggs\spam.py", "\\Eggs", r"./spam.py"),
- (r"\eggs\Spam.py", "\\Eggs", r"./Spam.py"),
- # no-op
- (r"\spam.py", r"\eggs", r"/spam.py"),
- (r"C:\spam.py", r"C:\eggs", r"C:/spam.py"),
- # TODO: Should these be supported.
- (r"C:\spam.py", "\\", r"C:/spam.py"),
- (r"\spam.py", "C:\\", r"/spam.py"),
- # root-only
- ("\\", "\\", "/"),
- ("\\\\", "\\", "//"),
- ("C:\\", "C:\\eggs", "C:/"),
- ("C:\\", "C:\\", "C:/"),
- (r"C:\spam.py", "D:\\", r"C:/spam.py"),
- ]
- )
- for fileid, rootdir, _os_path, expected in tests:
- pathsep = _os_path.sep
- with self.subTest(
- r"for {} (with rootdir {!r}): {!r}".format(pathsep, rootdir, fileid)
- ):
- fixed = fix_fileid(
- fileid,
- rootdir,
- _path_isabs=_os_path.isabs,
- _normcase=_os_path.normcase,
- _pathsep=pathsep,
- )
- self.assertEqual(fixed, expected)
-
-
-class ShlexUnsplitTests(unittest.TestCase):
- def test_no_args(self):
- argv = []
- joined = shlex_unsplit(argv)
-
- self.assertEqual(joined, "")
- self.assertEqual(shlex.split(joined), argv)
-
- def test_one_arg(self):
- argv = ["spam"]
- joined = shlex_unsplit(argv)
-
- self.assertEqual(joined, "spam")
- self.assertEqual(shlex.split(joined), argv)
-
- def test_multiple_args(self):
- argv = [
- "-x",
- "X",
- "-xyz",
- "spam",
- "eggs",
- ]
- joined = shlex_unsplit(argv)
-
- self.assertEqual(joined, "-x X -xyz spam eggs")
- self.assertEqual(shlex.split(joined), argv)
-
- def test_whitespace(self):
- argv = [
- "-x",
- "X Y Z",
- "spam spam\tspam",
- "eggs",
- ]
- joined = shlex_unsplit(argv)
-
- self.assertEqual(joined, "-x 'X Y Z' 'spam spam\tspam' eggs")
- self.assertEqual(shlex.split(joined), argv)
-
- def test_quotation_marks(self):
- argv = [
- "-x",
- "''",
- 'spam"spam"spam',
- "ham'ham'ham",
- "eggs",
- ]
- joined = shlex_unsplit(argv)
-
- self.assertEqual(
- joined,
- "-x ''\"'\"''\"'\"'' 'spam\"spam\"spam' 'ham'\"'\"'ham'\"'\"'ham' eggs",
- )
- self.assertEqual(shlex.split(joined), argv)
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/__init__.py b/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py b/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py b/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/pythonFiles/tests/unittestadapter/conftest.py b/pythonFiles/tests/unittestadapter/conftest.py
deleted file mode 100644
index 19af85d1e095..000000000000
--- a/pythonFiles/tests/unittestadapter/conftest.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import sys
-
-# Ignore the contents of this folder for Python 2 tests.
-if sys.version_info[0] < 3:
- collect_ignore_glob = ["*.py"]
diff --git a/pythonFiles/tests/unittestadapter/helpers.py b/pythonFiles/tests/unittestadapter/helpers.py
deleted file mode 100644
index 303d021368f7..000000000000
--- a/pythonFiles/tests/unittestadapter/helpers.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import pathlib
-
-TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
-
-
-def is_same_tree(tree1, tree2) -> bool:
- """Helper function to test if two test trees are the same.
-
- `is_same_tree` starts by comparing the root attributes, and then checks if all children are the same.
- """
- # Compare the root.
- if any(tree1[key] != tree2[key] for key in ["path", "name", "type_"]):
- return False
-
- # Compare child test nodes if they exist, otherwise compare test items.
- if "children" in tree1 and "children" in tree2:
- children1 = tree1["children"]
- children2 = tree2["children"]
-
- # Compare test nodes.
- if len(children1) != len(children2):
- return False
- else:
- return all(is_same_tree(*pair) for pair in zip(children1, children2))
- elif "id_" in tree1 and "id_" in tree2:
- # Compare test items.
- return all(tree1[key] == tree2[key] for key in ["id_", "lineno"])
-
- return False
diff --git a/pythonFiles/tests/unittestadapter/test_discovery.py b/pythonFiles/tests/unittestadapter/test_discovery.py
deleted file mode 100644
index 4249ca4faef2..000000000000
--- a/pythonFiles/tests/unittestadapter/test_discovery.py
+++ /dev/null
@@ -1,320 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import os
-import pathlib
-from typing import List
-
-import pytest
-from unittestadapter.discovery import discover_tests
-from unittestadapter.pvsc_utils import TestNodeTypeEnum, parse_unittest_args
-
-from . import expected_discovery_test_output
-from .helpers import TEST_DATA_PATH, is_same_tree
-
-
-@pytest.mark.parametrize(
- "args, expected",
- [
- (
- ["-s", "something", "-p", "other*", "-t", "else"],
- ("something", "other*", "else", 1, None, None),
- ),
- (
- [
- "--start-directory",
- "foo",
- "--pattern",
- "bar*",
- "--top-level-directory",
- "baz",
- ],
- ("foo", "bar*", "baz", 1, None, None),
- ),
- (
- ["--foo", "something"],
- (".", "test*.py", None, 1, None, None),
- ),
- (
- ["--foo", "something", "-v"],
- (".", "test*.py", None, 2, None, None),
- ),
- (
- ["--foo", "something", "-f"],
- (".", "test*.py", None, 1, True, None),
- ),
- (
- ["--foo", "something", "--verbose", "-f"],
- (".", "test*.py", None, 2, True, None),
- ),
- (
- ["--foo", "something", "-q", "--failfast"],
- (".", "test*.py", None, 0, True, None),
- ),
- (
- ["--foo", "something", "--quiet"],
- (".", "test*.py", None, 0, None, None),
- ),
- (
- ["--foo", "something", "--quiet", "--locals"],
- (".", "test*.py", None, 0, None, True),
- ),
- ],
-)
-def test_parse_unittest_args(args: List[str], expected: List[str]) -> None:
- """The parse_unittest_args function should return values for the start_dir, pattern, and top_level_dir arguments
- when passed as command-line options, and ignore unrecognized arguments.
- """
- actual = parse_unittest_args(args)
-
- assert actual == expected
-
-
-def test_simple_discovery() -> None:
- """The discover_tests function should return a dictionary with a "success" status, a uuid, no errors, and a test tree
- if unittest discovery was performed successfully.
- """
- start_dir = os.fsdecode(TEST_DATA_PATH)
- pattern = "discovery_simple*"
- file_path = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH / "discovery_simple.py"))
-
- expected = {
- "path": start_dir,
- "type_": TestNodeTypeEnum.folder,
- "name": ".data",
- "children": [
- {
- "name": "discovery_simple.py",
- "type_": TestNodeTypeEnum.file,
- "path": file_path,
- "children": [
- {
- "name": "DiscoverySimple",
- "path": file_path,
- "type_": TestNodeTypeEnum.class_,
- "children": [
- {
- "name": "test_one",
- "path": file_path,
- "type_": TestNodeTypeEnum.test,
- "lineno": "14",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_one",
- },
- {
- "name": "test_two",
- "path": file_path,
- "type_": TestNodeTypeEnum.test,
- "lineno": "17",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_two",
- },
- ],
- "id_": file_path + "\\" + "DiscoverySimple",
- }
- ],
- "id_": file_path,
- }
- ],
- "id_": start_dir,
- }
-
- uuid = "some-uuid"
- actual = discover_tests(start_dir, pattern, None, uuid)
-
- assert actual["status"] == "success"
- assert is_same_tree(actual.get("tests"), expected)
- assert "error" not in actual
-
-
-def test_simple_discovery_with_top_dir_calculated() -> None:
- """The discover_tests function should return a dictionary with a "success" status, a uuid, no errors, and a test tree
- if unittest discovery was performed successfully.
- """
- start_dir = "."
- pattern = "discovery_simple*"
- file_path = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH / "discovery_simple.py"))
-
- expected = {
- "path": os.fsdecode(pathlib.PurePath(TEST_DATA_PATH)),
- "type_": TestNodeTypeEnum.folder,
- "name": ".data",
- "children": [
- {
- "name": "discovery_simple.py",
- "type_": TestNodeTypeEnum.file,
- "path": file_path,
- "children": [
- {
- "name": "DiscoverySimple",
- "path": file_path,
- "type_": TestNodeTypeEnum.class_,
- "children": [
- {
- "name": "test_one",
- "path": file_path,
- "type_": TestNodeTypeEnum.test,
- "lineno": "14",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_one",
- },
- {
- "name": "test_two",
- "path": file_path,
- "type_": TestNodeTypeEnum.test,
- "lineno": "17",
- "id_": file_path
- + "\\"
- + "DiscoverySimple"
- + "\\"
- + "test_two",
- },
- ],
- "id_": file_path + "\\" + "DiscoverySimple",
- }
- ],
- "id_": file_path,
- }
- ],
- "id_": os.fsdecode(pathlib.PurePath(TEST_DATA_PATH)),
- }
-
- uuid = "some-uuid"
- # Define the CWD to be the root of the test data folder.
- os.chdir(os.fsdecode(pathlib.PurePath(TEST_DATA_PATH)))
- actual = discover_tests(start_dir, pattern, None, uuid)
-
- assert actual["status"] == "success"
- assert is_same_tree(actual.get("tests"), expected)
- assert "error" not in actual
-
-
-def test_empty_discovery() -> None:
- """The discover_tests function should return a dictionary with a "success" status, a uuid, no errors, and no test tree
- if unittest discovery was performed successfully but no tests were found.
- """
- start_dir = os.fsdecode(TEST_DATA_PATH)
- pattern = "discovery_empty*"
-
- uuid = "some-uuid"
- actual = discover_tests(start_dir, pattern, None, uuid)
-
- assert actual["status"] == "success"
- assert "tests" in actual
- assert "error" not in actual
-
-
-def test_error_discovery() -> None:
- """The discover_tests function should return a dictionary with an "error" status, a uuid, the discovered tests, and a list of errors
- if unittest discovery failed at some point.
- """
- # Discover tests in .data/discovery_error/.
- start_path = pathlib.PurePath(TEST_DATA_PATH / "discovery_error")
- start_dir = os.fsdecode(start_path)
- pattern = "file*"
-
- file_path = os.fsdecode(start_path / "file_two.py")
-
- expected = {
- "path": start_dir,
- "type_": TestNodeTypeEnum.folder,
- "name": "discovery_error",
- "children": [
- {
- "name": "file_two.py",
- "type_": TestNodeTypeEnum.file,
- "path": file_path,
- "children": [
- {
- "name": "DiscoveryErrorTwo",
- "path": file_path,
- "type_": TestNodeTypeEnum.class_,
- "children": [
- {
- "name": "test_one",
- "path": file_path,
- "type_": TestNodeTypeEnum.test,
- "lineno": "14",
- "id_": file_path
- + "\\"
- + "DiscoveryErrorTwo"
- + "\\"
- + "test_one",
- },
- {
- "name": "test_two",
- "path": file_path,
- "type_": TestNodeTypeEnum.test,
- "lineno": "17",
- "id_": file_path
- + "\\"
- + "DiscoveryErrorTwo"
- + "\\"
- + "test_two",
- },
- ],
- "id_": file_path + "\\" + "DiscoveryErrorTwo",
- }
- ],
- "id_": file_path,
- }
- ],
- "id_": start_dir,
- }
-
- uuid = "some-uuid"
- actual = discover_tests(start_dir, pattern, None, uuid)
-
- assert actual["status"] == "error"
- assert is_same_tree(expected, actual.get("tests"))
- assert len(actual.get("error", [])) == 1
-
-
-def test_unit_skip() -> None:
- """The discover_tests function should return a dictionary with a "success" status, a uuid, no errors, and test tree.
- if unittest discovery was performed and found a test in one file marked as skipped and another file marked as skipped.
- """
- start_dir = os.fsdecode(TEST_DATA_PATH / "unittest_skip")
- pattern = "unittest_*"
-
- uuid = "some-uuid"
- actual = discover_tests(start_dir, pattern, None, uuid)
-
- assert actual["status"] == "success"
- assert "tests" in actual
- assert is_same_tree(
- actual.get("tests"),
- expected_discovery_test_output.skip_unittest_folder_discovery_output,
- )
- assert "error" not in actual
-
-
-def test_complex_tree() -> None:
- """This test specifically tests when different start_dir and top_level_dir are provided."""
- start_dir = os.fsdecode(
- pathlib.PurePath(
- TEST_DATA_PATH,
- "utils_complex_tree",
- "test_outer_folder",
- "test_inner_folder",
- )
- )
- pattern = "test_*.py"
- top_level_dir = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree"))
- uuid = "some-uuid"
- actual = discover_tests(start_dir, pattern, top_level_dir, uuid)
- assert actual["status"] == "success"
- assert "error" not in actual
- assert is_same_tree(
- actual.get("tests"),
- expected_discovery_test_output.complex_tree_expected_output,
- )
diff --git a/pythonFiles/tests/unittestadapter/test_execution.py b/pythonFiles/tests/unittestadapter/test_execution.py
deleted file mode 100644
index 7d11c656b57b..000000000000
--- a/pythonFiles/tests/unittestadapter/test_execution.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import os
-import pathlib
-import sys
-
-import pytest
-
-script_dir = pathlib.Path(__file__).parent.parent
-sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
-
-from unittestadapter.execution import run_tests
-
-TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
-
-
-def test_no_ids_run() -> None:
- """This test runs on an empty array of test_ids, therefore it should return
- an empty dict for the result.
- """
- start_dir: str = os.fspath(TEST_DATA_PATH)
- testids = []
- pattern = "discovery_simple*"
- actual = run_tests(start_dir, testids, pattern, None, "fake-uuid", 1, None)
- assert actual
- assert all(item in actual for item in ("cwd", "status"))
- assert actual["status"] == "success"
- assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
- if actual["result"] is not None:
- assert len(actual["result"]) == 0
- else:
- raise AssertionError("actual['result'] is None")
-
-
-def test_single_ids_run() -> None:
- """This test runs on a single test_id, therefore it should return
- a dict with a single key-value pair for the result.
-
- This single test passes so the outcome should be 'success'.
- """
- id = "discovery_simple.DiscoverySimple.test_one"
- actual = run_tests(
- os.fspath(TEST_DATA_PATH),
- [id],
- "discovery_simple*",
- None,
- "fake-uuid",
- 1,
- None,
- )
- assert actual
- assert all(item in actual for item in ("cwd", "status"))
- assert actual["status"] == "success"
- assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
- assert actual["result"] is not None
- result = actual["result"]
- assert len(result) == 1
- assert id in result
- id_result = result[id]
- assert id_result is not None
- assert "outcome" in id_result
- assert id_result["outcome"] == "success"
-
-
-def test_subtest_run() -> None:
- """This test runs on a the test_subtest which has a single method, test_even,
- that uses unittest subtest.
-
- The actual result of run should return a dict payload with 6 entry for the 6 subtests.
- """
- id = "test_subtest.NumbersTest.test_even"
- actual = run_tests(
- os.fspath(TEST_DATA_PATH),
- [id],
- "test_subtest.py",
- None,
- "fake-uuid",
- 1,
- None,
- )
- subtests_ids = [
- "test_subtest.NumbersTest.test_even (i=0)",
- "test_subtest.NumbersTest.test_even (i=1)",
- "test_subtest.NumbersTest.test_even (i=2)",
- "test_subtest.NumbersTest.test_even (i=3)",
- "test_subtest.NumbersTest.test_even (i=4)",
- "test_subtest.NumbersTest.test_even (i=5)",
- ]
- assert actual
- assert all(item in actual for item in ("cwd", "status"))
- assert actual["status"] == "success"
- assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
- assert actual["result"] is not None
- result = actual["result"]
- assert len(result) == 6
- for id in subtests_ids:
- assert id in result
-
-
-@pytest.mark.parametrize(
- "test_ids, pattern, cwd, expected_outcome",
- [
- (
- [
- "test_add.TestAddFunction.test_add_negative_numbers",
- "test_add.TestAddFunction.test_add_positive_numbers",
- ],
- "test_add.py",
- os.fspath(TEST_DATA_PATH / "unittest_folder"),
- "success",
- ),
- (
- [
- "test_add.TestAddFunction.test_add_negative_numbers",
- "test_add.TestAddFunction.test_add_positive_numbers",
- "test_subtract.TestSubtractFunction.test_subtract_negative_numbers",
- "test_subtract.TestSubtractFunction.test_subtract_positive_numbers",
- ],
- "test*",
- os.fspath(TEST_DATA_PATH / "unittest_folder"),
- "success",
- ),
- (
- [
- "pattern_a_test.DiscoveryA.test_one_a",
- "pattern_a_test.DiscoveryA.test_two_a",
- ],
- "*test",
- os.fspath(TEST_DATA_PATH / "two_patterns"),
- "success",
- ),
- (
- [
- "test_pattern_b.DiscoveryB.test_one_b",
- "test_pattern_b.DiscoveryB.test_two_b",
- ],
- "test_*",
- os.fspath(TEST_DATA_PATH / "two_patterns"),
- "success",
- ),
- (
- [
- "file_one.CaseTwoFileOne.test_one",
- "file_one.CaseTwoFileOne.test_two",
- "folder.file_two.CaseTwoFileTwo.test_one",
- "folder.file_two.CaseTwoFileTwo.test_two",
- ],
- "*",
- os.fspath(TEST_DATA_PATH / "utils_nested_cases"),
- "success",
- ),
- (
- [
- "test_two_classes.ClassOne.test_one",
- "test_two_classes.ClassTwo.test_two",
- ],
- "test_two_classes.py",
- os.fspath(TEST_DATA_PATH),
- "success",
- ),
- ],
-)
-def test_multiple_ids_run(test_ids, pattern, cwd, expected_outcome) -> None:
- """
- The following are all successful tests of different formats.
-
- # 1. Two tests with the `pattern` specified as a file
- # 2. Two test files in the same folder called `unittest_folder`
- # 3. A folder with two different test file patterns, this test gathers pattern `*test`
- # 4. A folder with two different test file patterns, this test gathers pattern `test_*`
- # 5. A nested structure where a test file is on the same level as a folder containing a test file
- # 6. Test file with two test classes
-
- All tests should have the outcome of `success`.
- """
- actual = run_tests(cwd, test_ids, pattern, None, "fake-uuid", 1, None)
- assert actual
- assert all(item in actual for item in ("cwd", "status"))
- assert actual["status"] == "success"
- assert actual["cwd"] == cwd
- assert actual["result"] is not None
- result = actual["result"]
- assert len(result) == len(test_ids)
- for test_id in test_ids:
- assert test_id in result
- id_result = result[test_id]
- assert id_result is not None
- assert "outcome" in id_result
- assert id_result["outcome"] == expected_outcome
- assert True
-
-
-def test_failed_tests():
- """This test runs on a single file `test_fail` with two tests that fail."""
- test_ids = [
- "test_fail_simple.RunFailSimple.test_one_fail",
- "test_fail_simple.RunFailSimple.test_two_fail",
- ]
- actual = run_tests(
- os.fspath(TEST_DATA_PATH),
- test_ids,
- "test_fail_simple*",
- None,
- "fake-uuid",
- 1,
- None,
- )
- assert actual
- assert all(item in actual for item in ("cwd", "status"))
- assert actual["status"] == "success"
- assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
- assert actual["result"] is not None
- result = actual["result"]
- assert len(result) == len(test_ids)
- for test_id in test_ids:
- assert test_id in result
- id_result = result[test_id]
- assert id_result is not None
- assert "outcome" in id_result
- assert id_result["outcome"] == "failure"
- assert "message" and "traceback" in id_result
- assert "2 not greater than 3" in str(id_result["message"]) or "1 == 1" in str(
- id_result["traceback"]
- )
- assert True
-
-
-def test_unknown_id():
- """This test runs on a unknown test_id, therefore it should return
- an error as the outcome as it attempts to find the given test.
- """
- test_ids = ["unknown_id"]
- actual = run_tests(
- os.fspath(TEST_DATA_PATH),
- test_ids,
- "test_fail_simple*",
- None,
- "fake-uuid",
- 1,
- None,
- )
- assert actual
- assert all(item in actual for item in ("cwd", "status"))
- assert actual["status"] == "success"
- assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
- assert actual["result"] is not None
- result = actual["result"]
- assert len(result) == len(test_ids)
- assert "unittest.loader._FailedTest.unknown_id" in result
- id_result = result["unittest.loader._FailedTest.unknown_id"]
- assert id_result is not None
- assert "outcome" in id_result
- assert id_result["outcome"] == "error"
- assert "message" and "traceback" in id_result
-
-
-def test_incorrect_path():
- """This test runs on a non existent path, therefore it should return
- an error as the outcome as it attempts to find the given folder.
- """
- test_ids = ["unknown_id"]
- actual = run_tests(
- os.fspath(TEST_DATA_PATH / "unknown_folder"),
- test_ids,
- "test_fail_simple*",
- None,
- "fake-uuid",
- 1,
- None,
- )
- assert actual
- assert all(item in actual for item in ("cwd", "status", "error"))
- assert actual["status"] == "error"
- assert actual["cwd"] == os.fspath(TEST_DATA_PATH / "unknown_folder")
diff --git a/pythonFiles/unittestadapter/discovery.py b/pythonFiles/unittestadapter/discovery.py
deleted file mode 100644
index db06004e02c9..000000000000
--- a/pythonFiles/unittestadapter/discovery.py
+++ /dev/null
@@ -1,171 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import json
-import os
-import pathlib
-import sys
-import traceback
-import unittest
-from typing import List, Optional, Union
-
-script_dir = pathlib.Path(__file__).parent.parent
-sys.path.append(os.fspath(script_dir))
-sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
-
-from testing_tools import socket_manager
-from typing_extensions import Literal, NotRequired, TypedDict
-
-# If I use from utils then there will be an import error in test_discovery.py.
-from unittestadapter.pvsc_utils import (
- TestNode,
- build_test_tree,
- parse_unittest_args,
-)
-
-DEFAULT_PORT = 45454
-
-
-class PayloadDict(TypedDict):
- cwd: str
- status: Literal["success", "error"]
- tests: Optional[TestNode]
- error: NotRequired[List[str]]
-
-
-class EOTPayloadDict(TypedDict):
- """A dictionary that is used to send a end of transmission post request to the server."""
-
- command_type: Union[Literal["discovery"], Literal["execution"]]
- eot: bool
-
-
-def discover_tests(
- start_dir: str,
- pattern: str,
- top_level_dir: Optional[str],
- uuid: Optional[str],
-) -> PayloadDict:
- """Returns a dictionary containing details of the discovered tests.
-
- The returned dict has the following keys:
-
- - cwd: Absolute path to the test start directory;
- - uuid: UUID sent by the caller of the Python script, that needs to be sent back as an integrity check;
- - status: Test discovery status, can be "success" or "error";
- - tests: Discoverered tests if any, not present otherwise. Note that the status can be "error" but the payload can still contain tests;
- - error: Discovery error if any, not present otherwise.
-
- Payload format for a successful discovery:
- {
- "status": "success",
- "cwd": ,
- "tests":
- }
-
- Payload format for a successful discovery with no tests:
- {
- "status": "success",
- "cwd": ,
- }
-
- Payload format when there are errors:
- {
- "cwd":
- "": [list of errors]
- "status": "error",
- }
- """
- cwd = os.path.abspath(start_dir)
- if "/" in start_dir: # is a subdir
- parent_dir = os.path.dirname(start_dir)
- sys.path.insert(0, parent_dir)
- else:
- sys.path.insert(0, cwd)
- payload: PayloadDict = {"cwd": cwd, "status": "success", "tests": None}
- tests = None
- error: List[str] = []
-
- try:
- loader = unittest.TestLoader()
- suite = loader.discover(start_dir, pattern, top_level_dir)
-
- # If the top level directory is not provided, then use the start directory.
- if top_level_dir is None:
- top_level_dir = start_dir
-
- # Get abspath of top level directory for build_test_tree.
- top_level_dir = os.path.abspath(top_level_dir)
-
- tests, error = build_test_tree(
- suite, top_level_dir
- ) # test tree built successfully here.
-
- except Exception:
- error.append(traceback.format_exc())
-
- # Still include the tests in the payload even if there are errors so that the TS
- # side can determine if it is from run or discovery.
- payload["tests"] = tests if tests is not None else None
-
- if len(error):
- payload["status"] = "error"
- payload["error"] = error
-
- return payload
-
-
-def post_response(
- payload: Union[PayloadDict, EOTPayloadDict], port: int, uuid: str
-) -> None:
- # Build the request data (it has to be a POST request or the Node side will not process it), and send it.
- addr = ("localhost", port)
- data = json.dumps(payload)
- request = f"""Content-Length: {len(data)}
-Content-Type: application/json
-Request-uuid: {uuid}
-
-{data}"""
- try:
- with socket_manager.SocketManager(addr) as s:
- if s.socket is not None:
- s.socket.sendall(request.encode("utf-8"))
- except Exception as e:
- print(f"Error sending response: {e}")
- print(f"Request data: {request}")
-
-
-if __name__ == "__main__":
- # Get unittest discovery arguments.
- argv = sys.argv[1:]
- index = argv.index("--udiscovery")
-
- (
- start_dir,
- pattern,
- top_level_dir,
- _verbosity,
- _failfast,
- _locals,
- ) = parse_unittest_args(argv[index + 1 :])
-
- testPort = int(os.environ.get("TEST_PORT", DEFAULT_PORT))
- testUuid = os.environ.get("TEST_UUID")
- if testPort is DEFAULT_PORT:
- print(
- "Error[vscode-unittest]: TEST_PORT is not set.",
- " TEST_UUID = ",
- testUuid,
- )
- if testUuid is not None:
- # Perform test discovery.
- payload = discover_tests(start_dir, pattern, top_level_dir, testUuid)
- # Post this discovery payload.
- post_response(payload, testPort, testUuid)
- # Post EOT token.
- eot_payload: EOTPayloadDict = {"command_type": "discovery", "eot": True}
- post_response(eot_payload, testPort, testUuid)
- else:
- print("Error: no uuid provided or parsed.")
- eot_payload: EOTPayloadDict = {"command_type": "discovery", "eot": True}
- post_response(eot_payload, testPort, "")
diff --git a/pythonFiles/unittestadapter/execution.py b/pythonFiles/unittestadapter/execution.py
deleted file mode 100644
index 22451c25bf1f..000000000000
--- a/pythonFiles/unittestadapter/execution.py
+++ /dev/null
@@ -1,365 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import atexit
-import enum
-import json
-import os
-import pathlib
-import socket
-import sys
-import traceback
-import unittest
-from types import TracebackType
-from typing import Dict, List, Optional, Tuple, Type, Union
-
-script_dir = pathlib.Path(__file__).parent.parent
-sys.path.append(os.fspath(script_dir))
-sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
-
-from testing_tools import process_json_util, socket_manager
-from typing_extensions import Literal, NotRequired, TypeAlias, TypedDict
-from unittestadapter.pvsc_utils import parse_unittest_args
-
-ErrorType = Union[
- Tuple[Type[BaseException], BaseException, TracebackType], Tuple[None, None, None]
-]
-testPort = 0
-testUuid = 0
-START_DIR = ""
-DEFAULT_PORT = 45454
-
-
-class TestOutcomeEnum(str, enum.Enum):
- error = "error"
- failure = "failure"
- success = "success"
- skipped = "skipped"
- expected_failure = "expected-failure"
- unexpected_success = "unexpected-success"
- subtest_success = "subtest-success"
- subtest_failure = "subtest-failure"
-
-
-class UnittestTestResult(unittest.TextTestResult):
- def __init__(self, *args, **kwargs):
- self.formatted: Dict[str, Dict[str, Union[str, None]]] = dict()
- super(UnittestTestResult, self).__init__(*args, **kwargs)
-
- def startTest(self, test: unittest.TestCase):
- super(UnittestTestResult, self).startTest(test)
-
- def addError(
- self,
- test: unittest.TestCase,
- err: ErrorType,
- ):
- super(UnittestTestResult, self).addError(test, err)
- self.formatResult(test, TestOutcomeEnum.error, err)
-
- def addFailure(
- self,
- test: unittest.TestCase,
- err: ErrorType,
- ):
- super(UnittestTestResult, self).addFailure(test, err)
- self.formatResult(test, TestOutcomeEnum.failure, err)
-
- def addSuccess(self, test: unittest.TestCase):
- super(UnittestTestResult, self).addSuccess(test)
- self.formatResult(test, TestOutcomeEnum.success)
-
- def addSkip(self, test: unittest.TestCase, reason: str):
- super(UnittestTestResult, self).addSkip(test, reason)
- self.formatResult(test, TestOutcomeEnum.skipped)
-
- def addExpectedFailure(self, test: unittest.TestCase, err: ErrorType):
- super(UnittestTestResult, self).addExpectedFailure(test, err)
- self.formatResult(test, TestOutcomeEnum.expected_failure, err)
-
- def addUnexpectedSuccess(self, test: unittest.TestCase):
- super(UnittestTestResult, self).addUnexpectedSuccess(test)
- self.formatResult(test, TestOutcomeEnum.unexpected_success)
-
- def addSubTest(
- self,
- test: unittest.TestCase,
- subtest: unittest.TestCase,
- err: Union[ErrorType, None],
- ):
- super(UnittestTestResult, self).addSubTest(test, subtest, err)
- self.formatResult(
- test,
- TestOutcomeEnum.subtest_failure if err else TestOutcomeEnum.subtest_success,
- err,
- subtest,
- )
-
- def formatResult(
- self,
- test: unittest.TestCase,
- outcome: str,
- error: Union[ErrorType, None] = None,
- subtest: Union[unittest.TestCase, None] = None,
- ):
- tb = None
-
- message = ""
- # error is a tuple of the form returned by sys.exc_info(): (type, value, traceback).
- if error is not None:
- try:
- message = f"{error[0]} {error[1]}"
- except Exception:
- message = "Error occurred, unknown type or value"
- formatted = traceback.format_exception(*error)
- tb = "".join(formatted)
- # Remove the 'Traceback (most recent call last)'
- formatted = formatted[1:]
- if subtest:
- test_id = subtest.id()
- else:
- test_id = test.id()
-
- result = {
- "test": test.id(),
- "outcome": outcome,
- "message": message,
- "traceback": tb,
- "subtest": subtest.id() if subtest else None,
- }
- self.formatted[test_id] = result
- if testPort == 0 or testUuid == 0:
- print("Error sending response, port or uuid unknown to python server.")
- send_run_data(result, testPort, testUuid)
-
-
-class TestExecutionStatus(str, enum.Enum):
- error = "error"
- success = "success"
-
-
-TestResultTypeAlias: TypeAlias = Dict[str, Dict[str, Union[str, None]]]
-
-
-class PayloadDict(TypedDict):
- cwd: str
- status: TestExecutionStatus
- result: Optional[TestResultTypeAlias]
- not_found: NotRequired[List[str]]
- error: NotRequired[str]
-
-
-class EOTPayloadDict(TypedDict):
- """A dictionary that is used to send a end of transmission post request to the server."""
-
- command_type: Union[Literal["discovery"], Literal["execution"]]
- eot: bool
-
-
-# Args: start_path path to a directory or a file, list of ids that may be empty.
-# Edge cases:
-# - if tests got deleted since the VS Code side last ran discovery and the current test run,
-# return these test ids in the "not_found" entry, and the VS Code side can process them as "unknown";
-# - if tests got added since the VS Code side last ran discovery and the current test run, ignore them.
-def run_tests(
- start_dir: str,
- test_ids: List[str],
- pattern: str,
- top_level_dir: Optional[str],
- uuid: Optional[str],
- verbosity: int,
- failfast: Optional[bool],
- locals: Optional[bool] = None,
-) -> PayloadDict:
- cwd = os.path.abspath(start_dir)
- status = TestExecutionStatus.error
- error = None
- payload: PayloadDict = {"cwd": cwd, "status": status, "result": None}
-
- try:
- # If it's a file, split path and file name.
- start_dir = cwd
- if cwd.endswith(".py"):
- start_dir = os.path.dirname(cwd)
- pattern = os.path.basename(cwd)
-
- # Discover tests at path with the file name as a pattern (if any).
- loader = unittest.TestLoader()
-
- args = { # noqa: F841
- "start_dir": start_dir,
- "pattern": pattern,
- "top_level_dir": top_level_dir,
- }
- suite = loader.discover(start_dir, pattern, top_level_dir) # noqa: F841
-
- if failfast is None:
- failfast = False
- if locals is None:
- locals = False
- if verbosity is None:
- verbosity = 1
- runner = unittest.TextTestRunner(
- resultclass=UnittestTestResult,
- tb_locals=locals,
- failfast=failfast,
- verbosity=verbosity,
- )
- # lets try to tailer our own suite so we can figure out running only the ones we want
- loader = unittest.TestLoader()
- tailor: unittest.TestSuite = loader.loadTestsFromNames(test_ids)
- result: UnittestTestResult = runner.run(tailor) # type: ignore
-
- payload["result"] = result.formatted
-
- except Exception:
- status = TestExecutionStatus.error
- error = traceback.format_exc()
-
- if error is not None:
- payload["error"] = error
- else:
- status = TestExecutionStatus.success
-
- payload["status"] = status
-
- return payload
-
-
-__socket = None
-atexit.register(lambda: __socket.close() if __socket else None)
-
-
-def send_run_data(raw_data, port, uuid):
- status = raw_data["outcome"]
- cwd = os.path.abspath(START_DIR)
- if raw_data["subtest"]:
- test_id = raw_data["subtest"]
- else:
- test_id = raw_data["test"]
- test_dict = {}
- test_dict[test_id] = raw_data
- payload: PayloadDict = {"cwd": cwd, "status": status, "result": test_dict}
- post_response(payload, port, uuid)
-
-
-def post_response(
- payload: Union[PayloadDict, EOTPayloadDict], port: int, uuid: str
-) -> None:
- # Build the request data (it has to be a POST request or the Node side will not process it), and send it.
- addr = ("localhost", port)
- global __socket
- if __socket is None:
- try:
- __socket = socket_manager.SocketManager(addr)
- __socket.connect()
- except Exception as error:
- print(f"Plugin error connection error[vscode-pytest]: {error}")
- __socket = None
- data = json.dumps(payload)
- request = f"""Content-Length: {len(data)}
-Content-Type: application/json
-Request-uuid: {uuid}
-
-{data}"""
- try:
- if __socket is not None and __socket.socket is not None:
- __socket.socket.sendall(request.encode("utf-8"))
- except Exception as ex:
- print(f"Error sending response: {ex}")
- print(f"Request data: {request}")
-
-
-if __name__ == "__main__":
- # Get unittest test execution arguments.
- argv = sys.argv[1:]
- index = argv.index("--udiscovery")
-
- (
- start_dir,
- pattern,
- top_level_dir,
- verbosity,
- failfast,
- locals,
- ) = parse_unittest_args(argv[index + 1 :])
-
- run_test_ids_port = os.environ.get("RUN_TEST_IDS_PORT")
- run_test_ids_port_int = (
- int(run_test_ids_port) if run_test_ids_port is not None else 0
- )
- if run_test_ids_port_int == 0:
- print("Error[vscode-unittest]: RUN_TEST_IDS_PORT env var is not set.")
- # get data from socket
- test_ids_from_buffer = []
- try:
- client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- client_socket.connect(("localhost", run_test_ids_port_int))
- buffer = b""
-
- while True:
- # Receive the data from the client
- data = client_socket.recv(1024 * 1024)
- if not data:
- break
-
- # Append the received data to the buffer
- buffer += data
-
- try:
- # Try to parse the buffer as JSON
- test_ids_from_buffer = process_json_util.process_rpc_json(
- buffer.decode("utf-8")
- )
- # Clear the buffer as complete JSON object is received
- buffer = b""
- break
- except json.JSONDecodeError:
- # JSON decoding error, the complete JSON object is not yet received
- continue
- except socket.error as e:
- print(f"Error: Could not connect to runTestIdsPort: {e}")
- print("Error: Could not connect to runTestIdsPort")
-
- testPort = int(os.environ.get("TEST_PORT", DEFAULT_PORT))
- testUuid = os.environ.get("TEST_UUID")
- if testPort is DEFAULT_PORT:
- print(
- "Error[vscode-unittest]: TEST_PORT is not set.",
- " TEST_UUID = ",
- testUuid,
- )
- if testUuid is None:
- print(
- "Error[vscode-unittest]: TEST_UUID is not set.",
- " TEST_PORT = ",
- testPort,
- )
- testUuid = "unknown"
- if test_ids_from_buffer:
- # Perform test execution.
- payload = run_tests(
- start_dir,
- test_ids_from_buffer,
- pattern,
- top_level_dir,
- testUuid,
- verbosity,
- failfast,
- locals,
- )
- else:
- cwd = os.path.abspath(start_dir)
- status = TestExecutionStatus.error
- payload: PayloadDict = {
- "cwd": cwd,
- "status": status,
- "error": "No test ids received from buffer",
- "result": None,
- }
- eot_payload: EOTPayloadDict = {"command_type": "execution", "eot": True}
- if testUuid is None:
- print("Error sending response, uuid unknown to python server.")
- post_response(eot_payload, testPort, "unknown")
- else:
- post_response(eot_payload, testPort, testUuid)
diff --git a/pythonFiles/vscode_datascience_helpers/tests/logParser.py b/pythonFiles/vscode_datascience_helpers/tests/logParser.py
deleted file mode 100644
index e021853fee7a..000000000000
--- a/pythonFiles/vscode_datascience_helpers/tests/logParser.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import argparse
-import os
-from io import TextIOWrapper
-
-os.system("color")
-import re
-from pathlib import Path
-
-parser = argparse.ArgumentParser(description="Parse a test log into its parts")
-parser.add_argument("testlog", type=str, nargs=1, help="Log to parse")
-parser.add_argument(
- "--testoutput", action="store_true", help="Show all failures and passes"
-)
-parser.add_argument(
- "--split",
- action="store_true",
- help="Split into per process files. Each file will have the pid appended",
-)
-ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
-pid_regex = re.compile(r"(\d+).*")
-timestamp_regex = re.compile(r"\d{4}-\d{2}-\d{2}T.*\dZ")
-
-
-def stripTimestamp(line: str):
- match = timestamp_regex.match(line)
- if match:
- return line[match.end() :]
- return line
-
-
-def readStripLines(f: TextIOWrapper):
- return map(stripTimestamp, f.readlines())
-
-
-def printTestOutput(testlog):
- # Find all the lines that don't have a PID in them. These are the test output
- p = Path(testlog[0])
- with p.open() as f:
- for line in readStripLines(f):
- stripped = line.strip()
- if len(stripped) > 2 and stripped[0] == "\x1B" and stripped[1] == "[":
- print(line.rstrip()) # Should be a test line as it has color encoding
-
-
-def splitByPid(testlog):
- # Split testlog into prefixed logs based on pid
- baseFile = os.path.splitext(testlog[0])[0]
- p = Path(testlog[0])
- pids = set()
- logs = {}
- pid = None
- with p.open() as f:
- for line in readStripLines(f):
- stripped = ansi_escape.sub("", line.strip())
- if len(stripped) > 0:
- # Pull out the pid
- match = pid_regex.match(stripped)
-
- # Pids are at least two digits
- if match and len(match.group(1)) > 2:
- # Pid is found
- pid = int(match.group(1))
-
- # See if we've created a log for this pid or not
- if pid not in pids:
- pids.add(pid)
- logFile = "{}_{}.log".format(baseFile, pid)
- print("Writing to new log: " + logFile)
- logs[pid] = Path(logFile).open(mode="w")
-
- # Add this line to the log
- if pid is not None:
- logs[pid].write(line)
- # Close all of the open logs
- for key in logs:
- logs[key].close()
-
-
-def doWork(args):
- if not args.testlog:
- print("Test log should be passed")
- elif args.testoutput:
- printTestOutput(args.testlog)
- elif args.split:
- splitByPid(args.testlog)
- else:
- parser.print_usage()
-
-
-def main():
- doWork(parser.parse_args())
-
-
-if __name__ == "__main__":
- main()
diff --git a/pythonFiles/vscode_pytest/__init__.py b/pythonFiles/vscode_pytest/__init__.py
deleted file mode 100644
index a565fbf930a6..000000000000
--- a/pythonFiles/vscode_pytest/__init__.py
+++ /dev/null
@@ -1,772 +0,0 @@
-# Copyright (c) Microsoft Corporation. All rights reserved.
-# Licensed under the MIT License.
-
-import atexit
-import json
-import os
-import pathlib
-import sys
-import traceback
-
-import pytest
-
-script_dir = pathlib.Path(__file__).parent.parent
-sys.path.append(os.fspath(script_dir))
-sys.path.append(os.fspath(script_dir / "lib" / "python"))
-
-from typing import Any, Dict, List, Optional, Union
-
-from testing_tools import socket_manager
-from typing_extensions import Literal, TypedDict
-
-DEFAULT_PORT = 45454
-
-
-class TestData(TypedDict):
- """A general class that all test objects inherit from."""
-
- name: str
- path: pathlib.Path
- type_: Literal["class", "function", "file", "folder", "test", "error"]
- id_: str
-
-
-class TestItem(TestData):
- """A class defining test items."""
-
- lineno: str
- runID: str
-
-
-class TestNode(TestData):
- """A general class that handles all test data which contains children."""
-
- children: "list[Union[TestNode, TestItem, None]]"
-
-
-class VSCodePytestError(Exception):
- """A custom exception class for pytest errors."""
-
- def __init__(self, message):
- super().__init__(message)
-
-
-ERRORS = []
-IS_DISCOVERY = False
-map_id_to_path = dict()
-collected_tests_so_far = list()
-TEST_PORT = os.getenv("TEST_PORT")
-TEST_UUID = os.getenv("TEST_UUID")
-
-
-def pytest_load_initial_conftests(early_config, parser, args):
- global TEST_PORT
- global TEST_UUID
- TEST_PORT = os.getenv("TEST_PORT")
- TEST_UUID = os.getenv("TEST_UUID")
- if TEST_UUID is None or TEST_PORT is None:
- error_string = (
- "PYTEST ERROR: TEST_UUID and/or TEST_PORT are not set at the time of pytest starting. Please confirm these environment variables are not being"
- " changed or removed as they are required for successful test discovery and execution."
- f" \nTEST_UUID = {TEST_UUID}\nTEST_PORT = {TEST_PORT}\n"
- )
- print(error_string, file=sys.stderr)
- if "--collect-only" in args:
- global IS_DISCOVERY
- IS_DISCOVERY = True
-
-
-def pytest_internalerror(excrepr, excinfo):
- """A pytest hook that is called when an internal error occurs.
-
- Keyword arguments:
- excrepr -- the exception representation.
- excinfo -- the exception information of type ExceptionInfo.
- """
- # call.excinfo.exconly() returns the exception as a string.
- ERRORS.append(excinfo.exconly() + "\n Check Python Test Logs for more details.")
-
-
-def pytest_exception_interact(node, call, report):
- """A pytest hook that is called when an exception is raised which could be handled.
-
- Keyword arguments:
- node -- the node that raised the exception.
- call -- the call object.
- report -- the report object of either type CollectReport or TestReport.
- """
- # call.excinfo is the captured exception of the call, if it raised as type ExceptionInfo.
- # call.excinfo.exconly() returns the exception as a string.
- # If it is during discovery, then add the error to error logs.
- if IS_DISCOVERY:
- if call.excinfo and call.excinfo.typename != "AssertionError":
- if report.outcome == "skipped" and "SkipTest" in str(call):
- return
- ERRORS.append(
- call.excinfo.exconly() + "\n Check Python Test Logs for more details."
- )
- else:
- ERRORS.append(
- report.longreprtext + "\n Check Python Test Logs for more details."
- )
- else:
- # If during execution, send this data that the given node failed.
- report_value = "error"
- if call.excinfo.typename == "AssertionError":
- report_value = "failure"
- node_id = get_absolute_test_id(node.nodeid, get_node_path(node))
- if node_id not in collected_tests_so_far:
- collected_tests_so_far.append(node_id)
- item_result = create_test_outcome(
- node_id,
- report_value,
- "Test failed with exception",
- report.longreprtext,
- )
- collected_test = testRunResultDict()
- collected_test[node_id] = item_result
- cwd = pathlib.Path.cwd()
- execution_post(
- os.fsdecode(cwd),
- "success",
- collected_test if collected_test else None,
- )
-
-
-def get_absolute_test_id(test_id: str, testPath: pathlib.Path) -> str:
- """A function that returns the absolute test id. This is necessary because testIds are relative to the rootdir.
- This does not work for our case since testIds when referenced during run time are relative to the instantiation
- location. Absolute paths for testIds are necessary for the test tree ensures configurations that change the rootdir
- of pytest are handled correctly.
-
- Keyword arguments:
- test_id -- the pytest id of the test which is relative to the rootdir.
- testPath -- the path to the file the test is located in, as a pathlib.Path object.
- """
- split_id = test_id.split("::")[1:]
- absolute_test_id = "::".join([str(testPath), *split_id])
- return absolute_test_id
-
-
-def pytest_keyboard_interrupt(excinfo):
- """A pytest hook that is called when a keyboard interrupt is raised.
-
- Keyword arguments:
- excinfo -- the exception information of type ExceptionInfo.
- """
- # The function execonly() returns the exception as a string.
- ERRORS.append(excinfo.exconly() + "\n Check Python Test Logs for more details.")
-
-
-class TestOutcome(Dict):
- """A class that handles outcome for a single test.
-
- for pytest the outcome for a test is only 'passed', 'skipped' or 'failed'
- """
-
- test: str
- outcome: Literal["success", "failure", "skipped", "error"]
- message: Union[str, None]
- traceback: Union[str, None]
- subtest: Optional[str]
-
-
-def create_test_outcome(
- testid: str,
- outcome: str,
- message: Union[str, None],
- traceback: Union[str, None],
- subtype: Optional[str] = None,
-) -> TestOutcome:
- """A function that creates a TestOutcome object."""
- return TestOutcome(
- test=testid,
- outcome=outcome,
- message=message,
- traceback=traceback, # TODO: traceback
- subtest=None,
- )
-
-
-class testRunResultDict(Dict[str, Dict[str, TestOutcome]]):
- """A class that stores all test run results."""
-
- outcome: str
- tests: Dict[str, TestOutcome]
-
-
-@pytest.hookimpl(hookwrapper=True, trylast=True)
-def pytest_report_teststatus(report, config):
- """
- A pytest hook that is called when a test is called. It is called 3 times per test,
- during setup, call, and teardown.
- Keyword arguments:
- report -- the report on the test setup, call, and teardown.
- config -- configuration object.
- """
- cwd = pathlib.Path.cwd()
-
- if report.when == "call":
- traceback = None
- message = None
- report_value = "skipped"
- if report.passed:
- report_value = "success"
- elif report.failed:
- report_value = "failure"
- message = report.longreprtext
- try:
- node_path = map_id_to_path[report.nodeid]
- except KeyError:
- node_path = cwd
- # Calculate the absolute test id and use this as the ID moving forward.
- absolute_node_id = get_absolute_test_id(report.nodeid, node_path)
- if absolute_node_id not in collected_tests_so_far:
- collected_tests_so_far.append(absolute_node_id)
- item_result = create_test_outcome(
- absolute_node_id,
- report_value,
- message,
- traceback,
- )
- collected_test = testRunResultDict()
- collected_test[absolute_node_id] = item_result
- execution_post(
- os.fsdecode(cwd),
- "success",
- collected_test if collected_test else None,
- )
- yield
-
-
-ERROR_MESSAGE_CONST = {
- 2: "Pytest was unable to start or run any tests due to issues with test discovery or test collection.",
- 3: "Pytest was interrupted by the user, for example by pressing Ctrl+C during test execution.",
- 4: "Pytest encountered an internal error or exception during test execution.",
- 5: "Pytest was unable to find any tests to run.",
-}
-
-
-@pytest.hookimpl(hookwrapper=True, trylast=True)
-def pytest_runtest_protocol(item, nextitem):
- map_id_to_path[item.nodeid] = get_node_path(item)
- skipped = check_skipped_wrapper(item)
- if skipped:
- absolute_node_id = get_absolute_test_id(item.nodeid, get_node_path(item))
- report_value = "skipped"
- cwd = pathlib.Path.cwd()
- if absolute_node_id not in collected_tests_so_far:
- collected_tests_so_far.append(absolute_node_id)
- item_result = create_test_outcome(
- absolute_node_id,
- report_value,
- None,
- None,
- )
- collected_test = testRunResultDict()
- collected_test[absolute_node_id] = item_result
- execution_post(
- os.fsdecode(cwd),
- "success",
- collected_test if collected_test else None,
- )
- yield
-
-
-def check_skipped_wrapper(item):
- """A function that checks if a test is skipped or not by check its markers and its parent markers.
-
- Returns True if the test is marked as skipped at any level, False otherwise.
-
- Keyword arguments:
- item -- the pytest item object.
- """
- if item.own_markers:
- if check_skipped_condition(item):
- return True
- parent = item.parent
- while isinstance(parent, pytest.Class):
- if parent.own_markers:
- if check_skipped_condition(parent):
- return True
- parent = parent.parent
- return False
-
-
-def check_skipped_condition(item):
- """A helper function that checks if a item has a skip or a true skip condition.
-
- Keyword arguments:
- item -- the pytest item object.
- """
-
- for marker in item.own_markers:
- # If the test is marked with skip then it will not hit the pytest_report_teststatus hook,
- # therefore we need to handle it as skipped here.
- skip_condition = False
- if marker.name == "skipif":
- skip_condition = any(marker.args)
- if marker.name == "skip" or skip_condition:
- return True
- return False
-
-
-def pytest_sessionfinish(session, exitstatus):
- """A pytest hook that is called after pytest has fulled finished.
-
- Keyword arguments:
- session -- the pytest session object.
- exitstatus -- the status code of the session.
-
- Exit code 0: All tests were collected and passed successfully
- Exit code 1: Tests were collected and run but some of the tests failed
- Exit code 2: Test execution was interrupted by the user
- Exit code 3: Internal error happened while executing tests
- Exit code 4: pytest command line usage error
- Exit code 5: No tests were collected
- """
- cwd = pathlib.Path.cwd()
- if IS_DISCOVERY:
- if not (exitstatus == 0 or exitstatus == 1 or exitstatus == 5):
- errorNode: TestNode = {
- "name": "",
- "path": cwd,
- "type_": "error",
- "children": [],
- "id_": "",
- }
- post_response(os.fsdecode(cwd), errorNode)
- try:
- session_node: Union[TestNode, None] = build_test_tree(session)
- if not session_node:
- raise VSCodePytestError(
- "Something went wrong following pytest finish, \
- no session node was created"
- )
- post_response(os.fsdecode(cwd), session_node)
- except Exception as e:
- ERRORS.append(
- f"Error Occurred, traceback: {(traceback.format_exc() if e.__traceback__ else '')}"
- )
- errorNode: TestNode = {
- "name": "",
- "path": cwd,
- "type_": "error",
- "children": [],
- "id_": "",
- }
- post_response(os.fsdecode(cwd), errorNode)
- else:
- if exitstatus == 0 or exitstatus == 1:
- exitstatus_bool = "success"
- else:
- ERRORS.append(
- f"Pytest exited with error status: {exitstatus}, {ERROR_MESSAGE_CONST[exitstatus]}"
- )
- exitstatus_bool = "error"
-
- execution_post(
- os.fsdecode(cwd),
- exitstatus_bool,
- None,
- )
- # send end of transmission token
- command_type = "discovery" if IS_DISCOVERY else "execution"
- payload: EOTPayloadDict = {"command_type": command_type, "eot": True}
- send_post_request(payload)
-
-
-def build_test_tree(session: pytest.Session) -> TestNode:
- """Builds a tree made up of testing nodes from the pytest session.
-
- Keyword arguments:
- session -- the pytest session object.
- """
- session_node = create_session_node(session)
- session_children_dict: Dict[str, TestNode] = {}
- file_nodes_dict: Dict[Any, TestNode] = {}
- class_nodes_dict: Dict[str, TestNode] = {}
- function_nodes_dict: Dict[str, TestNode] = {}
-
- for test_case in session.items:
- test_node = create_test_node(test_case)
- if isinstance(test_case.parent, pytest.Class):
- case_iter = test_case.parent
- node_child_iter = test_node
- test_class_node: Union[TestNode, None] = None
- while isinstance(case_iter, pytest.Class):
- # While the given node is a class, create a class and nest the previous node as a child.
- try:
- test_class_node = class_nodes_dict[case_iter.nodeid]
- except KeyError:
- test_class_node = create_class_node(case_iter)
- class_nodes_dict[case_iter.nodeid] = test_class_node
- test_class_node["children"].append(node_child_iter)
- # Iterate up.
- node_child_iter = test_class_node
- case_iter = case_iter.parent
- # Now the parent node is not a class node, it is a file node.
- if case_iter:
- parent_module = case_iter
- else:
- ERRORS.append(f"Test class {case_iter} has no parent")
- break
- # Create a file node that has the last class as a child.
- try:
- test_file_node: TestNode = file_nodes_dict[parent_module]
- except KeyError:
- test_file_node = create_file_node(parent_module)
- file_nodes_dict[parent_module] = test_file_node
- # Check if the class is already a child of the file node.
- if (
- test_class_node is not None
- and test_class_node not in test_file_node["children"]
- ):
- test_file_node["children"].append(test_class_node)
- elif hasattr(test_case, "callspec"): # This means it is a parameterized test.
- function_name: str = ""
- # parameterized test cases cut the repetitive part of the name off.
- parent_part, parameterized_section = test_node["name"].split("[", 1)
- test_node["name"] = "[" + parameterized_section
- parent_path = os.fspath(get_node_path(test_case)) + "::" + parent_part
- try:
- function_name = test_case.originalname # type: ignore
- function_test_case = function_nodes_dict[parent_path]
- except AttributeError: # actual error has occurred
- ERRORS.append(
- f"unable to find original name for {test_case.name} with parameterization detected."
- )
- raise VSCodePytestError(
- "Unable to find original name for parameterized test case"
- )
- except KeyError:
- function_test_case: TestNode = create_parameterized_function_node(
- function_name, get_node_path(test_case), test_case.nodeid
- )
- function_nodes_dict[parent_path] = function_test_case
- function_test_case["children"].append(test_node)
- # Now, add the function node to file node.
- try:
- parent_test_case = file_nodes_dict[test_case.parent]
- except KeyError:
- parent_test_case = create_file_node(test_case.parent)
- file_nodes_dict[test_case.parent] = parent_test_case
- if function_test_case not in parent_test_case["children"]:
- parent_test_case["children"].append(function_test_case)
- else: # This includes test cases that are pytest functions or a doctests.
- try:
- parent_test_case = file_nodes_dict[test_case.parent]
- except KeyError:
- parent_test_case = create_file_node(test_case.parent)
- file_nodes_dict[test_case.parent] = parent_test_case
- parent_test_case["children"].append(test_node)
- created_files_folders_dict: Dict[str, TestNode] = {}
- for _, file_node in file_nodes_dict.items():
- # Iterate through all the files that exist and construct them into nested folders.
- root_folder_node: TestNode = build_nested_folders(
- file_node, created_files_folders_dict, session
- )
- # The final folder we get to is the highest folder in the path
- # and therefore we add this as a child to the session.
- root_id = root_folder_node.get("id_")
- if root_id and root_id not in session_children_dict:
- session_children_dict[root_id] = root_folder_node
- session_node["children"] = list(session_children_dict.values())
- return session_node
-
-
-def build_nested_folders(
- file_node: TestNode,
- created_files_folders_dict: Dict[str, TestNode],
- session: pytest.Session,
-) -> TestNode:
- """Takes a file or folder and builds the nested folder structure for it.
-
- Keyword arguments:
- file_module -- the created module for the file we are nesting.
- file_node -- the file node that we are building the nested folders for.
- created_files_folders_dict -- Dictionary of all the folders and files that have been created where the key is the path.
- session -- the pytest session object.
- """
- prev_folder_node = file_node
-
- # Begin the iterator_path one level above the current file.
- iterator_path = file_node["path"].parent
- while iterator_path != get_node_path(session):
- curr_folder_name = iterator_path.name
- try:
- curr_folder_node: TestNode = created_files_folders_dict[
- os.fspath(iterator_path)
- ]
- except KeyError:
- curr_folder_node: TestNode = create_folder_node(
- curr_folder_name, iterator_path
- )
- created_files_folders_dict[os.fspath(iterator_path)] = curr_folder_node
- if prev_folder_node not in curr_folder_node["children"]:
- curr_folder_node["children"].append(prev_folder_node)
- iterator_path = iterator_path.parent
- prev_folder_node = curr_folder_node
- return prev_folder_node
-
-
-def create_test_node(
- test_case: pytest.Item,
-) -> TestItem:
- """Creates a test node from a pytest test case.
-
- Keyword arguments:
- test_case -- the pytest test case.
- """
- test_case_loc: str = (
- str(test_case.location[1] + 1) if (test_case.location[1] is not None) else ""
- )
- absolute_test_id = get_absolute_test_id(test_case.nodeid, get_node_path(test_case))
- return {
- "name": test_case.name,
- "path": get_node_path(test_case),
- "lineno": test_case_loc,
- "type_": "test",
- "id_": absolute_test_id,
- "runID": absolute_test_id,
- }
-
-
-def create_session_node(session: pytest.Session) -> TestNode:
- """Creates a session node from a pytest session.
-
- Keyword arguments:
- session -- the pytest session.
- """
- node_path = get_node_path(session)
- return {
- "name": node_path.name,
- "path": node_path,
- "type_": "folder",
- "children": [],
- "id_": os.fspath(node_path),
- }
-
-
-def create_class_node(class_module: pytest.Class) -> TestNode:
- """Creates a class node from a pytest class object.
-
- Keyword arguments:
- class_module -- the pytest object representing a class module.
- """
- return {
- "name": class_module.name,
- "path": get_node_path(class_module),
- "type_": "class",
- "children": [],
- "id_": class_module.nodeid,
- }
-
-
-def create_parameterized_function_node(
- function_name: str, test_path: pathlib.Path, test_id: str
-) -> TestNode:
- """Creates a function node to be the parent for the parameterized test nodes.
-
- Keyword arguments:
- function_name -- the name of the function.
- test_path -- the path to the test file.
- test_id -- the id of the test, which is a parameterized test so it
- must be edited to get a unique id for the function node.
- """
- function_id: str = test_id.split("::")[0] + "::" + function_name
- return {
- "name": function_name,
- "path": test_path,
- "type_": "function",
- "children": [],
- "id_": function_id,
- }
-
-
-def create_file_node(file_module: Any) -> TestNode:
- """Creates a file node from a pytest file module.
-
- Keyword arguments:
- file_module -- the pytest file module.
- """
- node_path = get_node_path(file_module)
- return {
- "name": node_path.name,
- "path": node_path,
- "type_": "file",
- "id_": os.fspath(node_path),
- "children": [],
- }
-
-
-def create_folder_node(folder_name: str, path_iterator: pathlib.Path) -> TestNode:
- """Creates a folder node from a pytest folder name and its path.
-
- Keyword arguments:
- folderName -- the name of the folder.
- path_iterator -- the path of the folder.
- """
- return {
- "name": folder_name,
- "path": path_iterator,
- "type_": "folder",
- "id_": os.fspath(path_iterator),
- "children": [],
- }
-
-
-class DiscoveryPayloadDict(TypedDict):
- """A dictionary that is used to send a post request to the server."""
-
- cwd: str
- status: Literal["success", "error"]
- tests: Optional[TestNode]
- error: Optional[List[str]]
-
-
-class ExecutionPayloadDict(Dict):
- """
- A dictionary that is used to send a execution post request to the server.
- """
-
- cwd: str
- status: Literal["success", "error"]
- result: Union[testRunResultDict, None]
- not_found: Union[List[str], None] # Currently unused need to check
- error: Union[str, None] # Currently unused need to check
-
-
-class EOTPayloadDict(TypedDict):
- """A dictionary that is used to send a end of transmission post request to the server."""
-
- command_type: Union[Literal["discovery"], Literal["execution"]]
- eot: bool
-
-
-def get_node_path(node: Any) -> pathlib.Path:
- """A function that returns the path of a node given the switch to pathlib.Path."""
- path = getattr(node, "path", None) or pathlib.Path(node.fspath)
-
- if not path:
- raise VSCodePytestError(
- f"Unable to find path for node: {node}, node.path: {node.path}, node.fspath: {node.fspath}"
- )
- return path
-
-
-__socket = None
-atexit.register(lambda: __socket.close() if __socket else None)
-
-
-def execution_post(
- cwd: str, status: Literal["success", "error"], tests: Union[testRunResultDict, None]
-):
- """
- Sends a POST request with execution payload details.
-
- Args:
- cwd (str): Current working directory.
- status (Literal["success", "error"]): Execution status indicating success or error.
- tests (Union[testRunResultDict, None]): Test run results, if available.
- """
-
- payload: ExecutionPayloadDict = ExecutionPayloadDict(
- cwd=cwd, status=status, result=tests, not_found=None, error=None
- )
- if ERRORS:
- payload["error"] = ERRORS
- send_post_request(payload)
-
-
-def post_response(cwd: str, session_node: TestNode) -> None:
- """
- Sends a POST request with test session details in payload.
-
- Args:
- cwd (str): Current working directory.
- session_node (TestNode): Node information of the test session.
- """
-
- payload: DiscoveryPayloadDict = {
- "cwd": cwd,
- "status": "success" if not ERRORS else "error",
- "tests": session_node,
- "error": [],
- }
- if ERRORS is not None:
- payload["error"] = ERRORS
- send_post_request(payload, cls_encoder=PathEncoder)
-
-
-class PathEncoder(json.JSONEncoder):
- """A custom JSON encoder that encodes pathlib.Path objects as strings."""
-
- def default(self, obj):
- if isinstance(obj, pathlib.Path):
- return os.fspath(obj)
- return super().default(obj)
-
-
-def send_post_request(
- payload: Union[ExecutionPayloadDict, DiscoveryPayloadDict, EOTPayloadDict],
- cls_encoder=None,
-):
- """
- Sends a post request to the server.
-
- Keyword arguments:
- payload -- the payload data to be sent.
- cls_encoder -- a custom encoder if needed.
- """
- global TEST_PORT
- global TEST_UUID
- if TEST_UUID is None or TEST_PORT is None:
- # if TEST_UUID or TEST_PORT is None, print an error and fail as these are both critical errors
- error_msg = (
- "PYTEST ERROR: TEST_UUID and/or TEST_PORT are not set at the time of pytest starting. Please confirm these environment variables are not being"
- " changed or removed as they are required for successful pytest discovery and execution."
- f" \nTEST_UUID = {TEST_UUID}\nTEST_PORT = {TEST_PORT}\n"
- )
- print(error_msg, file=sys.stderr)
- raise VSCodePytestError(error_msg)
-
- addr = ("localhost", int(TEST_PORT))
- global __socket
-
- if __socket is None:
- try:
- __socket = socket_manager.SocketManager(addr)
- __socket.connect()
- except Exception as error:
- error_msg = f"Error attempting to connect to extension communication socket[vscode-pytest]: {error}"
- print(error_msg, file=sys.stderr)
- print(
- "If you are on a Windows machine, this error may be occurring if any of your tests clear environment variables"
- " as they are required to communicate with the extension. Please reference https://docs.pytest.org/en/stable/how-to/monkeypatch.html#monkeypatching-environment-variables"
- "for the correct way to clear environment variables during testing.\n",
- file=sys.stderr,
- )
- __socket = None
- raise VSCodePytestError(error_msg)
-
- data = json.dumps(payload, cls=cls_encoder)
- request = f"""Content-Length: {len(data)}
-Content-Type: application/json
-Request-uuid: {TEST_UUID}
-
-{data}"""
-
- try:
- if __socket is not None and __socket.socket is not None:
- __socket.socket.sendall(request.encode("utf-8"))
- else:
- print(
- f"Plugin error connection error[vscode-pytest], socket is None \n[vscode-pytest] data: \n{request} \n",
- file=sys.stderr,
- )
- except Exception as error:
- print(
- f"Plugin error, exception thrown while attempting to send data[vscode-pytest]: {error} \n[vscode-pytest] data: \n{request}\n",
- file=sys.stderr,
- )
diff --git a/pythonFiles/vscode_pytest/run_pytest_script.py b/pythonFiles/vscode_pytest/run_pytest_script.py
deleted file mode 100644
index 8005f3a32c0e..000000000000
--- a/pythonFiles/vscode_pytest/run_pytest_script.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (c) Microsoft Corporation.
-# Licensed under the MIT License.
-import json
-import os
-import pathlib
-import socket
-import sys
-
-import pytest
-
-script_dir = pathlib.Path(__file__).parent.parent
-sys.path.append(os.fspath(script_dir))
-sys.path.append(os.fspath(script_dir / "lib" / "python"))
-from testing_tools import process_json_util
-
-# This script handles running pytest via pytest.main(). It is called via run in the
-# pytest execution adapter and gets the test_ids to run via stdin and the rest of the
-# args through sys.argv. It then runs pytest.main() with the args and test_ids.
-
-if __name__ == "__main__":
- # Add the root directory to the path so that we can import the plugin.
- directory_path = pathlib.Path(__file__).parent.parent
- sys.path.append(os.fspath(directory_path))
- sys.path.insert(0, os.getcwd())
- # Get the rest of the args to run with pytest.
- args = sys.argv[1:]
- run_test_ids_port = os.environ.get("RUN_TEST_IDS_PORT")
- run_test_ids_port_int = (
- int(run_test_ids_port) if run_test_ids_port is not None else 0
- )
- if run_test_ids_port_int == 0:
- print("Error[vscode-pytest]: RUN_TEST_IDS_PORT env var is not set.")
- test_ids_from_buffer = []
- try:
- client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- client_socket.connect(("localhost", run_test_ids_port_int))
- print(f"CLIENT: Server listening on port {run_test_ids_port_int}...")
- buffer = b""
-
- while True:
- # Receive the data from the client
- data = client_socket.recv(1024 * 1024)
- if not data:
- break
-
- # Append the received data to the buffer
- buffer += data
-
- try:
- # Try to parse the buffer as JSON
- test_ids_from_buffer = process_json_util.process_rpc_json(
- buffer.decode("utf-8")
- )
- # Clear the buffer as complete JSON object is received
- buffer = b""
- print("Received JSON data in run script")
- break
- except json.JSONDecodeError:
- # JSON decoding error, the complete JSON object is not yet received
- continue
- except socket.error as e:
- print(f"Error: Could not connect to runTestIdsPort: {e}")
- print("Error: Could not connect to runTestIdsPort")
- try:
- if test_ids_from_buffer:
- arg_array = ["-p", "vscode_pytest"] + args + test_ids_from_buffer
- print("Running pytest with args: " + str(arg_array))
- pytest.main(arg_array)
- else:
- print(
- "Error: No test ids received from stdin, could be an error or a run request without ids provided.",
- )
- print("Running pytest with no test ids as args. Args being used: ", args)
- arg_array = ["-p", "vscode_pytest"] + args
- pytest.main(arg_array)
- except json.JSONDecodeError:
- print("Error: Could not parse test ids from stdin")
diff --git a/pythonFiles/.env b/python_files/.env
similarity index 100%
rename from pythonFiles/.env
rename to python_files/.env
diff --git a/pythonFiles/.vscode/settings.json b/python_files/.vscode/settings.json
similarity index 100%
rename from pythonFiles/.vscode/settings.json
rename to python_files/.vscode/settings.json
diff --git a/pythonFiles/Notebooks intro.ipynb b/python_files/Notebooks intro.ipynb
similarity index 81%
rename from pythonFiles/Notebooks intro.ipynb
rename to python_files/Notebooks intro.ipynb
index 850d7f5a86f9..0e8aadad1919 100644
--- a/pythonFiles/Notebooks intro.ipynb
+++ b/python_files/Notebooks intro.ipynb
@@ -11,7 +11,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "1. Open the command palette with the shortcut: `Ctrl/Command` + `Shift` + `P`\r\n",
+ "1. Open the command palette with the shortcut: `Ctrl/Command` + `Shift` + `P`\n",
"2. Search for the command `Create New Blank Notebook`"
]
},
@@ -26,8 +26,8 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "1. Open the command palette with the shortcut: `Ctrl/Command` + `Shift` + `P`\r\n",
- "\r\n",
+ "1. Open the command palette with the shortcut: `Ctrl/Command` + `Shift` + `P`\n",
+ "\n",
"2. Search for the command `Python: Open Start Page`"
]
},
@@ -42,10 +42,10 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "You are currently viewing what we call our Notebook Editor. It is an interactive document based on Jupyter Notebooks that supports the intermixing of code, outputs and markdown documentation. \r\n",
- "\r\n",
- "This cell is a markdown cell. To edit the text in this cell, simply double click on the cell to change it into edit mode.\r\n",
- "\r\n",
+ "You are currently viewing what we call our Notebook Editor. It is an interactive document based on Jupyter Notebooks that supports the intermixing of code, outputs and markdown documentation. \n",
+ "\n",
+ "This cell is a markdown cell. To edit the text in this cell, simply double click on the cell to change it into edit mode.\n",
+ "\n",
"The next cell below is a code cell. You can switch a cell between code and markdown by clicking on the code  /markdown  icons or using the keyboard shortcut `M` and `Y` respectively."
]
},
@@ -55,16 +55,16 @@
"metadata": {},
"outputs": [],
"source": [
- "print('hello world')"
+ "print(\"hello world\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "* To execute the code in the cell above, click on the cell to select it and then either press the play  button in the cell toolbar, or use the keyboard shortcut `Ctrl/Command` + `Enter`.\r\n",
- "* To edit the code, just click in cell and start editing.\r\n",
- "* To add a new cell below, click the `Add Cell` icon  at the bottom left of the cell or enter command mode with the `ESC` Key and then use the keyboard shortcut `B` to create the new cell below.\r\n"
+ "* To execute the code in the cell above, click on the cell to select it and then either press the play  button in the cell toolbar, or use the keyboard shortcut `Ctrl/Command` + `Enter`.\n",
+ "* To edit the code, just click in cell and start editing.\n",
+ "* To add a new cell below, click the `Add Cell` icon  at the bottom left of the cell or enter command mode with the `ESC` Key and then use the keyboard shortcut `B` to create the new cell below.\n"
]
},
{
@@ -78,40 +78,40 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "**Variable explorer**\r\n",
- "\r\n",
- "To view all your active variables and their current values in the notebook, click on the variable explorer icon  in the top toolbar.\r\n",
- "\r\n",
- "\r\n",
- "\r\n",
- "**Data Viewer**\r\n",
- "\r\n",
- "To view your data frame in a more visual \"Excel\" like format, open the variable explorer and to the left of any dataframe object, you will see the data viewer icon  which you can click to open the data viewer.\r\n",
- "\r\n",
- "\r\n",
- "\r\n",
- "**Convert to Python File**\r\n",
- "\r\n",
- "To export your notebook to a Python file (.py), click on the `Convert to Python script` icon  in the top toolbar \r\n",
- "\r\n",
- "\r\n",
- "\r\n",
- "**Plot Viewer**\r\n",
- "\r\n",
- "If you have a graph (such as matplotlib) in your output, you'll notice if you hover over the graph, the `Plot Viewer` icon  will appear in the top left. Click the icon to open up the graph in the Plotviewer which allows you to zoom on your plots and export it in formats such as png and jpeg.\r\n",
- "\r\n",
- "\r\n",
- "\r\n",
- "**Switching Kernels**\r\n",
- "\r\n",
- "The notebook editor will detect all kernels in your system by default. To change your notebook kernel, click on the kernel status in the top toolbar at the far right. For example, your kernel status may say \"Python 3: Idle\". This will open up the kernel selector where you can choose your desired kernel.\r\n",
- "\r\n",
- "\r\n",
- "\r\n",
- "**Remote Jupyter Server**\r\n",
- "\r\n",
- "To connect to a remote Jupyter server, open the command prompt and search for the command `Specify remote or local Jupyter server for connections`. Then select `Existing` and enter the remote Jupyter server URL. Afterwards, you'll be prompted to reload the window and the Notebook will be opened connected to the remote Jupyter server.\r\n",
- "\r\n",
+ "**Variable explorer**\n",
+ "\n",
+ "To view all your active variables and their current values in the notebook, click on the variable explorer icon  in the top toolbar.\n",
+ "\n",
+ "\n",
+ "\n",
+ "**Data Viewer**\n",
+ "\n",
+ "To view your data frame in a more visual \"Excel\" like format, open the variable explorer and to the left of any dataframe object, you will see the data viewer icon  which you can click to open the data viewer.\n",
+ "\n",
+ "\n",
+ "\n",
+ "**Convert to Python File**\n",
+ "\n",
+ "To export your notebook to a Python file (.py), click on the `Convert to Python script` icon  in the top toolbar \n",
+ "\n",
+ "\n",
+ "\n",
+ "**Plot Viewer**\n",
+ "\n",
+ "If you have a graph (such as matplotlib) in your output, you'll notice if you hover over the graph, the `Plot Viewer` icon  will appear in the top left. Click the icon to open up the graph in the Plotviewer which allows you to zoom on your plots and export it in formats such as png and jpeg.\n",
+ "\n",
+ "\n",
+ "\n",
+ "**Switching Kernels**\n",
+ "\n",
+ "The notebook editor will detect all kernels in your system by default. To change your notebook kernel, click on the kernel status in the top toolbar at the far right. For example, your kernel status may say \"Python 3: Idle\". This will open up the kernel selector where you can choose your desired kernel.\n",
+ "\n",
+ "\n",
+ "\n",
+ "**Remote Jupyter Server**\n",
+ "\n",
+ "To connect to a remote Jupyter server, open the command prompt and search for the command `Specify remote or local Jupyter server for connections`. Then select `Existing` and enter the remote Jupyter server URL. Afterwards, you'll be prompted to reload the window and the Notebook will be opened connected to the remote Jupyter server.\n",
+ "\n",
""
]
},
@@ -129,7 +129,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "- [Data science tutorial for Visual Studio Code](https://code.visualstudio.com/docs/python/data-science-tutorial)\r\n",
+ "- [Data science tutorial for Visual Studio Code](https://code.visualstudio.com/docs/python/data-science-tutorial)\n",
"- [Jupyter Notebooks in Visual Studio Code documentation](https://code.visualstudio.com/docs/python/jupyter-support)"
]
}
@@ -145,9 +145,10 @@
"name": "python3"
},
"language_info": {
+ "name": "python",
"version": "3.8.6-final"
}
},
"nbformat": 4,
"nbformat_minor": 0
-}
\ No newline at end of file
+}
diff --git a/pythonFiles/create_conda.py b/python_files/create_conda.py
similarity index 87%
rename from pythonFiles/create_conda.py
rename to python_files/create_conda.py
index 15320a8a1ce6..284f734081b2 100644
--- a/pythonFiles/create_conda.py
+++ b/python_files/create_conda.py
@@ -48,19 +48,19 @@ def parse_args(argv: Sequence[str]) -> argparse.Namespace:
def file_exists(path: Union[str, pathlib.PurePath]) -> bool:
- return os.path.exists(path)
+ return os.path.exists(path) # noqa: PTH110
def conda_env_exists(name: Union[str, pathlib.PurePath]) -> bool:
- return os.path.exists(CWD / name)
+ return os.path.exists(CWD / name) # noqa: PTH110
def run_process(args: Sequence[str], error_message: str) -> None:
try:
print("Running: " + " ".join(args))
- subprocess.run(args, cwd=os.getcwd(), check=True)
- except subprocess.CalledProcessError:
- raise VenvError(error_message)
+ subprocess.run(args, cwd=os.getcwd(), check=True) # noqa: PTH109
+ except subprocess.CalledProcessError as exc:
+ raise VenvError(error_message) from exc
def get_conda_env_path(name: str) -> str:
@@ -89,11 +89,10 @@ def install_packages(env_path: str) -> None:
def add_gitignore(name: str) -> None:
- git_ignore = os.fspath(CWD / name / ".gitignore")
- if not file_exists(git_ignore):
- print(f"Creating: {git_ignore}")
- with open(git_ignore, "w") as f:
- f.write("*")
+ git_ignore = CWD / name / ".gitignore"
+ if not git_ignore.is_file():
+ print(f"Creating: {os.fsdecode(git_ignore)}")
+ git_ignore.write_text("*")
def main(argv: Optional[Sequence[str]] = None) -> None:
diff --git a/pythonFiles/create_microvenv.py b/python_files/create_microvenv.py
similarity index 87%
rename from pythonFiles/create_microvenv.py
rename to python_files/create_microvenv.py
index 10eae38ab977..2f2135444bc1 100644
--- a/pythonFiles/create_microvenv.py
+++ b/python_files/create_microvenv.py
@@ -20,9 +20,9 @@ class MicroVenvError(Exception):
def run_process(args: Sequence[str], error_message: str) -> None:
try:
print("Running: " + " ".join(args))
- subprocess.run(args, cwd=os.getcwd(), check=True)
- except subprocess.CalledProcessError:
- raise MicroVenvError(error_message)
+ subprocess.run(args, cwd=os.getcwd(), check=True) # noqa: PTH109
+ except subprocess.CalledProcessError as exc:
+ raise MicroVenvError(error_message) from exc
def parse_args(argv: Sequence[str]) -> argparse.Namespace:
diff --git a/pythonFiles/create_venv.py b/python_files/create_venv.py
similarity index 84%
rename from pythonFiles/create_venv.py
rename to python_files/create_venv.py
index 092286f986cf..83106bd889f8 100644
--- a/pythonFiles/create_venv.py
+++ b/python_files/create_venv.py
@@ -36,6 +36,7 @@ def parse_args(argv: Sequence[str]) -> argparse.Namespace:
default=None,
help="Install additional dependencies from sources like `pyproject.toml` into the virtual environment.",
)
+
parser.add_argument(
"--extras",
action="append",
@@ -49,6 +50,7 @@ def parse_args(argv: Sequence[str]) -> argparse.Namespace:
default=False,
help="Add .gitignore to the newly created virtual environment.",
)
+
parser.add_argument(
"--name",
default=VENV_NAME,
@@ -57,12 +59,14 @@ def parse_args(argv: Sequence[str]) -> argparse.Namespace:
metavar="NAME",
action="store",
)
+
parser.add_argument(
"--stdin",
action="store_true",
default=False,
help="Read arguments from stdin.",
)
+
return parser.parse_args(argv)
@@ -71,26 +75,43 @@ def is_installed(module: str) -> bool:
def file_exists(path: Union[str, pathlib.PurePath]) -> bool:
- return os.path.exists(path)
+ return pathlib.Path(path).exists()
+
+
+def is_file(path: Union[str, pathlib.PurePath]) -> bool:
+ return pathlib.Path(path).is_file()
def venv_exists(name: str) -> bool:
- return os.path.exists(CWD / name) and file_exists(get_venv_path(name))
+ return (
+ (CWD / name).exists()
+ and (CWD / name / "pyvenv.cfg").exists()
+ and file_exists(get_venv_path(name))
+ )
def run_process(args: Sequence[str], error_message: str) -> None:
try:
print("Running: " + " ".join(args))
- subprocess.run(args, cwd=os.getcwd(), check=True)
- except subprocess.CalledProcessError:
- raise VenvError(error_message)
+ subprocess.run(args, cwd=os.getcwd(), check=True) # noqa: PTH109
+ except subprocess.CalledProcessError as exc:
+ raise VenvError(error_message) from exc
+
+
+def get_win_venv_path(name: str) -> str:
+ venv_dir = CWD / name
+ # If using MSYS2 Python, the Python executable is located in the 'bin' directory.
+ if file_exists(venv_dir / "bin" / "python.exe"):
+ return os.fspath(venv_dir / "bin" / "python.exe")
+ else:
+ return os.fspath(venv_dir / "Scripts" / "python.exe")
def get_venv_path(name: str) -> str:
# See `venv` doc here for more details on binary location:
# https://docs.python.org/3/library/venv.html#creating-virtual-environments
if sys.platform == "win32":
- return os.fspath(CWD / name / "Scripts" / "python.exe")
+ return get_win_venv_path(name)
else:
return os.fspath(CWD / name / "bin" / "python")
@@ -126,12 +147,15 @@ def upgrade_pip(venv_path: str) -> None:
print("CREATE_VENV.UPGRADED_PIP")
+def create_gitignore(git_ignore: Union[str, pathlib.PurePath]):
+ print("Creating:", os.fspath(git_ignore))
+ pathlib.Path(git_ignore).write_text("*")
+
+
def add_gitignore(name: str) -> None:
git_ignore = CWD / name / ".gitignore"
- if not file_exists(git_ignore):
- print("Creating: " + os.fspath(git_ignore))
- with open(git_ignore, "w") as f:
- f.write("*")
+ if not is_file(git_ignore):
+ create_gitignore(git_ignore)
def download_pip_pyz(name: str):
@@ -140,13 +164,10 @@ def download_pip_pyz(name: str):
try:
with url_lib.urlopen(url) as response:
- pip_pyz_path = os.fspath(CWD / name / "pip.pyz")
- with open(pip_pyz_path, "wb") as out_file:
- data = response.read()
- out_file.write(data)
- out_file.flush()
- except Exception:
- raise VenvError("CREATE_VENV.DOWNLOAD_PIP_FAILED")
+ pip_pyz_path = CWD / name / "pip.pyz"
+ pip_pyz_path.write_bytes(data=response.read())
+ except Exception as exc:
+ raise VenvError("CREATE_VENV.DOWNLOAD_PIP_FAILED") from exc
def install_pip(name: str):
diff --git a/pythonFiles/deactivate/bash/deactivate b/python_files/deactivate/bash/deactivate
similarity index 100%
rename from pythonFiles/deactivate/bash/deactivate
rename to python_files/deactivate/bash/deactivate
diff --git a/pythonFiles/deactivate/fish/deactivate b/python_files/deactivate/fish/deactivate
similarity index 100%
rename from pythonFiles/deactivate/fish/deactivate
rename to python_files/deactivate/fish/deactivate
diff --git a/pythonFiles/deactivate/powershell/deactivate.ps1 b/python_files/deactivate/powershell/deactivate.ps1
similarity index 100%
rename from pythonFiles/deactivate/powershell/deactivate.ps1
rename to python_files/deactivate/powershell/deactivate.ps1
diff --git a/pythonFiles/deactivate/zsh/deactivate b/python_files/deactivate/zsh/deactivate
similarity index 100%
rename from pythonFiles/deactivate/zsh/deactivate
rename to python_files/deactivate/zsh/deactivate
diff --git a/pythonFiles/download_get_pip.py b/python_files/download_get_pip.py
similarity index 52%
rename from pythonFiles/download_get_pip.py
rename to python_files/download_get_pip.py
index b8238d60f261..91ab107760d8 100644
--- a/pythonFiles/download_get_pip.py
+++ b/python_files/download_get_pip.py
@@ -2,19 +2,19 @@
# Licensed under the MIT License.
import json
-import os
import pathlib
import urllib.request as url_lib
+
from packaging.version import parse as version_parser
EXTENSION_ROOT = pathlib.Path(__file__).parent.parent
-GET_PIP_DEST = EXTENSION_ROOT / "pythonFiles"
+GET_PIP_DEST = EXTENSION_ROOT / "python_files"
PIP_PACKAGE = "pip"
PIP_VERSION = "latest" # Can be "latest", or specific version "23.1.2"
def _get_package_data():
- json_uri = "https://pypi.org/pypi/{0}/json".format(PIP_PACKAGE)
+ json_uri = f"https://pypi.org/pypi/{PIP_PACKAGE}/json"
# Response format: https://warehouse.readthedocs.io/api-reference/json/#project
# Release metadata format: https://github.com/pypa/interoperability-peps/blob/master/pep-0426-core-metadata.rst
with url_lib.urlopen(json_uri) as response:
@@ -22,12 +22,12 @@ def _get_package_data():
def _download_and_save(root, version):
- root = os.getcwd() if root is None or root == "." else root
+ root = pathlib.Path.cwd() if root is None or root == "." else pathlib.Path(root)
url = f"https://raw.githubusercontent.com/pypa/get-pip/{version}/public/get-pip.py"
print(url)
with url_lib.urlopen(url) as response:
data = response.read()
- get_pip_file = pathlib.Path(root) / "get-pip.py"
+ get_pip_file = root / "get-pip.py"
get_pip_file.write_bytes(data)
@@ -35,11 +35,24 @@ def main(root):
data = _get_package_data()
if PIP_VERSION == "latest":
- use_version = max(data["releases"].keys(), key=version_parser)
+ # Pick latest 5 versions to try and get-pip
+ sorted_versions = sorted(data["releases"].keys(), key=version_parser, reverse=True)[:5]
+ downloaded = False
+ while sorted_versions:
+ use_version = sorted_versions.pop(0)
+ try:
+ print(f"Trying version: get-pip == {use_version}")
+ _download_and_save(root, use_version)
+ downloaded = True
+ break
+ except Exception as e:
+ print(f"Failed to download get-pip == {use_version}: {e}")
+ print(f"NExt attempt(s) with versions: {sorted_versions}")
+ if not downloaded:
+ raise Exception("Failed to download get-pip.py")
else:
use_version = PIP_VERSION
-
- _download_and_save(root, use_version)
+ _download_and_save(root, use_version)
if __name__ == "__main__":
diff --git a/pythonFiles/get_output_via_markers.py b/python_files/get_output_via_markers.py
similarity index 89%
rename from pythonFiles/get_output_via_markers.py
rename to python_files/get_output_via_markers.py
index 00dd57065b3c..e37f7f8c5df0 100644
--- a/pythonFiles/get_output_via_markers.py
+++ b/python_files/get_output_via_markers.py
@@ -18,9 +18,9 @@
del sys.argv[0]
exec(code, ns, ns)
elif module.startswith("-m"):
- moduleName = sys.argv[2]
+ module_name = sys.argv[2]
sys.argv = sys.argv[2:] # It should begin with the module name.
- runpy.run_module(moduleName, run_name="__main__", alter_sys=True)
+ runpy.run_module(module_name, run_name="__main__", alter_sys=True)
elif module.endswith(".py"):
sys.argv = sys.argv[1:]
runpy.run_path(module, run_name="__main__")
diff --git a/python_files/get_variable_info.py b/python_files/get_variable_info.py
new file mode 100644
index 000000000000..d60795982617
--- /dev/null
+++ b/python_files/get_variable_info.py
@@ -0,0 +1,539 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See LICENSE in the project root
+# for license information.
+
+import locale
+import sys
+from typing import ClassVar
+
+
+# this class is from in ptvsd/debugpy tools
+class SafeRepr(object): # noqa: UP004
+ # Can be used to override the encoding from locale.getpreferredencoding()
+ locale_preferred_encoding = None
+
+ # Can be used to override the encoding used for sys.stdout.encoding
+ sys_stdout_encoding = None
+
+ # String types are truncated to maxstring_outer when at the outer-
+ # most level, and truncated to maxstring_inner characters inside
+ # collections.
+ maxstring_outer = 2**16
+ maxstring_inner = 128
+ string_types = (str, bytes)
+ bytes = bytes
+ set_info = (set, "{", "}", False)
+ frozenset_info = (frozenset, "frozenset({", "})", False)
+ int_types = (int,)
+ long_iter_types = (list, tuple, bytearray, range, dict, set, frozenset)
+
+ # Collection types are recursively iterated for each limit in
+ # maxcollection.
+ maxcollection = (60, 20)
+
+ # Specifies type, prefix string, suffix string, and whether to include a
+ # comma if there is only one element. (Using a sequence rather than a
+ # mapping because we use isinstance() to determine the matching type.)
+ collection_types = [ # noqa: RUF012
+ (tuple, "(", ")", True),
+ (list, "[", "]", False),
+ frozenset_info,
+ set_info,
+ ]
+ try:
+ from collections import deque
+
+ collection_types.append((deque, "deque([", "])", False))
+ except Exception:
+ pass
+
+ # type, prefix string, suffix string, item prefix string,
+ # item key/value separator, item suffix string
+ dict_types: ClassVar[list] = [(dict, "{", "}", "", ": ", "")]
+ try:
+ from collections import OrderedDict
+
+ dict_types.append((OrderedDict, "OrderedDict([", "])", "(", ", ", ")"))
+ except Exception:
+ pass
+
+ # All other types are treated identically to strings, but using
+ # different limits.
+ maxother_outer = 2**16
+ maxother_inner = 128
+
+ convert_to_hex = False
+ raw_value = False
+
+ def __call__(self, obj):
+ """
+ :param object obj:
+ The object for which we want a representation.
+
+ :return str:
+ Returns bytes encoded as utf-8 on py2 and str on py3.
+ """ # noqa: D205
+ try:
+ return "".join(self._repr(obj, 0))
+ except Exception:
+ try:
+ return f"An exception was raised: {sys.exc_info()[1]!r}"
+ except Exception:
+ return "An exception was raised"
+
+ def _repr(self, obj, level):
+ """Returns an iterable of the parts in the final repr string."""
+ try:
+ obj_repr = type(obj).__repr__
+ except Exception:
+ obj_repr = None
+
+ def has_obj_repr(t):
+ r = t.__repr__
+ try:
+ return obj_repr == r
+ except Exception:
+ return obj_repr is r
+
+ for t, prefix, suffix, comma in self.collection_types:
+ if isinstance(obj, t) and has_obj_repr(t):
+ return self._repr_iter(obj, level, prefix, suffix, comma)
+
+ for (
+ t,
+ prefix,
+ suffix,
+ item_prefix,
+ item_sep,
+ item_suffix,
+ ) in self.dict_types:
+ if isinstance(obj, t) and has_obj_repr(t):
+ return self._repr_dict(
+ obj, level, prefix, suffix, item_prefix, item_sep, item_suffix
+ )
+
+ for t in self.string_types:
+ if isinstance(obj, t) and has_obj_repr(t):
+ return self._repr_str(obj, level)
+
+ if self._is_long_iter(obj):
+ return self._repr_long_iter(obj)
+
+ return self._repr_other(obj, level)
+
+ # Determines whether an iterable exceeds the limits set in
+ # maxlimits, and is therefore unsafe to repr().
+ def _is_long_iter(self, obj, level=0):
+ try:
+ # Strings have their own limits (and do not nest). Because
+ # they don't have __iter__ in 2.x, this check goes before
+ # the next one.
+ if isinstance(obj, self.string_types):
+ return len(obj) > self.maxstring_inner
+
+ # If it's not an iterable (and not a string), it's fine.
+ if not hasattr(obj, "__iter__"):
+ return False
+
+ # If it's not an instance of these collection types then it
+ # is fine. Note: this is a fix for
+ # https://github.com/Microsoft/ptvsd/issues/406
+ if not isinstance(obj, self.long_iter_types):
+ return False
+
+ # Iterable is its own iterator - this is a one-off iterable
+ # like generator or enumerate(). We can't really count that,
+ # but repr() for these should not include any elements anyway,
+ # so we can treat it the same as non-iterables.
+ if obj is iter(obj):
+ return False
+
+ # range reprs fine regardless of length.
+ if isinstance(obj, range):
+ return False
+
+ # numpy and scipy collections (ndarray etc) have
+ # self-truncating repr, so they're always safe.
+ try:
+ module = type(obj).__module__.partition(".")[0]
+ if module in ("numpy", "scipy"):
+ return False
+ except Exception:
+ pass
+
+ # Iterables that nest too deep are considered long.
+ if level >= len(self.maxcollection):
+ return True
+
+ # It is too long if the length exceeds the limit, or any
+ # of its elements are long iterables.
+ if hasattr(obj, "__len__"):
+ try:
+ size = len(obj)
+ except Exception:
+ size = None
+ if size is not None and size > self.maxcollection[level]:
+ return True
+ return any(self._is_long_iter(item, level + 1) for item in obj)
+ return any(
+ i > self.maxcollection[level] or self._is_long_iter(item, level + 1)
+ for i, item in enumerate(obj)
+ )
+
+ except Exception:
+ # If anything breaks, assume the worst case.
+ return True
+
+ def _repr_iter(self, obj, level, prefix, suffix, comma_after_single_element=False): # noqa: FBT002
+ yield prefix
+
+ if level >= len(self.maxcollection):
+ yield "..."
+ else:
+ count = self.maxcollection[level]
+ yield_comma = False
+ for item in obj:
+ if yield_comma:
+ yield ", "
+ yield_comma = True
+
+ count -= 1
+ if count <= 0:
+ yield "..."
+ break
+
+ yield from self._repr(item, 100 if item is obj else level + 1)
+ else:
+ if comma_after_single_element: # noqa: SIM102
+ if count == self.maxcollection[level] - 1:
+ yield ","
+ yield suffix
+
+ def _repr_long_iter(self, obj):
+ try:
+ length = hex(len(obj)) if self.convert_to_hex else len(obj)
+ obj_repr = f"<{type(obj).__name__}, len() = {length}>"
+ except Exception:
+ try:
+ obj_repr = "<" + type(obj).__name__ + ">"
+ except Exception:
+ obj_repr = ""
+ yield obj_repr
+
+ def _repr_dict(self, obj, level, prefix, suffix, item_prefix, item_sep, item_suffix):
+ if not obj:
+ yield prefix + suffix
+ return
+ if level >= len(self.maxcollection):
+ yield prefix + "..." + suffix
+ return
+
+ yield prefix
+
+ count = self.maxcollection[level]
+ yield_comma = False
+
+ obj_keys = list(obj)
+
+ for key in obj_keys:
+ if yield_comma:
+ yield ", "
+ yield_comma = True
+
+ count -= 1
+ if count <= 0:
+ yield "..."
+ break
+
+ yield item_prefix
+ for p in self._repr(key, level + 1):
+ yield p
+
+ yield item_sep
+
+ try:
+ item = obj[key]
+ except Exception:
+ yield ">"
+ else:
+ for p in self._repr(item, 100 if item is obj else level + 1):
+ yield p
+ yield item_suffix
+
+ yield suffix
+
+ def _repr_str(self, obj, level):
+ try:
+ if self.raw_value:
+ # For raw value retrieval, ignore all limits.
+ if isinstance(obj, bytes):
+ yield obj.decode("latin-1")
+ else:
+ yield obj
+ return
+
+ limit_inner = self.maxother_inner
+ limit_outer = self.maxother_outer
+ limit = limit_inner if level > 0 else limit_outer
+ if len(obj) <= limit:
+ # Note that we check the limit before doing the repr (so, the final string
+ # may actually be considerably bigger on some cases, as besides
+ # the additional u, b, ' chars, some chars may be escaped in repr, so
+ # even a single char such as \U0010ffff may end up adding more
+ # chars than expected).
+ yield self._convert_to_unicode_or_bytes_repr(repr(obj))
+ return
+
+ # Slightly imprecise calculations - we may end up with a string that is
+ # up to 6 characters longer than limit. If you need precise formatting,
+ # you are using the wrong class.
+ left_count, right_count = max(1, int(2 * limit / 3)), max(1, int(limit / 3))
+
+ # Important: only do repr after slicing to avoid duplicating a byte array that could be
+ # huge.
+
+ # Note: we don't deal with high surrogates here because we're not dealing with the
+ # repr() of a random object.
+ # i.e.: A high surrogate unicode char may be splitted on Py2, but as we do a `repr`
+ # afterwards, that's ok.
+
+ # Also, we just show the unicode/string/bytes repr() directly to make clear what the
+ # input type was (so, on py2 a unicode would start with u' and on py3 a bytes would
+ # start with b').
+
+ part1 = obj[:left_count]
+ part1 = repr(part1)
+ part1 = part1[: part1.rindex("'")] # Remove the last '
+
+ part2 = obj[-right_count:]
+ part2 = repr(part2)
+ part2 = part2[part2.index("'") + 1 :] # Remove the first ' (and possibly u or b).
+
+ yield part1
+ yield "..."
+ yield part2
+ except: # noqa: E722
+ # This shouldn't really happen, but let's play it safe.
+ # exception('Error getting string representation to show.')
+ yield from self._repr_obj(obj, level, self.maxother_inner, self.maxother_outer)
+
+ def _repr_other(self, obj, level):
+ return self._repr_obj(obj, level, self.maxother_inner, self.maxother_outer)
+
+ def _repr_obj(self, obj, level, limit_inner, limit_outer):
+ try:
+ if self.raw_value:
+ # For raw value retrieval, ignore all limits.
+ if isinstance(obj, bytes):
+ yield obj.decode("latin-1")
+ return
+
+ try:
+ mv = memoryview(obj)
+ except Exception:
+ yield self._convert_to_unicode_or_bytes_repr(repr(obj))
+ return
+ else:
+ # Map bytes to Unicode codepoints with same values.
+ yield mv.tobytes().decode("latin-1")
+ return
+ elif self.convert_to_hex and isinstance(obj, self.int_types):
+ obj_repr = hex(obj)
+ else:
+ obj_repr = repr(obj)
+ except Exception:
+ try:
+ obj_repr = object.__repr__(obj)
+ except Exception:
+ try:
+ obj_repr = ""
+ except Exception:
+ obj_repr = ""
+
+ limit = limit_inner if level > 0 else limit_outer
+
+ if limit >= len(obj_repr):
+ yield self._convert_to_unicode_or_bytes_repr(obj_repr)
+ return
+
+ # Slightly imprecise calculations - we may end up with a string that is
+ # up to 3 characters longer than limit. If you need precise formatting,
+ # you are using the wrong class.
+ left_count, right_count = max(1, int(2 * limit / 3)), max(1, int(limit / 3))
+
+ yield obj_repr[:left_count]
+ yield "..."
+ yield obj_repr[-right_count:]
+
+ def _convert_to_unicode_or_bytes_repr(self, obj_repr):
+ return obj_repr
+
+ def _bytes_as_unicode_if_possible(self, obj_repr):
+ # We try to decode with 3 possible encoding (sys.stdout.encoding,
+ # locale.getpreferredencoding() and 'utf-8). If no encoding can decode
+ # the input, we return the original bytes.
+ try_encodings = []
+ encoding = self.sys_stdout_encoding or getattr(sys.stdout, "encoding", None)
+ if encoding:
+ try_encodings.append(encoding.lower())
+
+ preferred_encoding = self.locale_preferred_encoding or locale.getpreferredencoding()
+ if preferred_encoding:
+ preferred_encoding = preferred_encoding.lower()
+ if preferred_encoding not in try_encodings:
+ try_encodings.append(preferred_encoding)
+
+ if "utf-8" not in try_encodings:
+ try_encodings.append("utf-8")
+
+ for encoding in try_encodings:
+ try:
+ return obj_repr.decode(encoding)
+ except UnicodeDecodeError: # noqa: PERF203
+ pass
+
+ return obj_repr # Return the original version (in bytes)
+
+
+class DisplayOptions:
+ def __init__(self, width, max_columns):
+ self.width = width
+ self.max_columns = max_columns
+
+
+_safe_repr = SafeRepr()
+_collection_types = ["list", "tuple", "set"]
+_array_page_size = 50
+
+
+def _get_value(variable):
+ return _safe_repr(variable)
+
+
+def _get_property_names(variable):
+ props = []
+ private_props = []
+ for prop in dir(variable):
+ if not prop.startswith("_"):
+ props.append(prop)
+ elif not prop.startswith("__"):
+ private_props.append(prop)
+ return props + private_props
+
+
+def _get_full_type(var_type):
+ module = ""
+ if hasattr(var_type, "__module__") and var_type.__module__ != "builtins":
+ module = var_type.__module__ + "."
+ if hasattr(var_type, "__qualname__"):
+ return module + var_type.__qualname__
+ elif hasattr(var_type, "__name__"):
+ return module + var_type.__name__
+ return None
+
+
+def _get_variable_description(variable):
+ result = {}
+
+ var_type = type(variable)
+ result["type"] = _get_full_type(var_type)
+ if hasattr(var_type, "__mro__"):
+ result["interfaces"] = [_get_full_type(t) for t in var_type.__mro__]
+
+ if hasattr(variable, "__len__") and result["type"] in _collection_types:
+ result["count"] = len(variable)
+
+ result["hasNamedChildren"] = hasattr(variable, "__dict__") or isinstance(variable, dict)
+
+ result["value"] = _get_value(variable)
+ return result
+
+
+def _get_child_property(root, property_chain):
+ try:
+ variable = root
+ for prop in property_chain:
+ if isinstance(prop, int):
+ if hasattr(variable, "__getitem__"):
+ variable = variable[prop]
+ elif isinstance(variable, set):
+ variable = list(variable)[prop]
+ else:
+ return None
+ elif hasattr(variable, prop):
+ variable = getattr(variable, prop)
+ elif isinstance(variable, dict) and prop in variable:
+ variable = variable[prop]
+ else:
+ return None
+ except Exception:
+ return None
+
+ return variable
+
+
+types_to_exclude = ["module", "function", "method", "class", "type"]
+
+
+### Get info on variables at the root level
+def getVariableDescriptions(): # noqa: N802
+ return [
+ {
+ "name": varName,
+ **_get_variable_description(globals()[varName]),
+ "root": varName,
+ "propertyChain": [],
+ "language": "python",
+ }
+ for varName in globals()
+ if type(globals()[varName]).__name__ not in types_to_exclude
+ and not varName.startswith("__")
+ ]
+
+
+### Get info on children of a variable reached through the given property chain
+def getAllChildrenDescriptions(root_var_name, property_chain, start_index): # noqa: N802
+ root = globals()[root_var_name]
+ if root is None:
+ return []
+
+ parent = root
+ if len(property_chain) > 0:
+ parent = _get_child_property(root, property_chain)
+
+ children = []
+ parent_info = _get_variable_description(parent)
+ if "count" in parent_info:
+ if parent_info["count"] > 0:
+ last_item = min(parent_info["count"], start_index + _array_page_size)
+ index_range = range(start_index, last_item)
+ children = [
+ {
+ **_get_variable_description(_get_child_property(parent, [i])),
+ "name": str(i),
+ "root": root_var_name,
+ "propertyChain": [*property_chain, i],
+ "language": "python",
+ }
+ for i in index_range
+ ]
+ elif parent_info["hasNamedChildren"]:
+ children_names = []
+ if hasattr(parent, "__dict__"):
+ children_names = _get_property_names(parent)
+ elif isinstance(parent, dict):
+ children_names = list(parent.keys())
+
+ children = []
+ for prop in children_names:
+ child_property = _get_child_property(parent, [prop])
+ if child_property is not None and type(child_property).__name__ not in types_to_exclude:
+ child = {
+ **_get_variable_description(child_property),
+ "name": prop,
+ "root": root_var_name,
+ "propertyChain": [*property_chain, prop],
+ }
+ children.append(child)
+
+ return children
diff --git a/pythonFiles/installed_check.py b/python_files/installed_check.py
similarity index 94%
rename from pythonFiles/installed_check.py
rename to python_files/installed_check.py
index 4a43a8bc8b30..4fa3cdbb2385 100644
--- a/pythonFiles/installed_check.py
+++ b/python_files/installed_check.py
@@ -11,9 +11,9 @@
LIB_ROOT = pathlib.Path(__file__).parent / "lib" / "python"
sys.path.insert(0, os.fspath(LIB_ROOT))
-import tomli
-from importlib_metadata import metadata
-from packaging.requirements import Requirement
+import tomli # noqa: E402
+from importlib_metadata import metadata # noqa: E402
+from packaging.requirements import Requirement # noqa: E402
DEFAULT_SEVERITY = "3" # 'Hint'
try:
@@ -36,9 +36,7 @@ def parse_args(argv: Optional[Sequence[str]] = None):
def parse_requirements(line: str) -> Optional[Requirement]:
try:
req = Requirement(line.strip("\\"))
- if req.marker is None:
- return req
- elif req.marker.evaluate():
+ if req.marker is None or req.marker.evaluate():
return req
except Exception:
pass
diff --git a/pythonFiles/interpreterInfo.py b/python_files/interpreterInfo.py
similarity index 100%
rename from pythonFiles/interpreterInfo.py
rename to python_files/interpreterInfo.py
diff --git a/python_files/jedilsp_requirements/requirements.in b/python_files/jedilsp_requirements/requirements.in
new file mode 100644
index 000000000000..794e9c8ea686
--- /dev/null
+++ b/python_files/jedilsp_requirements/requirements.in
@@ -0,0 +1,8 @@
+# This file is used to generate requirements.txt.
+# To update requirements.txt, run the following commands.
+# Use Python 3.9 when creating the environment or using pip-tools
+# 1) Install `uv` https://docs.astral.sh/uv/getting-started/installation/
+# 2) uv pip compile --generate-hashes --upgrade python_files\jedilsp_requirements\requirements.in -o python_files\jedilsp_requirements\requirements.txt
+
+jedi-language-server>=0.34.3
+pygls>=0.10.3
diff --git a/python_files/jedilsp_requirements/requirements.txt b/python_files/jedilsp_requirements/requirements.txt
new file mode 100644
index 000000000000..e2599e7bbce4
--- /dev/null
+++ b/python_files/jedilsp_requirements/requirements.txt
@@ -0,0 +1,63 @@
+# This file was autogenerated by uv via the following command:
+# uv pip compile --generate-hashes python_files\jedilsp_requirements\requirements.in -o .\python_files\jedilsp_requirements\requirements.txt
+attrs==25.3.0 \
+ --hash=sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3 \
+ --hash=sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b
+ # via
+ # cattrs
+ # lsprotocol
+cattrs==25.2.0 \
+ --hash=sha256:539d7eedee7d2f0706e4e109182ad096d608ba84633c32c75ef3458f1d11e8f1 \
+ --hash=sha256:f46c918e955db0177be6aa559068390f71988e877c603ae2e56c71827165cc06
+ # via
+ # jedi-language-server
+ # lsprotocol
+ # pygls
+docstring-to-markdown==0.17 \
+ --hash=sha256:df72a112294c7492487c9da2451cae0faeee06e86008245c188c5761c9590ca3 \
+ --hash=sha256:fd7d5094aa83943bf5f9e1a13701866b7c452eac19765380dead666e36d3711c
+ # via jedi-language-server
+exceptiongroup==1.3.0 \
+ --hash=sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10 \
+ --hash=sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88
+ # via cattrs
+importlib-metadata==8.7.0 \
+ --hash=sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000 \
+ --hash=sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd
+ # via docstring-to-markdown
+jedi==0.19.2 \
+ --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \
+ --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9
+ # via jedi-language-server
+jedi-language-server==0.45.1 \
+ --hash=sha256:8c0c6b4eaeffdbb87be79e9897c9929ffeddf875dff7c1c36dd67768e294942b \
+ --hash=sha256:a1fcfba8008f2640e921937fcf1933c3961d74249341eba8b3ef9a0c3f817102
+ # via -r python_files/jedilsp_requirements/requirements.in
+lsprotocol==2023.0.1 \
+ --hash=sha256:c75223c9e4af2f24272b14c6375787438279369236cd568f596d4951052a60f2 \
+ --hash=sha256:cc5c15130d2403c18b734304339e51242d3018a05c4f7d0f198ad6e0cd21861d
+ # via
+ # jedi-language-server
+ # pygls
+parso==0.8.5 \
+ --hash=sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a \
+ --hash=sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887
+ # via jedi
+pygls==1.3.1 \
+ --hash=sha256:140edceefa0da0e9b3c533547c892a42a7d2fd9217ae848c330c53d266a55018 \
+ --hash=sha256:6e00f11efc56321bdeb6eac04f6d86131f654c7d49124344a9ebb968da3dd91e
+ # via
+ # -r python_files/jedilsp_requirements/requirements.in
+ # jedi-language-server
+typing-extensions==4.15.0 \
+ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \
+ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548
+ # via
+ # cattrs
+ # docstring-to-markdown
+ # exceptiongroup
+ # jedi-language-server
+zipp==3.23.0 \
+ --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \
+ --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166
+ # via importlib-metadata
diff --git a/pythonFiles/linter.py b/python_files/linter.py
similarity index 89%
rename from pythonFiles/linter.py
rename to python_files/linter.py
index 58ad9397f58b..edbbe9dfafe5 100644
--- a/pythonFiles/linter.py
+++ b/python_files/linter.py
@@ -1,7 +1,6 @@
import subprocess
import sys
-
linter_settings = {
"pylint": {
"args": ["--reports=n", "--output-format=json"],
@@ -37,11 +36,7 @@ def main():
invoke = sys.argv[1]
if invoke == "-m":
linter = sys.argv[2]
- args = (
- [sys.executable, "-m", linter]
- + linter_settings[linter]["args"]
- + sys.argv[3:]
- )
+ args = [sys.executable, "-m", linter] + linter_settings[linter]["args"] + sys.argv[3:]
else:
linter = sys.argv[2]
args = [sys.argv[3]] + linter_settings[linter]["args"] + sys.argv[4:]
diff --git a/pythonFiles/normalizeSelection.py b/python_files/normalizeSelection.py
similarity index 84%
rename from pythonFiles/normalizeSelection.py
rename to python_files/normalizeSelection.py
index 7608ce8860f6..9d82a4dc9440 100644
--- a/pythonFiles/normalizeSelection.py
+++ b/python_files/normalizeSelection.py
@@ -8,6 +8,8 @@
import textwrap
from typing import Iterable
+attach_bracket_paste = sys.version_info >= (3, 13)
+
def split_lines(source):
"""
@@ -21,12 +23,11 @@ def split_lines(source):
def _get_statements(selection):
- """
- Process a multiline selection into a list of its top-level statements.
+ """Process a multiline selection into a list of its top-level statements.
+
This will remove empty newlines around and within the selection, dedent it,
and split it using the result of `ast.parse()`.
"""
-
# Remove blank lines within the selection to prevent the REPL from thinking the block is finished.
lines = (line for line in split_lines(selection) if line.strip() != "")
@@ -57,7 +58,7 @@ def _get_statements(selection):
# Also, not all AST objects can have decorators.
if hasattr(node, "decorator_list") and sys.version_info >= (3, 8):
# Using getattr instead of node.decorator_list or pyright will complain about an unknown member.
- line_end -= len(getattr(node, "decorator_list"))
+ line_end -= len(getattr(node, "decorator_list")) # noqa: B009
ends.append(line_end)
ends.append(len(lines))
@@ -74,7 +75,7 @@ def _get_statements(selection):
# Special handling of decorators similar to what's above.
if hasattr(node, "decorator_list") and sys.version_info >= (3, 8):
# Using getattr instead of node.decorator_list or pyright will complain about an unknown member.
- start -= len(getattr(node, "decorator_list"))
+ start -= len(getattr(node, "decorator_list")) # noqa: B009
block = "\n".join(lines[start:end])
# If the block is multiline, add an extra newline character at its end.
@@ -119,8 +120,12 @@ def normalize_lines(selection):
# Insert a newline between each top-level statement, and append a newline to the selection.
source = "\n".join(statements) + "\n"
+ # If selection ends with trailing dictionary or list, remove last unnecessary newline.
if selection[-2] == "}" or selection[-2] == "]":
source = source[:-1]
+ # If the selection contains trailing return dictionary, insert newline to trigger execute.
+ if check_end_with_return_dict(selection):
+ source = source + "\n"
except Exception:
# If there's a problem when parsing statements,
# append a blank line to end the block and send it as-is.
@@ -133,19 +138,22 @@ def normalize_lines(selection):
min_key = None
+def check_end_with_return_dict(code):
+ stripped_code = code.strip()
+ return stripped_code.endswith("}") and "return {" in stripped_code.strip()
+
+
def check_exact_exist(top_level_nodes, start_line, end_line):
- exact_nodes = []
- for node in top_level_nodes:
- if node.lineno == start_line and node.end_lineno == end_line:
- exact_nodes.append(node)
+ return [
+ node
+ for node in top_level_nodes
+ if node.lineno == start_line and node.end_lineno == end_line
+ ]
- return exact_nodes
+def traverse_file(whole_file_content, start_line, end_line, was_highlighted): # noqa: ARG001
+ """Intended to traverse through a user's given file content and find, collect all appropriate lines that should be sent to the REPL in case of smart selection.
-def traverse_file(wholeFileContent, start_line, end_line, was_highlighted):
- """
- Intended to traverse through a user's given file content and find, collect all appropriate lines
- that should be sent to the REPL in case of smart selection.
This could be exact statement such as just a single line print statement,
or a multiline dictionary, or differently styled multi-line list comprehension, etc.
Then call the normalize_lines function to normalize our smartly selected code block.
@@ -153,7 +161,7 @@ def traverse_file(wholeFileContent, start_line, end_line, was_highlighted):
parsed_file_content = None
try:
- parsed_file_content = ast.parse(wholeFileContent)
+ parsed_file_content = ast.parse(whole_file_content)
except Exception:
# Handle case where user is attempting to run code where file contains deprecated Python code.
# Let typescript side know and show warning message.
@@ -191,11 +199,8 @@ def traverse_file(wholeFileContent, start_line, end_line, was_highlighted):
ast.IfExp,
ast.ExceptHandler,
)
- if isinstance(node, ast_types_with_nodebody) and isinstance(
- node.body, Iterable
- ):
- for child_nodes in node.body:
- top_level_nodes.append(child_nodes)
+ if isinstance(node, ast_types_with_nodebody) and isinstance(node.body, Iterable):
+ top_level_nodes.extend(node.body)
exact_nodes = check_exact_exist(top_level_nodes, start_line, end_line)
@@ -204,9 +209,7 @@ def traverse_file(wholeFileContent, start_line, end_line, was_highlighted):
which_line_next = 0
for same_line_node in exact_nodes:
should_run_top_blocks.append(same_line_node)
- smart_code += (
- f"{ast.get_source_segment(wholeFileContent, same_line_node)}\n"
- )
+ smart_code += f"{ast.get_source_segment(whole_file_content, same_line_node)}\n"
which_line_next = get_next_block_lineno(should_run_top_blocks)
return {
"normalized_smart_result": smart_code,
@@ -220,7 +223,7 @@ def traverse_file(wholeFileContent, start_line, end_line, was_highlighted):
if start_line == top_node.lineno and end_line == top_node.end_lineno:
should_run_top_blocks.append(top_node)
- smart_code += f"{ast.get_source_segment(wholeFileContent, top_node)}\n"
+ smart_code += f"{ast.get_source_segment(whole_file_content, top_node)}\n"
break # If we found exact match, don't waste computation in parsing extra nodes.
elif start_line >= top_node.lineno and end_line <= top_node.end_lineno:
# Case to apply smart selection for multiple line.
@@ -235,7 +238,7 @@ def traverse_file(wholeFileContent, start_line, end_line, was_highlighted):
should_run_top_blocks.append(top_node)
- smart_code += str(ast.get_source_segment(wholeFileContent, top_node))
+ smart_code += str(ast.get_source_segment(whole_file_content, top_node))
smart_code += "\n"
normalized_smart_result = normalize_lines(smart_code)
@@ -266,7 +269,7 @@ def get_next_block_lineno(which_line_next):
raw = stdin.read()
contents = json.loads(raw.decode("utf-8"))
# Empty highlight means user has not explicitly selected specific text.
- empty_Highlight = contents.get("emptyHighlight", False)
+ empty_highlight = contents.get("emptyHighlight", False)
# We also get the activeEditor selection start line and end line from the typescript VS Code side.
# Remember to add 1 to each of the received since vscode starts line counting from 0 .
@@ -277,28 +280,30 @@ def get_next_block_lineno(which_line_next):
data = None
which_line_next = 0
- if (
- empty_Highlight
- and contents.get("smartSendExperimentEnabled")
- and contents.get("smartSendSettingsEnabled")
- ):
+ if empty_highlight and contents.get("smartSendSettingsEnabled"):
result = traverse_file(
contents["wholeFileContent"],
vscode_start_line,
vscode_end_line,
- not empty_Highlight,
+ not empty_highlight,
)
normalized = result["normalized_smart_result"]
which_line_next = result["which_line_next"]
if normalized == "deprecated":
- data = json.dumps({"normalized": normalized})
+ data = json.dumps(
+ {"normalized": normalized, "attach_bracket_paste": attach_bracket_paste}
+ )
else:
data = json.dumps(
- {"normalized": normalized, "nextBlockLineno": result["which_line_next"]}
+ {
+ "normalized": normalized,
+ "nextBlockLineno": result["which_line_next"],
+ "attach_bracket_paste": attach_bracket_paste,
+ }
)
else:
normalized = normalize_lines(contents["code"])
- data = json.dumps({"normalized": normalized})
+ data = json.dumps({"normalized": normalized, "attach_bracket_paste": attach_bracket_paste})
stdout = sys.stdout if sys.version_info < (3,) else sys.stdout.buffer
stdout.write(data.encode("utf-8"))
diff --git a/pythonFiles/printEnvVariables.py b/python_files/printEnvVariables.py
similarity index 100%
rename from pythonFiles/printEnvVariables.py
rename to python_files/printEnvVariables.py
index 353149f237de..bf2cfd80e666 100644
--- a/pythonFiles/printEnvVariables.py
+++ b/python_files/printEnvVariables.py
@@ -1,7 +1,7 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
-import os
import json
+import os
print(json.dumps(dict(os.environ)))
diff --git a/python_files/printEnvVariablesToFile.py b/python_files/printEnvVariablesToFile.py
new file mode 100644
index 000000000000..f6013a8c24cf
--- /dev/null
+++ b/python_files/printEnvVariablesToFile.py
@@ -0,0 +1,16 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import sys
+
+# Prevent overwriting itself, since sys.argv[0] is the path to this file
+if len(sys.argv) > 1:
+ # Last argument is the target file into which we'll write the env variables line by line.
+ output_file = sys.argv[-1]
+else:
+ raise ValueError("Missing output file argument")
+
+with open(output_file, "w") as outfile: # noqa: PTH123
+ for key, val in os.environ.items(): # noqa: FURB122
+ outfile.write(f"{key}={val}\n")
diff --git a/python_files/pyproject.toml b/python_files/pyproject.toml
new file mode 100644
index 000000000000..7fb5e18339cb
--- /dev/null
+++ b/python_files/pyproject.toml
@@ -0,0 +1,83 @@
+[tool.pyright]
+exclude = ['lib']
+extraPaths = ['lib/python', 'lib/jedilsp']
+ignore = [
+ # Ignore all pre-existing code with issues
+ 'get-pip.py',
+ 'tensorboard_launcher.py',
+ 'testlauncher.py',
+ 'visualstudio_py_testlauncher.py',
+ 'testing_tools/unittest_discovery.py',
+ 'testing_tools/adapter/util.py',
+ 'testing_tools/adapter/pytest/_discovery.py',
+ 'testing_tools/adapter/pytest/_pytest_item.py',
+ 'tests/testing_tools/adapter/.data',
+ 'tests/testing_tools/adapter/test___main__.py',
+ 'tests/testing_tools/adapter/test_discovery.py',
+ 'tests/testing_tools/adapter/test_functional.py',
+ 'tests/testing_tools/adapter/test_report.py',
+ 'tests/testing_tools/adapter/test_util.py',
+ 'tests/testing_tools/adapter/pytest/test_cli.py',
+ 'tests/testing_tools/adapter/pytest/test_discovery.py',
+]
+
+[tool.ruff]
+line-length = 100
+target-version = "py38"
+exclude = [
+ "**/.data",
+ "lib",
+]
+
+[tool.ruff.format]
+docstring-code-format = true
+
+[tool.ruff.lint]
+# Ruff's defaults are F and a subset of E.
+# https://docs.astral.sh/ruff/rules/#rules
+# Compatible w/ ruff formatter. https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
+# Up-to-date as of Ruff 0.5.0.
+select = [
+ "A", # flake8-builtins
+ "ARG", # flake8-unused-argument
+ "ASYNC", # flake8-async
+ "B", # flake8-bugbear
+ "C4", # flake8-comprehensions
+ "D2", "D400", "D403", "D419", # pydocstyle
+ "DJ", # flake8-django
+ "DTZ", # flake8-dasetimez
+ "E4", "E7", "E9", # pycodestyle (errors)
+ "EXE", # flake8-executable
+ "F", # Pyflakes
+ "FBT", # flake8-boolean-trap
+ "FLY", # flynt
+ "FURB", # refurb
+ "I", # isort
+ "INP", # flake8-no-pep420
+ "INT", # flake8-gettext
+ "LOG", # flake8-logging
+ "N", # pep8-naming
+ "NPY", # NumPy-specific rules
+ "PD", # pandas-vet
+ "PERF", # Perflint
+ "PIE", # flake8-pie
+ "PTH", # flake8-pathlib
+ # flake8-pytest-style
+ "PT006", "PT007", "PT009", "PT012", "PT014", "PT015", "PT016", "PT017", "PT018", "PT019",
+ "PT020", "PT021", "PT022", "PT024", "PT025", "PT026", "PT027",
+ "PYI", # flake8-pyi
+ "Q", # flake8-quotes
+ "RET502", "RET503", "RET504", # flake8-return
+ "RSE", # flake8-raise
+ "RUF", # Ruff-specific rules
+ "SIM", # flake8-simplify
+ "SLF", # flake8-self
+ "SLOT", # flake8-slots
+ "TCH", # flake8-type-checking
+ "UP", # pyupgrade
+ "W", # pycodestyle (warnings)
+ "YTT", # flake8-2020
+]
+
+[tool.ruff.lint.pydocstyle]
+convention = "pep257"
diff --git a/python_files/python_server.py b/python_files/python_server.py
new file mode 100644
index 000000000000..e7ee92794a21
--- /dev/null
+++ b/python_files/python_server.py
@@ -0,0 +1,214 @@
+import ast
+import contextlib
+import io
+import json
+import sys
+import traceback
+import uuid
+from pathlib import Path
+from typing import Dict, List, Optional, Union
+
+STDIN = sys.stdin
+STDOUT = sys.stdout
+STDERR = sys.stderr
+USER_GLOBALS = {}
+
+
+def _send_message(msg: str):
+ # Content-Length is the data size in bytes.
+ length_msg = len(msg.encode())
+ STDOUT.buffer.write(f"Content-Length: {length_msg}\r\n\r\n{msg}".encode())
+ STDOUT.buffer.flush()
+
+
+def send_message(**kwargs):
+ _send_message(json.dumps({"jsonrpc": "2.0", **kwargs}))
+
+
+def print_log(msg: str):
+ send_message(method="log", params=msg)
+
+
+def send_response(
+ response: str,
+ response_id: int,
+ execution_status: bool = True, # noqa: FBT001, FBT002
+):
+ send_message(
+ id=response_id,
+ result={"status": execution_status, "output": response},
+ )
+
+
+def send_request(params: Optional[Union[List, Dict]] = None):
+ request_id = uuid.uuid4().hex
+ if params is None:
+ send_message(id=request_id, method="input")
+ else:
+ send_message(id=request_id, method="input", params=params)
+
+ return request_id
+
+
+original_input = input
+
+
+def custom_input(prompt=""):
+ try:
+ send_request({"prompt": prompt})
+ headers = get_headers()
+ # Content-Length is the data size in bytes.
+ content_length = int(headers.get("Content-Length", 0))
+
+ if content_length:
+ message_text = STDIN.buffer.read(content_length).decode()
+ message_json = json.loads(message_text)
+ return message_json["result"]["userInput"]
+ except EOFError:
+ # Input stream closed, exit gracefully
+ sys.exit(0)
+ except Exception:
+ print_log(traceback.format_exc())
+
+
+# Set input to our custom input
+USER_GLOBALS["input"] = custom_input
+input = custom_input # noqa: A001
+
+
+def handle_response(request_id):
+ while True:
+ try:
+ headers = get_headers()
+ # Content-Length is the data size in bytes.
+ content_length = int(headers.get("Content-Length", 0))
+
+ if content_length:
+ message_text = STDIN.buffer.read(content_length).decode()
+ message_json = json.loads(message_text)
+ our_user_input = message_json["result"]["userInput"]
+ if message_json["id"] == request_id:
+ send_response(our_user_input, message_json["id"])
+ elif message_json["method"] == "exit":
+ sys.exit(0)
+ except EOFError: # noqa: PERF203
+ # Input stream closed, exit gracefully
+ sys.exit(0)
+ except Exception:
+ print_log(traceback.format_exc())
+
+
+def exec_function(user_input):
+ try:
+ compile(user_input, "", "eval")
+ except SyntaxError:
+ return exec
+ return eval
+
+
+def check_valid_command(request):
+ try:
+ user_input = request["params"]
+ ast.parse(user_input[0])
+ send_response("True", request["id"])
+ except SyntaxError:
+ send_response("False", request["id"])
+
+
+def execute(request, user_globals):
+ str_output = CustomIO("", encoding="utf-8")
+ str_error = CustomIO("", encoding="utf-8")
+ str_input = CustomIO("", encoding="utf-8", newline="\n")
+
+ with contextlib.redirect_stdout(str_output), contextlib.redirect_stderr(str_error):
+ original_stdin = sys.stdin
+ try:
+ sys.stdin = str_input
+ execution_status = exec_user_input(request["params"], user_globals)
+ finally:
+ sys.stdin = original_stdin
+
+ send_response(str_output.get_value(), request["id"], execution_status)
+
+
+def exec_user_input(user_input, user_globals) -> bool:
+ user_input = user_input[0] if isinstance(user_input, list) else user_input
+
+ try:
+ callable_ = exec_function(user_input)
+ retval = callable_(user_input, user_globals)
+ if retval is not None:
+ print(retval)
+ return True
+ except KeyboardInterrupt:
+ print(traceback.format_exc())
+ return False
+ except Exception:
+ print(traceback.format_exc())
+ return False
+
+
+class CustomIO(io.TextIOWrapper):
+ """Custom stream object to replace stdio."""
+
+ def __init__(self, name, encoding="utf-8", newline=None):
+ self._buffer = io.BytesIO()
+ self._custom_name = name
+ super().__init__(self._buffer, encoding=encoding, newline=newline)
+
+ def close(self):
+ """Provide this close method which is used by some tools."""
+ # This is intentionally empty.
+
+ def get_value(self) -> str:
+ """Returns value from the buffer as string."""
+ self.seek(0)
+ return self.read()
+
+
+def get_headers():
+ headers = {}
+ while True:
+ raw = STDIN.buffer.readline()
+ # Detect EOF: readline() returns empty bytes when input stream is closed
+ if raw == b"":
+ raise EOFError("EOF reached while reading headers")
+ line = raw.decode().strip()
+ if not line:
+ break
+ name, value = line.split(":", 1)
+ headers[name] = value.strip()
+ return headers
+
+
+if __name__ == "__main__":
+ # https://docs.python.org/3/tutorial/modules.html#the-module-search-path
+ # The directory containing the input script (or the current directory when no file is specified).
+ # Here we emulate the same behavior like no file is specified.
+ input_script_dir = Path(__file__).parent
+ script_dir_str = str(input_script_dir)
+ if script_dir_str in sys.path:
+ sys.path.remove(script_dir_str)
+ while "" in sys.path:
+ sys.path.remove("")
+ sys.path.insert(0, "")
+ while True:
+ try:
+ headers = get_headers()
+ # Content-Length is the data size in bytes.
+ content_length = int(headers.get("Content-Length", 0))
+
+ if content_length:
+ request_text = STDIN.buffer.read(content_length).decode()
+ request_json = json.loads(request_text)
+ if request_json["method"] == "execute":
+ execute(request_json, USER_GLOBALS)
+ if request_json["method"] == "check_valid_command":
+ check_valid_command(request_json)
+ elif request_json["method"] == "exit":
+ sys.exit(0)
+ except EOFError: # noqa: PERF203
+ # Input stream closed (VS Code terminated), exit gracefully
+ sys.exit(0)
+ except Exception:
+ print_log(traceback.format_exc())
diff --git a/pythonFiles/pythonrc.py b/python_files/pythonrc.py
similarity index 71%
rename from pythonFiles/pythonrc.py
rename to python_files/pythonrc.py
index 1cb72b0ec344..3042ffb7a309 100644
--- a/pythonFiles/pythonrc.py
+++ b/python_files/pythonrc.py
@@ -1,12 +1,14 @@
+import platform
import sys
if sys.platform != "win32":
import readline
original_ps1 = ">>> "
+is_wsl = "microsoft-standard-WSL" in platform.release()
-class repl_hooks:
+class REPLHooks:
def __init__(self):
self.global_exit = None
self.failure_flag = False
@@ -21,11 +23,11 @@ def my_displayhook(self, value):
self.original_displayhook(value)
- def my_excepthook(self, type, value, traceback):
+ def my_excepthook(self, type_, value, traceback):
self.global_exit = value
self.failure_flag = True
- self.original_excepthook(type, value, traceback)
+ self.original_excepthook(type_, value, traceback)
def get_last_command():
@@ -37,30 +39,28 @@ def get_last_command():
return last_command
-class ps1:
- hooks = repl_hooks()
+class PS1:
+ hooks = REPLHooks()
sys.excepthook = hooks.my_excepthook
sys.displayhook = hooks.my_displayhook
# str will get called for every prompt with exit code to show success/failure
def __str__(self):
- exit_code = 0
- if self.hooks.failure_flag:
- exit_code = 1
- else:
- exit_code = 0
-
+ exit_code = int(bool(self.hooks.failure_flag))
+ self.hooks.failure_flag = False
# Guide following official VS Code doc for shell integration sequence:
result = ""
# For non-windows allow recent_command history.
if sys.platform != "win32":
- result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}{command_line}".format(
+ result = "{soh}{command_executed}{command_line}{command_finished}{prompt_started}{stx}{prompt}{soh}{command_start}{stx}".format(
+ soh="\001",
+ stx="\002",
+ command_executed="\x1b]633;C\x07",
+ command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
command_finished="\x1b]633;D;" + str(exit_code) + "\x07",
prompt_started="\x1b]633;A\x07",
prompt=original_ps1,
command_start="\x1b]633;B\x07",
- command_executed="\x1b]633;C\x07",
- command_line="\x1b]633;E;" + str(get_last_command()) + "\x07",
)
else:
result = "{command_finished}{prompt_started}{prompt}{command_start}{command_executed}".format(
@@ -75,6 +75,14 @@ def __str__(self):
return result
+ def __repr__(self):
+ return ""
-if sys.platform != "win32":
- sys.ps1 = ps1()
+
+if sys.platform != "win32" and (not is_wsl):
+ sys.ps1 = PS1()
+
+if sys.platform == "darwin":
+ print("Cmd click to launch VS Code Native REPL")
+else:
+ print("Ctrl click to launch VS Code Native REPL")
diff --git a/python_files/run-jedi-language-server.py b/python_files/run-jedi-language-server.py
new file mode 100644
index 000000000000..47bf503d596c
--- /dev/null
+++ b/python_files/run-jedi-language-server.py
@@ -0,0 +1,14 @@
+import os
+import pathlib
+import sys
+
+# Add the lib path to our sys path so jedi_language_server can find its references
+extension_dir = pathlib.Path(__file__).parent.parent
+EXTENSION_ROOT = os.fsdecode(extension_dir)
+sys.path.insert(0, os.fsdecode(extension_dir / "python_files" / "lib" / "jedilsp"))
+del extension_dir
+
+
+from jedi_language_server.cli import cli # noqa: E402
+
+sys.exit(cli())
diff --git a/pythonFiles/shell_exec.py b/python_files/shell_exec.py
similarity index 87%
rename from pythonFiles/shell_exec.py
rename to python_files/shell_exec.py
index 4987399a53ea..62b6b28af6cd 100644
--- a/pythonFiles/shell_exec.py
+++ b/python_files/shell_exec.py
@@ -16,7 +16,7 @@
print("Executing command in shell >> " + " ".join(shell_args))
-with open(lock_file, "w") as fp:
+with open(lock_file, "w") as fp: # noqa: PTH123
try:
# Signal start of execution.
fp.write("START\n")
@@ -36,7 +36,7 @@
fp.flush()
try:
# ALso log the error for use from the other side.
- with open(lock_file + ".error", "w") as fpError:
- fpError.write(traceback.format_exc())
+ with open(lock_file + ".error", "w") as fp_error: # noqa: PTH123
+ fp_error.write(traceback.format_exc())
except Exception:
pass
diff --git a/pythonFiles/tensorboard_launcher.py b/python_files/tensorboard_launcher.py
similarity index 78%
rename from pythonFiles/tensorboard_launcher.py
rename to python_files/tensorboard_launcher.py
index bad1ef09fc6e..a04d51e7eb74 100644
--- a/pythonFiles/tensorboard_launcher.py
+++ b/python_files/tensorboard_launcher.py
@@ -1,7 +1,9 @@
-import time
-import sys
-import os
+import contextlib
import mimetypes
+import os
+import sys
+import time
+
from tensorboard import program
@@ -17,14 +19,12 @@ def main(logdir):
tb = program.TensorBoard()
tb.configure(bind_all=False, logdir=logdir)
url = tb.launch()
- sys.stdout.write("TensorBoard started at %s\n" % (url))
+ sys.stdout.write(f"TensorBoard started at {url}\n")
sys.stdout.flush()
- while True:
- try:
+ with contextlib.suppress(KeyboardInterrupt):
+ while True:
time.sleep(60)
- except KeyboardInterrupt:
- break
sys.stdout.write("TensorBoard is shutting down")
sys.stdout.flush()
@@ -32,5 +32,5 @@ def main(logdir):
if __name__ == "__main__":
if len(sys.argv) == 2:
logdir = str(sys.argv[1])
- sys.stdout.write("Starting TensorBoard with logdir %s" % (logdir))
+ sys.stdout.write(f"Starting TensorBoard with logdir {logdir}")
main(logdir)
diff --git a/pythonFiles/testing_tools/__init__.py b/python_files/testing_tools/__init__.py
similarity index 100%
rename from pythonFiles/testing_tools/__init__.py
rename to python_files/testing_tools/__init__.py
diff --git a/python_files/testing_tools/socket_manager.py b/python_files/testing_tools/socket_manager.py
new file mode 100644
index 000000000000..f143ac111cdb
--- /dev/null
+++ b/python_files/testing_tools/socket_manager.py
@@ -0,0 +1,95 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import contextlib
+import socket
+import sys
+
+# set the socket before it gets blocked or overwritten by a user tests
+_SOCKET = socket.socket
+
+
+class PipeManager:
+ def __init__(self, name):
+ self.name = name
+
+ def __enter__(self):
+ return self.connect()
+
+ def __exit__(self, *_):
+ self.close()
+
+ def connect(self):
+ self._writer = open(self.name, "w", encoding="utf-8") # noqa: SIM115, PTH123
+ # reader created in read method
+ return self
+
+ def close(self):
+ self._writer.close()
+ if hasattr(self, "_reader"):
+ self._reader.close()
+
+ def write(self, data: str):
+ try:
+ # for windows, is should only use \n\n
+ request = f"""content-length: {len(data)}\ncontent-type: application/json\n\n{data}"""
+ self._writer.write(request)
+ self._writer.flush()
+ except Exception as e:
+ print("error attempting to write to pipe", e)
+ raise (e)
+
+ def read(self, bufsize=1024) -> str:
+ """Read data from the socket.
+
+ Args:
+ bufsize (int): Number of bytes to read from the socket.
+
+ Returns:
+ data (str): Data received from the socket.
+ """
+ # returns a string automatically from read
+ if not hasattr(self, "_reader"):
+ self._reader = open(self.name, encoding="utf-8") # noqa: SIM115, PTH123
+ return self._reader.read(bufsize)
+
+
+class SocketManager:
+ """Create a socket and connect to the given address.
+
+ The address is a (host: str, port: int) tuple.
+ Example usage:
+
+ ```
+ with SocketManager(("localhost", 6767)) as sock:
+ request = json.dumps(payload)
+ result = s.socket.sendall(request.encode("utf-8"))
+ ```
+ """
+
+ def __init__(self, addr):
+ self.addr = addr
+ self.socket = None
+
+ def __enter__(self):
+ return self.connect()
+
+ def __exit__(self, *_):
+ self.close()
+
+ def connect(self):
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
+ if sys.platform == "win32":
+ addr_use = socket.SO_EXCLUSIVEADDRUSE
+ else:
+ addr_use = socket.SO_REUSEADDR
+ self.socket.setsockopt(socket.SOL_SOCKET, addr_use, 1)
+ self.socket.connect(self.addr)
+
+ return self
+
+ def close(self):
+ if self.socket:
+ with contextlib.suppress(Exception):
+ self.socket.shutdown(socket.SHUT_RDWR)
+ self.socket.close()
diff --git a/pythonFiles/testlauncher.py b/python_files/testlauncher.py
similarity index 71%
rename from pythonFiles/testlauncher.py
rename to python_files/testlauncher.py
index 3278815b380c..2309a203363b 100644
--- a/pythonFiles/testlauncher.py
+++ b/python_files/testlauncher.py
@@ -7,30 +7,31 @@
def parse_argv():
"""Parses arguments for use with the test launcher.
+
Arguments are:
1. Working directory.
2. Test runner `pytest`
3. Rest of the arguments are passed into the test runner.
"""
cwd = sys.argv[1]
- testRunner = sys.argv[2]
+ test_runner = sys.argv[2]
args = sys.argv[3:]
- return (cwd, testRunner, args)
+ return (cwd, test_runner, args)
+
+def run(cwd, test_runner, args):
+ """Runs the test.
-def run(cwd, testRunner, args):
- """Runs the test
cwd -- the current directory to be set
testRunner -- test runner to be used `pytest`
args -- arguments passed into the test runner
"""
-
- sys.path[0] = os.getcwd()
+ sys.path[0] = os.getcwd() # noqa: PTH109
os.chdir(cwd)
try:
- if testRunner == "pytest":
+ if test_runner == "pytest":
import pytest
pytest.main(args)
@@ -40,5 +41,5 @@ def run(cwd, testRunner, args):
if __name__ == "__main__":
- cwd, testRunner, args = parse_argv()
- run(cwd, testRunner, args)
+ cwd, test_runner, args = parse_argv()
+ run(cwd, test_runner, args)
diff --git a/pythonFiles/tests/__init__.py b/python_files/tests/__init__.py
similarity index 93%
rename from pythonFiles/tests/__init__.py
rename to python_files/tests/__init__.py
index 4f762cd1f81a..86bc29ff33e8 100644
--- a/pythonFiles/tests/__init__.py
+++ b/python_files/tests/__init__.py
@@ -1,5 +1,6 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
+# ruff:noqa: PTH118, PTH120
import os.path
TEST_ROOT = os.path.dirname(__file__)
diff --git a/pythonFiles/tests/__main__.py b/python_files/tests/__main__.py
similarity index 86%
rename from pythonFiles/tests/__main__.py
rename to python_files/tests/__main__.py
index 901385d41d87..2595fce358e4 100644
--- a/pythonFiles/tests/__main__.py
+++ b/python_files/tests/__main__.py
@@ -12,9 +12,7 @@
def parse_args():
parser = argparse.ArgumentParser()
# To mark a test as functional: (decorator) @pytest.mark.functional
- parser.add_argument(
- "--functional", dest="markers", action="append_const", const="functional"
- )
+ parser.add_argument("--functional", dest="markers", action="append_const", const="functional")
parser.add_argument(
"--no-functional", dest="markers", action="append_const", const="not functional"
)
@@ -36,7 +34,7 @@ def parse_args():
return ns, remainder
-def main(pytestargs, markers=None, specific=False):
+def main(pytestargs, markers=None, specific=False): # noqa: FBT002
sys.path.insert(1, TESTING_TOOLS_ROOT)
sys.path.insert(1, DEBUG_ADAPTER_ROOT)
@@ -48,8 +46,7 @@ def main(pytestargs, markers=None, specific=False):
pytestargs.insert(0, marker)
pytestargs.insert(0, "-m")
- ec = pytest.main(pytestargs)
- return ec
+ return pytest.main(pytestargs)
if __name__ == "__main__":
diff --git a/python_files/tests/pytestadapter/.data/2496-black-formatter/app.py b/python_files/tests/pytestadapter/.data/2496-black-formatter/app.py
new file mode 100644
index 000000000000..3b474e9d911e
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/2496-black-formatter/app.py
@@ -0,0 +1,6 @@
+def add(a, b):
+ return a + b
+
+
+def subtract(a, b):
+ return a - b
diff --git a/python_files/tests/pytestadapter/.data/2496-black-formatter/test_app.py b/python_files/tests/pytestadapter/.data/2496-black-formatter/test_app.py
new file mode 100644
index 000000000000..ef4398feb786
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/2496-black-formatter/test_app.py
@@ -0,0 +1,14 @@
+import pytest
+from app import add, subtract
+
+
+def test_add(): # test_marker--test_add
+ assert add(2, 3) == 5
+ assert add(-1, 1) == 0
+ assert add(0, 0) == 0
+
+
+def test_subtract(): # test_marker--test_subtract
+ assert subtract(5, 3) == 2
+ assert subtract(0, 0) == 0
+ assert subtract(-1, -1) == 0
diff --git a/python_files/tests/pytestadapter/.data/config_sub_folder/config/pytest.ini b/python_files/tests/pytestadapter/.data/config_sub_folder/config/pytest.ini
new file mode 100644
index 000000000000..dfac39a723e8
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/config_sub_folder/config/pytest.ini
@@ -0,0 +1,8 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+[pytest]
+python_files =
+ test_*.py
+testpaths =
+ tests
diff --git a/python_files/tests/pytestadapter/.data/config_sub_folder/tests/test_hello.py b/python_files/tests/pytestadapter/.data/config_sub_folder/tests/test_hello.py
new file mode 100644
index 000000000000..2fd5e2b0a309
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/config_sub_folder/tests/test_hello.py
@@ -0,0 +1,6 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+
+def test_hello(): # test_marker--test_hello
+ assert True
diff --git a/pythonFiles/testing_tools/adapter/__init__.py b/python_files/tests/pytestadapter/.data/coverage_gen/__init__.py
similarity index 100%
rename from pythonFiles/testing_tools/adapter/__init__.py
rename to python_files/tests/pytestadapter/.data/coverage_gen/__init__.py
diff --git a/python_files/tests/pytestadapter/.data/coverage_gen/reverse.py b/python_files/tests/pytestadapter/.data/coverage_gen/reverse.py
new file mode 100644
index 000000000000..cb6755a3a369
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/coverage_gen/reverse.py
@@ -0,0 +1,19 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+def reverse_string(s):
+ if s is None or s == "":
+ return "Error: Input is None"
+ return s[::-1]
+
+def reverse_sentence(sentence):
+ if sentence is None or sentence == "":
+ return "Error: Input is None"
+ words = sentence.split()
+ reversed_words = [reverse_string(word) for word in words]
+ return " ".join(reversed_words)
+
+# Example usage
+if __name__ == "__main__":
+ sample_string = "hello"
+ print(reverse_string(sample_string)) # Output: "olleh"
diff --git a/python_files/tests/pytestadapter/.data/coverage_gen/test_reverse.py b/python_files/tests/pytestadapter/.data/coverage_gen/test_reverse.py
new file mode 100644
index 000000000000..e7319f143608
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/coverage_gen/test_reverse.py
@@ -0,0 +1,28 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+from .reverse import reverse_sentence, reverse_string
+
+
+def test_reverse_sentence():
+ """
+ Tests the reverse_sentence function to ensure it correctly reverses each word in a sentence.
+
+ Test cases:
+ - "hello world" should be reversed to "olleh dlrow"
+ - "Python is fun" should be reversed to "nohtyP si nuf"
+ - "a b c" should remain "a b c" as each character is a single word
+ """
+ assert reverse_sentence("hello world") == "olleh dlrow"
+ assert reverse_sentence("Python is fun") == "nohtyP si nuf"
+ assert reverse_sentence("a b c") == "a b c"
+
+def test_reverse_sentence_error():
+ assert reverse_sentence("") == "Error: Input is None"
+ assert reverse_sentence(None) == "Error: Input is None"
+
+
+def test_reverse_string():
+ assert reverse_string("hello") == "olleh"
+ assert reverse_string("Python") == "nohtyP"
+ # this test specifically does not cover the error cases
diff --git a/python_files/tests/pytestadapter/.data/coverage_w_config/pyproject.toml b/python_files/tests/pytestadapter/.data/coverage_w_config/pyproject.toml
new file mode 100644
index 000000000000..c3406cc68929
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/coverage_w_config/pyproject.toml
@@ -0,0 +1,5 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+[tool.coverage.report]
+omit = ["test_ignore.py", "tests/*.py"]
diff --git a/python_files/tests/pytestadapter/.data/coverage_w_config/test_ignore.py b/python_files/tests/pytestadapter/.data/coverage_w_config/test_ignore.py
new file mode 100644
index 000000000000..98640e336ab4
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/coverage_w_config/test_ignore.py
@@ -0,0 +1,5 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+def test_to_ignore():
+ assert True
diff --git a/python_files/tests/pytestadapter/.data/coverage_w_config/test_ran.py b/python_files/tests/pytestadapter/.data/coverage_w_config/test_ran.py
new file mode 100644
index 000000000000..864acec79ba2
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/coverage_w_config/test_ran.py
@@ -0,0 +1,9 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+def test_simple():
+ assert True
+
+
+def untouched_function():
+ return 1
diff --git a/python_files/tests/pytestadapter/.data/coverage_w_config/tests/test_disregard.py b/python_files/tests/pytestadapter/.data/coverage_w_config/tests/test_disregard.py
new file mode 100644
index 000000000000..110a11534171
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/coverage_w_config/tests/test_disregard.py
@@ -0,0 +1,5 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+def test_i_hope_this_is_ignored():
+ assert True
diff --git a/pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py b/python_files/tests/pytestadapter/.data/dual_level_nested_folder/nested_folder_one/test_bottom_folder.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py
rename to python_files/tests/pytestadapter/.data/dual_level_nested_folder/nested_folder_one/test_bottom_folder.py
diff --git a/pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py b/python_files/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py
rename to python_files/tests/pytestadapter/.data/dual_level_nested_folder/test_top_folder.py
diff --git a/pythonFiles/tests/pytestadapter/.data/empty_discovery.py b/python_files/tests/pytestadapter/.data/empty_discovery.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/empty_discovery.py
rename to python_files/tests/pytestadapter/.data/empty_discovery.py
diff --git a/pythonFiles/tests/pytestadapter/.data/error_parametrize_discovery.py b/python_files/tests/pytestadapter/.data/error_parametrize_discovery.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/error_parametrize_discovery.py
rename to python_files/tests/pytestadapter/.data/error_parametrize_discovery.py
diff --git a/pythonFiles/tests/pytestadapter/.data/error_pytest_import.txt b/python_files/tests/pytestadapter/.data/error_pytest_import.txt
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/error_pytest_import.txt
rename to python_files/tests/pytestadapter/.data/error_pytest_import.txt
diff --git a/pythonFiles/tests/pytestadapter/.data/error_raise_exception.py b/python_files/tests/pytestadapter/.data/error_raise_exception.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/error_raise_exception.py
rename to python_files/tests/pytestadapter/.data/error_raise_exception.py
diff --git a/pythonFiles/tests/pytestadapter/.data/error_syntax_discovery.txt b/python_files/tests/pytestadapter/.data/error_syntax_discovery.txt
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/error_syntax_discovery.txt
rename to python_files/tests/pytestadapter/.data/error_syntax_discovery.txt
diff --git a/pythonFiles/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py b/python_files/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py
rename to python_files/tests/pytestadapter/.data/folder_a/folder_b/folder_a/test_nest.py
diff --git a/python_files/tests/pytestadapter/.data/folder_with_script/script_random.py b/python_files/tests/pytestadapter/.data/folder_with_script/script_random.py
new file mode 100644
index 000000000000..d8c32027a9e6
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/folder_with_script/script_random.py
@@ -0,0 +1,7 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+# This file has no test, it's just a random script.
+
+if __name__ == "__main__":
+ print("Hello World!")
diff --git a/pythonFiles/tests/pytestadapter/.data/simple_pytest.py b/python_files/tests/pytestadapter/.data/folder_with_script/test_simple.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/simple_pytest.py
rename to python_files/tests/pytestadapter/.data/folder_with_script/test_simple.py
diff --git a/pythonFiles/tests/pytestadapter/.data/param_same_name/test_param1.py b/python_files/tests/pytestadapter/.data/param_same_name/test_param1.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/param_same_name/test_param1.py
rename to python_files/tests/pytestadapter/.data/param_same_name/test_param1.py
diff --git a/pythonFiles/tests/pytestadapter/.data/param_same_name/test_param2.py b/python_files/tests/pytestadapter/.data/param_same_name/test_param2.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/param_same_name/test_param2.py
rename to python_files/tests/pytestadapter/.data/param_same_name/test_param2.py
diff --git a/pythonFiles/tests/pytestadapter/.data/parametrize_tests.py b/python_files/tests/pytestadapter/.data/parametrize_tests.py
similarity index 50%
rename from pythonFiles/tests/pytestadapter/.data/parametrize_tests.py
rename to python_files/tests/pytestadapter/.data/parametrize_tests.py
index c4dbadc32d6e..34d3c4201f0f 100644
--- a/pythonFiles/tests/pytestadapter/.data/parametrize_tests.py
+++ b/python_files/tests/pytestadapter/.data/parametrize_tests.py
@@ -4,13 +4,14 @@
import pytest
-# Testing pytest with parametrized tests. The first two pass, the third fails.
-# The tests ids are parametrize_tests.py::test_adding[3+5-8] and so on.
-@pytest.mark.parametrize( # test_marker--test_adding
- "actual, expected", [("3+5", 8), ("2+4", 6), ("6+9", 16)]
-)
-def test_adding(actual, expected):
- assert eval(actual) == expected
+class TestClass:
+ # Testing pytest with parametrized tests. The first two pass, the third fails.
+ # The tests ids are parametrize_tests.py::test_adding[3+5-8] and so on.
+ @pytest.mark.parametrize( # test_marker--test_adding
+ "actual, expected", [("3+5", 8), ("2+4", 6), ("6+9", 16)]
+ )
+ def test_adding(self, actual, expected):
+ assert eval(actual) == expected
# Testing pytest with parametrized tests. All three pass.
diff --git a/python_files/tests/pytestadapter/.data/pytest.ini b/python_files/tests/pytestadapter/.data/pytest.ini
new file mode 100644
index 000000000000..ddbcd6544e5d
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/pytest.ini
@@ -0,0 +1,5 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+# pytest.ini is specified here so the root directory of the tests is kept at .data instead of referencing
+# the parent python_files/pyproject.toml for test_discovery.py and test_execution.py for pytest-adapter tests.
diff --git a/python_files/tests/pytestadapter/.data/pytest_describe_plugin/describe_only.py b/python_files/tests/pytestadapter/.data/pytest_describe_plugin/describe_only.py
new file mode 100644
index 000000000000..0702c032684b
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/pytest_describe_plugin/describe_only.py
@@ -0,0 +1,9 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+def describe_A():
+ def test_1(): # test_marker--test_1
+ pass
+
+ def test_2(): # test_marker--test_2
+ pass
diff --git a/python_files/tests/pytestadapter/.data/pytest_describe_plugin/nested_describe.py b/python_files/tests/pytestadapter/.data/pytest_describe_plugin/nested_describe.py
new file mode 100644
index 000000000000..5b9c13cc8d53
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/pytest_describe_plugin/nested_describe.py
@@ -0,0 +1,31 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import pytest
+
+
+def describe_list():
+ @pytest.fixture
+ def list():
+ return []
+
+ def describe_append():
+ def add_empty(list): # test_marker--add_empty
+ list.append("foo")
+ list.append("bar")
+ assert list == ["foo", "bar"]
+
+ def remove_empty(list): # test_marker--remove_empty
+ try:
+ list.remove("foo")
+ except ValueError:
+ pass
+
+ def describe_remove():
+ @pytest.fixture
+ def list():
+ return ["foo", "bar"]
+
+ def removes(list): # test_marker--removes
+ list.remove("foo")
+ assert list == ["bar"]
diff --git a/pythonFiles/tests/pytestadapter/.data/root/tests/pytest.ini b/python_files/tests/pytestadapter/.data/root/tests/pytest.ini
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/root/tests/pytest.ini
rename to python_files/tests/pytestadapter/.data/root/tests/pytest.ini
diff --git a/pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py b/python_files/tests/pytestadapter/.data/root/tests/test_a.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/root/tests/test_a.py
rename to python_files/tests/pytestadapter/.data/root/tests/test_a.py
diff --git a/pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py b/python_files/tests/pytestadapter/.data/root/tests/test_b.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/root/tests/test_b.py
rename to python_files/tests/pytestadapter/.data/root/tests/test_b.py
diff --git a/python_files/tests/pytestadapter/.data/same_function_new_class_param.py b/python_files/tests/pytestadapter/.data/same_function_new_class_param.py
new file mode 100644
index 000000000000..6f85051436b8
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/same_function_new_class_param.py
@@ -0,0 +1,25 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import pytest
+
+
+class TestNotEmpty:
+ @pytest.mark.parametrize("a, b", [(1, 1), (2, 2)]) # test_marker--TestNotEmpty::test_integer
+ def test_integer(self, a, b):
+ assert a == b
+
+ @pytest.mark.parametrize( # test_marker--TestNotEmpty::test_string
+ "a, b", [("a", "a"), ("b", "b")]
+ )
+ def test_string(self, a, b):
+ assert a == b
+
+
+class TestEmpty:
+ @pytest.mark.parametrize("a, b", [(0, 0)]) # test_marker--TestEmpty::test_integer
+ def test_integer(self, a, b):
+ assert a == b
+
+ @pytest.mark.parametrize("a, b", [("", "")]) # test_marker--TestEmpty::test_string
+ def test_string(self, a, b):
+ assert a == b
diff --git a/python_files/tests/pytestadapter/.data/simple_pytest.py b/python_files/tests/pytestadapter/.data/simple_pytest.py
new file mode 100644
index 000000000000..9f9bfb014f3d
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/simple_pytest.py
@@ -0,0 +1,7 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+
+# This test passes.
+def test_function(): # test_marker--test_function
+ assert 1 == 1
diff --git a/python_files/tests/pytestadapter/.data/skip_test_fixture.py b/python_files/tests/pytestadapter/.data/skip_test_fixture.py
new file mode 100644
index 000000000000..3d354cae86ea
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/skip_test_fixture.py
@@ -0,0 +1,19 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import pytest
+
+
+@pytest.fixture
+def docker_client() -> object:
+ try:
+ # NOTE: Actually connect with the docker sdk
+ raise Exception("Docker client not available")
+ except Exception:
+ pytest.skip("Docker client not available")
+
+ return object()
+
+
+def test_docker_client(docker_client):
+ assert False
diff --git a/pythonFiles/tests/pytestadapter/.data/skip_tests.py b/python_files/tests/pytestadapter/.data/skip_tests.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/skip_tests.py
rename to python_files/tests/pytestadapter/.data/skip_tests.py
diff --git a/pythonFiles/tests/pytestadapter/.data/test_env_vars.py b/python_files/tests/pytestadapter/.data/test_env_vars.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/test_env_vars.py
rename to python_files/tests/pytestadapter/.data/test_env_vars.py
diff --git a/pythonFiles/tests/pytestadapter/.data/test_logging.py b/python_files/tests/pytestadapter/.data/test_logging.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/test_logging.py
rename to python_files/tests/pytestadapter/.data/test_logging.py
diff --git a/pythonFiles/tests/pytestadapter/.data/test_multi_class_nest.py b/python_files/tests/pytestadapter/.data/test_multi_class_nest.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/test_multi_class_nest.py
rename to python_files/tests/pytestadapter/.data/test_multi_class_nest.py
diff --git a/python_files/tests/pytestadapter/.data/test_param_span_class.py b/python_files/tests/pytestadapter/.data/test_param_span_class.py
new file mode 100644
index 000000000000..a024c438bbf9
--- /dev/null
+++ b/python_files/tests/pytestadapter/.data/test_param_span_class.py
@@ -0,0 +1,16 @@
+import pytest
+
+
+@pytest.fixture(scope="function", params=[1, 2])
+def setup(request):
+ return request.param
+
+
+class TestClass1:
+ def test_method1(self, setup): # test_marker--TestClass1::test_method1
+ assert 1 == 1
+
+
+class TestClass2:
+ def test_method1(self, setup): # test_marker--TestClass2::test_method1
+ assert 2 == 2
diff --git a/pythonFiles/tests/pytestadapter/.data/text_docstring.txt b/python_files/tests/pytestadapter/.data/text_docstring.txt
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/text_docstring.txt
rename to python_files/tests/pytestadapter/.data/text_docstring.txt
diff --git a/pythonFiles/tests/pytestadapter/.data/unittest_folder/test_add.py b/python_files/tests/pytestadapter/.data/unittest_folder/test_add.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/unittest_folder/test_add.py
rename to python_files/tests/pytestadapter/.data/unittest_folder/test_add.py
diff --git a/pythonFiles/tests/pytestadapter/.data/unittest_folder/test_subtract.py b/python_files/tests/pytestadapter/.data/unittest_folder/test_subtract.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/unittest_folder/test_subtract.py
rename to python_files/tests/pytestadapter/.data/unittest_folder/test_subtract.py
diff --git a/pythonFiles/tests/pytestadapter/.data/unittest_pytest_same_file.py b/python_files/tests/pytestadapter/.data/unittest_pytest_same_file.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/unittest_pytest_same_file.py
rename to python_files/tests/pytestadapter/.data/unittest_pytest_same_file.py
diff --git a/pythonFiles/tests/pytestadapter/.data/unittest_skiptest_file_level.py b/python_files/tests/pytestadapter/.data/unittest_skiptest_file_level.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/.data/unittest_skiptest_file_level.py
rename to python_files/tests/pytestadapter/.data/unittest_skiptest_file_level.py
diff --git a/pythonFiles/tests/debug_adapter/__init__.py b/python_files/tests/pytestadapter/__init__.py
similarity index 100%
rename from pythonFiles/tests/debug_adapter/__init__.py
rename to python_files/tests/pytestadapter/__init__.py
diff --git a/python_files/tests/pytestadapter/expected_discovery_test_output.py b/python_files/tests/pytestadapter/expected_discovery_test_output.py
new file mode 100644
index 000000000000..047f1c72ad17
--- /dev/null
+++ b/python_files/tests/pytestadapter/expected_discovery_test_output.py
@@ -0,0 +1,2083 @@
+import os
+
+from .helpers import (
+ TEST_DATA_PATH,
+ find_class_line_number,
+ find_test_line_number,
+ get_absolute_test_id,
+)
+
+# This file contains the expected output dictionaries for tests discovery and is used in test_discovery.py.
+
+# This is the expected output for the empty_discovery.py file.
+# βββ
+TEST_DATA_PATH_STR = os.fspath(TEST_DATA_PATH)
+empty_discovery_pytest_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the simple_pytest.py file.
+# βββ simple_pytest.py
+# βββ test_function
+simple_test_file_path = TEST_DATA_PATH / "simple_pytest.py"
+simple_discovery_pytest_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "simple_pytest.py",
+ "path": os.fspath(simple_test_file_path),
+ "type_": "file",
+ "id_": os.fspath(simple_test_file_path),
+ "children": [
+ {
+ "name": "test_function",
+ "path": os.fspath(simple_test_file_path),
+ "lineno": find_test_line_number(
+ "test_function",
+ simple_test_file_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "simple_pytest.py::test_function", simple_test_file_path
+ ),
+ "runID": get_absolute_test_id(
+ "simple_pytest.py::test_function", simple_test_file_path
+ ),
+ }
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the unittest_pytest_same_file.py file.
+# βββ unittest_pytest_same_file.py
+# βββ TestExample
+# β βββ test_true_unittest
+# βββ test_true_pytest
+unit_pytest_same_file_path = TEST_DATA_PATH / "unittest_pytest_same_file.py"
+unit_pytest_same_file_discovery_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "unittest_pytest_same_file.py",
+ "path": os.fspath(unit_pytest_same_file_path),
+ "type_": "file",
+ "id_": os.fspath(unit_pytest_same_file_path),
+ "children": [
+ {
+ "name": "TestExample",
+ "path": os.fspath(unit_pytest_same_file_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_true_unittest",
+ "path": os.fspath(unit_pytest_same_file_path),
+ "lineno": find_test_line_number(
+ "test_true_unittest",
+ os.fspath(unit_pytest_same_file_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_pytest_same_file.py::TestExample::test_true_unittest",
+ unit_pytest_same_file_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_pytest_same_file.py::TestExample::test_true_unittest",
+ unit_pytest_same_file_path,
+ ),
+ }
+ ],
+ "id_": get_absolute_test_id(
+ "unittest_pytest_same_file.py::TestExample",
+ unit_pytest_same_file_path,
+ ),
+ "lineno": find_class_line_number("TestExample", unit_pytest_same_file_path),
+ },
+ {
+ "name": "test_true_pytest",
+ "path": os.fspath(unit_pytest_same_file_path),
+ "lineno": find_test_line_number(
+ "test_true_pytest",
+ unit_pytest_same_file_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_pytest_same_file.py::test_true_pytest",
+ unit_pytest_same_file_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_pytest_same_file.py::test_true_pytest",
+ unit_pytest_same_file_path,
+ ),
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the unittest_skip_file_level test.
+# βββ unittest_skiptest_file_level.py
+unittest_skip_file_level_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the unittest_folder tests
+# βββ unittest_folder
+# βββ test_add.py
+# β βββ TestAddFunction
+# β βββ test_add_negative_numbers
+# β βββ test_add_positive_numbers
+# β βββ TestDuplicateFunction
+# β βββ test_dup_a
+# βββ test_subtract.py
+# βββ TestSubtractFunction
+# βββ test_subtract_negative_numbers
+# βββ test_subtract_positive_numbers
+# β βββ TestDuplicateFunction
+# β βββ test_dup_s
+unittest_folder_path = TEST_DATA_PATH / "unittest_folder"
+test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
+test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py"
+unittest_folder_discovery_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "unittest_folder",
+ "path": os.fspath(unittest_folder_path),
+ "type_": "folder",
+ "id_": os.fspath(unittest_folder_path),
+ "children": [
+ {
+ "name": "test_add.py",
+ "path": os.fspath(test_add_path),
+ "type_": "file",
+ "id_": os.fspath(test_add_path),
+ "children": [
+ {
+ "name": "TestAddFunction",
+ "path": os.fspath(test_add_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_add_negative_numbers",
+ "path": os.fspath(test_add_path),
+ "lineno": find_test_line_number(
+ "test_add_negative_numbers",
+ os.fspath(test_add_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers",
+ test_add_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers",
+ test_add_path,
+ ),
+ },
+ {
+ "name": "test_add_positive_numbers",
+ "path": os.fspath(test_add_path),
+ "lineno": find_test_line_number(
+ "test_add_positive_numbers",
+ os.fspath(test_add_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
+ test_add_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
+ test_add_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestAddFunction",
+ test_add_path,
+ ),
+ "lineno": find_class_line_number("TestAddFunction", test_add_path),
+ },
+ {
+ "name": "TestDuplicateFunction",
+ "path": os.fspath(test_add_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_dup_a",
+ "path": os.fspath(test_add_path),
+ "lineno": find_test_line_number(
+ "test_dup_a",
+ os.fspath(test_add_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a",
+ test_add_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestDuplicateFunction::test_dup_a",
+ test_add_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_add.py::TestDuplicateFunction",
+ test_add_path,
+ ),
+ "lineno": find_class_line_number(
+ "TestDuplicateFunction", test_add_path
+ ),
+ },
+ ],
+ },
+ {
+ "name": "test_subtract.py",
+ "path": os.fspath(test_subtract_path),
+ "type_": "file",
+ "id_": os.fspath(test_subtract_path),
+ "children": [
+ {
+ "name": "TestSubtractFunction",
+ "path": os.fspath(test_subtract_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_subtract_negative_numbers",
+ "path": os.fspath(test_subtract_path),
+ "lineno": find_test_line_number(
+ "test_subtract_negative_numbers",
+ os.fspath(test_subtract_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
+ test_subtract_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
+ test_subtract_path,
+ ),
+ },
+ {
+ "name": "test_subtract_positive_numbers",
+ "path": os.fspath(test_subtract_path),
+ "lineno": find_test_line_number(
+ "test_subtract_positive_numbers",
+ os.fspath(test_subtract_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
+ test_subtract_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
+ test_subtract_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestSubtractFunction",
+ test_subtract_path,
+ ),
+ "lineno": find_class_line_number(
+ "TestSubtractFunction", test_subtract_path
+ ),
+ },
+ {
+ "name": "TestDuplicateFunction",
+ "path": os.fspath(test_subtract_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_dup_s",
+ "path": os.fspath(test_subtract_path),
+ "lineno": find_test_line_number(
+ "test_dup_s",
+ os.fspath(test_subtract_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s",
+ test_subtract_path,
+ ),
+ "runID": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestDuplicateFunction::test_dup_s",
+ test_subtract_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "unittest_folder/test_subtract.py::TestDuplicateFunction",
+ test_subtract_path,
+ ),
+ "lineno": find_class_line_number(
+ "TestDuplicateFunction", test_subtract_path
+ ),
+ },
+ ],
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+
+# This is the expected output for the dual_level_nested_folder tests
+# βββ dual_level_nested_folder
+# βββ test_top_folder.py
+# βββ test_top_function_t
+# βββ test_top_function_f
+# βββ nested_folder_one
+# βββ test_bottom_folder.py
+# βββ test_bottom_function_t
+# βββ test_bottom_function_f
+dual_level_nested_folder_path = TEST_DATA_PATH / "dual_level_nested_folder"
+test_top_folder_path = TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
+
+test_nested_folder_one_path = TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one"
+
+test_bottom_folder_path = (
+ TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py"
+)
+
+
+dual_level_nested_folder_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "dual_level_nested_folder",
+ "path": os.fspath(dual_level_nested_folder_path),
+ "type_": "folder",
+ "id_": os.fspath(dual_level_nested_folder_path),
+ "children": [
+ {
+ "name": "test_top_folder.py",
+ "path": os.fspath(test_top_folder_path),
+ "type_": "file",
+ "id_": os.fspath(test_top_folder_path),
+ "children": [
+ {
+ "name": "test_top_function_t",
+ "path": os.fspath(test_top_folder_path),
+ "lineno": find_test_line_number(
+ "test_top_function_t",
+ test_top_folder_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "dual_level_nested_folder/test_top_folder.py::test_top_function_t",
+ test_top_folder_path,
+ ),
+ "runID": get_absolute_test_id(
+ "dual_level_nested_folder/test_top_folder.py::test_top_function_t",
+ test_top_folder_path,
+ ),
+ },
+ {
+ "name": "test_top_function_f",
+ "path": os.fspath(test_top_folder_path),
+ "lineno": find_test_line_number(
+ "test_top_function_f",
+ test_top_folder_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "dual_level_nested_folder/test_top_folder.py::test_top_function_f",
+ test_top_folder_path,
+ ),
+ "runID": get_absolute_test_id(
+ "dual_level_nested_folder/test_top_folder.py::test_top_function_f",
+ test_top_folder_path,
+ ),
+ },
+ ],
+ },
+ {
+ "name": "nested_folder_one",
+ "path": os.fspath(test_nested_folder_one_path),
+ "type_": "folder",
+ "id_": os.fspath(test_nested_folder_one_path),
+ "children": [
+ {
+ "name": "test_bottom_folder.py",
+ "path": os.fspath(test_bottom_folder_path),
+ "type_": "file",
+ "id_": os.fspath(test_bottom_folder_path),
+ "children": [
+ {
+ "name": "test_bottom_function_t",
+ "path": os.fspath(test_bottom_folder_path),
+ "lineno": find_test_line_number(
+ "test_bottom_function_t",
+ test_bottom_folder_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
+ test_bottom_folder_path,
+ ),
+ "runID": get_absolute_test_id(
+ "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
+ test_bottom_folder_path,
+ ),
+ },
+ {
+ "name": "test_bottom_function_f",
+ "path": os.fspath(test_bottom_folder_path),
+ "lineno": find_test_line_number(
+ "test_bottom_function_f",
+ test_bottom_folder_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
+ test_bottom_folder_path,
+ ),
+ "runID": get_absolute_test_id(
+ "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
+ test_bottom_folder_path,
+ ),
+ },
+ ],
+ }
+ ],
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the double_nested_folder tests.
+# βββ folder_a
+# βββ folder_b
+# βββ folder_a
+# βββ test_nest.py
+# βββ test_function
+
+folder_a_path = TEST_DATA_PATH / "folder_a"
+folder_b_path = TEST_DATA_PATH / "folder_a" / "folder_b"
+folder_a_nested_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a"
+test_nest_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py"
+double_nested_folder_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "folder_a",
+ "path": os.fspath(folder_a_path),
+ "type_": "folder",
+ "id_": os.fspath(folder_a_path),
+ "children": [
+ {
+ "name": "folder_b",
+ "path": os.fspath(folder_b_path),
+ "type_": "folder",
+ "id_": os.fspath(folder_b_path),
+ "children": [
+ {
+ "name": "folder_a",
+ "path": os.fspath(folder_a_nested_path),
+ "type_": "folder",
+ "id_": os.fspath(folder_a_nested_path),
+ "children": [
+ {
+ "name": "test_nest.py",
+ "path": os.fspath(test_nest_path),
+ "type_": "file",
+ "id_": os.fspath(test_nest_path),
+ "children": [
+ {
+ "name": "test_function",
+ "path": os.fspath(test_nest_path),
+ "lineno": find_test_line_number(
+ "test_function",
+ test_nest_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "folder_a/folder_b/folder_a/test_nest.py::test_function",
+ test_nest_path,
+ ),
+ "runID": get_absolute_test_id(
+ "folder_a/folder_b/folder_a/test_nest.py::test_function",
+ test_nest_path,
+ ),
+ }
+ ],
+ }
+ ],
+ }
+ ],
+ }
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the nested_folder tests.
+# βββ parametrize_tests.py
+# βββ TestClass
+# βββ test_adding
+# βββ [3+5-8]
+# βββ [2+4-6]
+# βββ [6+9-16]
+# βββ test_string
+# βββ [hello]
+# βββ [complicated split [] ()]
+parameterize_tests_path = TEST_DATA_PATH / "parametrize_tests.py"
+parametrize_tests_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "parametrize_tests.py",
+ "path": os.fspath(parameterize_tests_path),
+ "type_": "file",
+ "id_": os.fspath(parameterize_tests_path),
+ "children": [
+ {
+ "name": "TestClass",
+ "path": os.fspath(parameterize_tests_path),
+ "type_": "class",
+ "id_": get_absolute_test_id(
+ "parametrize_tests.py::TestClass",
+ parameterize_tests_path,
+ ),
+ "lineno": find_class_line_number("TestClass", parameterize_tests_path),
+ "children": [
+ {
+ "name": "test_adding",
+ "path": os.fspath(parameterize_tests_path),
+ "type_": "function",
+ "id_": os.fspath(parameterize_tests_path) + "::TestClass::test_adding",
+ "children": [
+ {
+ "name": "[3+5-8]",
+ "path": os.fspath(parameterize_tests_path),
+ "lineno": find_test_line_number(
+ "test_adding[3+5-8]",
+ parameterize_tests_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]",
+ parameterize_tests_path,
+ ),
+ "runID": get_absolute_test_id(
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]",
+ parameterize_tests_path,
+ ),
+ },
+ {
+ "name": "[2+4-6]",
+ "path": os.fspath(parameterize_tests_path),
+ "lineno": find_test_line_number(
+ "test_adding[2+4-6]",
+ parameterize_tests_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "parametrize_tests.py::TestClass::test_adding[2+4-6]",
+ parameterize_tests_path,
+ ),
+ "runID": get_absolute_test_id(
+ "parametrize_tests.py::TestClass::test_adding[2+4-6]",
+ parameterize_tests_path,
+ ),
+ },
+ {
+ "name": "[6+9-16]",
+ "path": os.fspath(parameterize_tests_path),
+ "lineno": find_test_line_number(
+ "test_adding[6+9-16]",
+ parameterize_tests_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "parametrize_tests.py::TestClass::test_adding[6+9-16]",
+ parameterize_tests_path,
+ ),
+ "runID": get_absolute_test_id(
+ "parametrize_tests.py::TestClass::test_adding[6+9-16]",
+ parameterize_tests_path,
+ ),
+ },
+ ],
+ },
+ ],
+ },
+ {
+ "name": "test_string",
+ "path": os.fspath(parameterize_tests_path),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[hello]",
+ "path": os.fspath(parameterize_tests_path),
+ "lineno": find_test_line_number(
+ "test_string[hello]",
+ parameterize_tests_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "parametrize_tests.py::test_string[hello]",
+ parameterize_tests_path,
+ ),
+ "runID": get_absolute_test_id(
+ "parametrize_tests.py::test_string[hello]",
+ parameterize_tests_path,
+ ),
+ },
+ {
+ "name": "[complicated split [] ()]",
+ "path": os.fspath(parameterize_tests_path),
+ "lineno": find_test_line_number(
+ "test_string[1]",
+ parameterize_tests_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "parametrize_tests.py::test_string[complicated split [] ()]",
+ parameterize_tests_path,
+ ),
+ "runID": get_absolute_test_id(
+ "parametrize_tests.py::test_string[complicated split [] ()]",
+ parameterize_tests_path,
+ ),
+ },
+ ],
+ "id_": os.fspath(parameterize_tests_path) + "::test_string",
+ },
+ ],
+ },
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the text_docstring.txt tests.
+# βββ text_docstring.txt
+text_docstring_path = TEST_DATA_PATH / "text_docstring.txt"
+doctest_pytest_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "text_docstring.txt",
+ "path": os.fspath(text_docstring_path),
+ "type_": "file",
+ "id_": os.fspath(text_docstring_path),
+ "children": [
+ {
+ "name": "text_docstring.txt",
+ "path": os.fspath(text_docstring_path),
+ "lineno": find_test_line_number(
+ "text_docstring.txt",
+ os.fspath(text_docstring_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "text_docstring.txt::text_docstring.txt", text_docstring_path
+ ),
+ "runID": get_absolute_test_id(
+ "text_docstring.txt::text_docstring.txt", text_docstring_path
+ ),
+ }
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the param_same_name tests.
+# βββ param_same_name
+# βββ test_param1.py
+# βββ test_odd_even
+# βββ [a]
+# βββ [b]
+# βββ [c]
+# βββ test_param2.py
+# βββ test_odd_even
+# βββ [1]
+# βββ [2]
+# βββ [3]
+param1_path = TEST_DATA_PATH / "param_same_name" / "test_param1.py"
+param2_path = TEST_DATA_PATH / "param_same_name" / "test_param2.py"
+param_same_name_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "param_same_name",
+ "path": os.fspath(TEST_DATA_PATH / "param_same_name"),
+ "type_": "folder",
+ "id_": os.fspath(TEST_DATA_PATH / "param_same_name"),
+ "children": [
+ {
+ "name": "test_param1.py",
+ "path": os.fspath(param1_path),
+ "type_": "file",
+ "id_": os.fspath(param1_path),
+ "children": [
+ {
+ "name": "test_odd_even",
+ "path": os.fspath(param1_path),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[a]",
+ "path": os.fspath(param1_path),
+ "lineno": "6",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "param_same_name/test_param1.py::test_odd_even[a]",
+ param1_path,
+ ),
+ "runID": get_absolute_test_id(
+ "param_same_name/test_param1.py::test_odd_even[a]",
+ param1_path,
+ ),
+ },
+ {
+ "name": "[b]",
+ "path": os.fspath(param1_path),
+ "lineno": "6",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "param_same_name/test_param1.py::test_odd_even[b]",
+ param1_path,
+ ),
+ "runID": get_absolute_test_id(
+ "param_same_name/test_param1.py::test_odd_even[b]",
+ param1_path,
+ ),
+ },
+ {
+ "name": "[c]",
+ "path": os.fspath(param1_path),
+ "lineno": "6",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "param_same_name/test_param1.py::test_odd_even[c]",
+ param1_path,
+ ),
+ "runID": get_absolute_test_id(
+ "param_same_name/test_param1.py::test_odd_even[c]",
+ param1_path,
+ ),
+ },
+ ],
+ "id_": os.fspath(param1_path) + "::test_odd_even",
+ }
+ ],
+ },
+ {
+ "name": "test_param2.py",
+ "path": os.fspath(param2_path),
+ "type_": "file",
+ "id_": os.fspath(param2_path),
+ "children": [
+ {
+ "name": "test_odd_even",
+ "path": os.fspath(param2_path),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[1]",
+ "path": os.fspath(param2_path),
+ "lineno": "6",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "param_same_name/test_param2.py::test_odd_even[1]",
+ param2_path,
+ ),
+ "runID": get_absolute_test_id(
+ "param_same_name/test_param2.py::test_odd_even[1]",
+ param2_path,
+ ),
+ },
+ {
+ "name": "[2]",
+ "path": os.fspath(param2_path),
+ "lineno": "6",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "param_same_name/test_param2.py::test_odd_even[2]",
+ param2_path,
+ ),
+ "runID": get_absolute_test_id(
+ "param_same_name/test_param2.py::test_odd_even[2]",
+ param2_path,
+ ),
+ },
+ {
+ "name": "[3]",
+ "path": os.fspath(param2_path),
+ "lineno": "6",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "param_same_name/test_param2.py::test_odd_even[3]",
+ param2_path,
+ ),
+ "runID": get_absolute_test_id(
+ "param_same_name/test_param2.py::test_odd_even[3]",
+ param2_path,
+ ),
+ },
+ ],
+ "id_": os.fspath(param2_path) + "::test_odd_even",
+ }
+ ],
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+tests_path = TEST_DATA_PATH / "root" / "tests"
+tests_a_path = TEST_DATA_PATH / "root" / "tests" / "test_a.py"
+tests_b_path = TEST_DATA_PATH / "root" / "tests" / "test_b.py"
+# This is the expected output for the root folder tests.
+# βββ tests
+# βββ test_a.py
+# βββ test_a_function
+# βββ test_b.py
+# βββ test_b_function
+root_with_config_expected_output = {
+ "name": "tests",
+ "path": os.fspath(tests_path),
+ "type_": "folder",
+ "children": [
+ {
+ "name": "test_a.py",
+ "path": os.fspath(tests_a_path),
+ "type_": "file",
+ "id_": os.fspath(tests_a_path),
+ "children": [
+ {
+ "name": "test_a_function",
+ "path": os.fspath(os.path.join(tests_path, "test_a.py")), # noqa: PTH118
+ "lineno": find_test_line_number(
+ "test_a_function",
+ os.path.join(tests_path, "test_a.py"), # noqa: PTH118
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id("tests/test_a.py::test_a_function", tests_a_path),
+ "runID": get_absolute_test_id("tests/test_a.py::test_a_function", tests_a_path),
+ }
+ ],
+ },
+ {
+ "name": "test_b.py",
+ "path": os.fspath(tests_b_path),
+ "type_": "file",
+ "id_": os.fspath(tests_b_path),
+ "children": [
+ {
+ "name": "test_b_function",
+ "path": os.fspath(os.path.join(tests_path, "test_b.py")), # noqa: PTH118
+ "lineno": find_test_line_number(
+ "test_b_function",
+ os.path.join(tests_path, "test_b.py"), # noqa: PTH118
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id("tests/test_b.py::test_b_function", tests_b_path),
+ "runID": get_absolute_test_id("tests/test_b.py::test_b_function", tests_b_path),
+ }
+ ],
+ },
+ ],
+ "id_": os.fspath(tests_path),
+}
+TEST_MULTI_CLASS_NEST_PATH = TEST_DATA_PATH / "test_multi_class_nest.py"
+# This is the expected output for the nested_classes tests.
+# βββ test_multi_class_nest.py
+# βββ TestFirstClass
+# βββ TestSecondClass
+# βββ test_second
+# βββ test_first
+# βββ TestSecondClass2
+# βββ test_second2
+# βββ test_independent
+nested_classes_expected_test_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "test_multi_class_nest.py",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "type_": "file",
+ "id_": str(TEST_MULTI_CLASS_NEST_PATH),
+ "children": [
+ {
+ "name": "TestFirstClass",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "type_": "class",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "lineno": find_class_line_number("TestFirstClass", TEST_MULTI_CLASS_NEST_PATH),
+ "children": [
+ {
+ "name": "TestSecondClass",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "type_": "class",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::TestSecondClass",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "lineno": find_class_line_number(
+ "TestSecondClass", TEST_MULTI_CLASS_NEST_PATH
+ ),
+ "children": [
+ {
+ "name": "test_second",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "lineno": find_test_line_number(
+ "test_second",
+ str(TEST_MULTI_CLASS_NEST_PATH),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::TestSecondClass::test_second",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "runID": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::TestSecondClass::test_second",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ }
+ ],
+ },
+ {
+ "name": "test_first",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "lineno": find_test_line_number(
+ "test_first", str(TEST_MULTI_CLASS_NEST_PATH)
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::test_first",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "runID": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::test_first",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ },
+ {
+ "name": "TestSecondClass2",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "type_": "class",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::TestSecondClass2",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "lineno": find_class_line_number(
+ "TestSecondClass2", TEST_MULTI_CLASS_NEST_PATH
+ ),
+ "children": [
+ {
+ "name": "test_second2",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "lineno": find_test_line_number(
+ "test_second2",
+ str(TEST_MULTI_CLASS_NEST_PATH),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::TestSecondClass2::test_second2",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "runID": get_absolute_test_id(
+ "test_multi_class_nest.py::TestFirstClass::TestSecondClass2::test_second2",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ }
+ ],
+ },
+ ],
+ },
+ {
+ "name": "test_independent",
+ "path": str(TEST_MULTI_CLASS_NEST_PATH),
+ "lineno": find_test_line_number(
+ "test_independent", str(TEST_MULTI_CLASS_NEST_PATH)
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_multi_class_nest.py::test_independent",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ "runID": get_absolute_test_id(
+ "test_multi_class_nest.py::test_independent",
+ TEST_MULTI_CLASS_NEST_PATH,
+ ),
+ },
+ ],
+ }
+ ],
+ "id_": str(TEST_DATA_PATH),
+}
+SYMLINK_FOLDER_PATH = TEST_DATA_PATH / "symlink_folder"
+SYMLINK_FOLDER_PATH_TESTS = TEST_DATA_PATH / "symlink_folder" / "tests"
+SYMLINK_FOLDER_PATH_TESTS_TEST_A = TEST_DATA_PATH / "symlink_folder" / "tests" / "test_a.py"
+SYMLINK_FOLDER_PATH_TESTS_TEST_B = TEST_DATA_PATH / "symlink_folder" / "tests" / "test_b.py"
+
+# This is the expected output for the symlink_folder tests.
+# βββ symlink_folder
+# βββ tests
+# βββ test_a.py
+# βββ test_a_function
+# βββ test_b.py
+# βββ test_b_function
+symlink_expected_discovery_output = {
+ "name": "symlink_folder",
+ "path": str(SYMLINK_FOLDER_PATH),
+ "type_": "folder",
+ "children": [
+ {
+ "name": "tests",
+ "path": str(SYMLINK_FOLDER_PATH_TESTS),
+ "type_": "folder",
+ "id_": str(SYMLINK_FOLDER_PATH_TESTS),
+ "children": [
+ {
+ "name": "test_a.py",
+ "path": str(SYMLINK_FOLDER_PATH_TESTS_TEST_A),
+ "type_": "file",
+ "id_": str(SYMLINK_FOLDER_PATH_TESTS_TEST_A),
+ "children": [
+ {
+ "name": "test_a_function",
+ "path": str(SYMLINK_FOLDER_PATH_TESTS_TEST_A),
+ "lineno": find_test_line_number(
+ "test_a_function",
+ os.path.join(tests_path, "test_a.py"), # noqa: PTH118
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "tests/test_a.py::test_a_function",
+ SYMLINK_FOLDER_PATH_TESTS_TEST_A,
+ ),
+ "runID": get_absolute_test_id(
+ "tests/test_a.py::test_a_function",
+ SYMLINK_FOLDER_PATH_TESTS_TEST_A,
+ ),
+ }
+ ],
+ },
+ {
+ "name": "test_b.py",
+ "path": str(SYMLINK_FOLDER_PATH_TESTS_TEST_B),
+ "type_": "file",
+ "id_": str(SYMLINK_FOLDER_PATH_TESTS_TEST_B),
+ "children": [
+ {
+ "name": "test_b_function",
+ "path": str(SYMLINK_FOLDER_PATH_TESTS_TEST_B),
+ "lineno": find_test_line_number(
+ "test_b_function",
+ os.path.join(tests_path, "test_b.py"), # noqa: PTH118
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "tests/test_b.py::test_b_function",
+ SYMLINK_FOLDER_PATH_TESTS_TEST_B,
+ ),
+ "runID": get_absolute_test_id(
+ "tests/test_b.py::test_b_function",
+ SYMLINK_FOLDER_PATH_TESTS_TEST_B,
+ ),
+ }
+ ],
+ },
+ ],
+ }
+ ],
+ "id_": str(SYMLINK_FOLDER_PATH),
+}
+
+same_function_new_class_param_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "same_function_new_class_param.py",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "file",
+ "id_": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "children": [
+ {
+ "name": "TestNotEmpty",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_integer",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[1-1]",
+ "path": os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ "lineno": find_test_line_number(
+ "TestNotEmpty::test_integer",
+ os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_integer[1-1]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "runID": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_integer[1-1]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ },
+ {
+ "name": "[2-2]",
+ "path": os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ "lineno": find_test_line_number(
+ "TestNotEmpty::test_integer",
+ os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_integer[2-2]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "runID": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_integer[2-2]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ },
+ ],
+ "id_": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py")
+ + "::TestNotEmpty::test_integer",
+ },
+ {
+ "name": "test_string",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[a-a]",
+ "path": os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ "lineno": find_test_line_number(
+ "TestNotEmpty::test_string",
+ os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_string[a-a]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "runID": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_string[a-a]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ },
+ {
+ "name": "[b-b]",
+ "path": os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ "lineno": find_test_line_number(
+ "TestNotEmpty::test_string",
+ os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_string[b-b]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "runID": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty::test_string[b-b]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ },
+ ],
+ "id_": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py")
+ + "::TestNotEmpty::test_string",
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestNotEmpty",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "lineno": find_class_line_number(
+ "TestNotEmpty", TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ },
+ {
+ "name": "TestEmpty",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_integer",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[0-0]",
+ "path": os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ "lineno": find_test_line_number(
+ "TestEmpty::test_integer",
+ os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestEmpty::test_integer[0-0]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "runID": get_absolute_test_id(
+ "same_function_new_class_param.py::TestEmpty::test_integer[0-0]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ },
+ ],
+ "id_": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py")
+ + "::TestEmpty::test_integer",
+ },
+ {
+ "name": "test_string",
+ "path": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py"),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[-]",
+ "path": os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ "lineno": find_test_line_number(
+ "TestEmpty::test_string",
+ os.fspath(
+ TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestEmpty::test_string[-]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "runID": get_absolute_test_id(
+ "same_function_new_class_param.py::TestEmpty::test_string[-]",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ },
+ ],
+ "id_": os.fspath(TEST_DATA_PATH / "same_function_new_class_param.py")
+ + "::TestEmpty::test_string",
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "same_function_new_class_param.py::TestEmpty",
+ TEST_DATA_PATH / "same_function_new_class_param.py",
+ ),
+ "lineno": find_class_line_number(
+ "TestEmpty", TEST_DATA_PATH / "same_function_new_class_param.py"
+ ),
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+test_param_span_class_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "test_param_span_class.py",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "type_": "file",
+ "id_": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "children": [
+ {
+ "name": "TestClass1",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_method1",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[1]",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "lineno": find_test_line_number(
+ "TestClass1::test_method1",
+ os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_param_span_class.py::TestClass1::test_method1[1]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ "runID": get_absolute_test_id(
+ "test_param_span_class.py::TestClass1::test_method1[1]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ },
+ {
+ "name": "[2]",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "lineno": find_test_line_number(
+ "TestClass1::test_method1",
+ os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_param_span_class.py::TestClass1::test_method1[2]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ "runID": get_absolute_test_id(
+ "test_param_span_class.py::TestClass1::test_method1[2]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ },
+ ],
+ "id_": os.fspath(
+ TEST_DATA_PATH
+ / "test_param_span_class.py::TestClass1::test_method1"
+ ),
+ }
+ ],
+ "id_": get_absolute_test_id(
+ "test_param_span_class.py::TestClass1",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ "lineno": find_class_line_number(
+ "TestClass1", TEST_DATA_PATH / "test_param_span_class.py"
+ ),
+ },
+ {
+ "name": "TestClass2",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_method1",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "type_": "function",
+ "children": [
+ {
+ "name": "[1]",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "lineno": find_test_line_number(
+ "TestClass2::test_method1",
+ os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_param_span_class.py::TestClass2::test_method1[1]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ "runID": get_absolute_test_id(
+ "test_param_span_class.py::TestClass2::test_method1[1]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ },
+ {
+ "name": "[2]",
+ "path": os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ "lineno": find_test_line_number(
+ "TestClass2::test_method1",
+ os.fspath(TEST_DATA_PATH / "test_param_span_class.py"),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_param_span_class.py::TestClass2::test_method1[2]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ "runID": get_absolute_test_id(
+ "test_param_span_class.py::TestClass2::test_method1[2]",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ },
+ ],
+ "id_": os.fspath(
+ TEST_DATA_PATH
+ / "test_param_span_class.py::TestClass2::test_method1"
+ ),
+ }
+ ],
+ "id_": get_absolute_test_id(
+ "test_param_span_class.py::TestClass2",
+ TEST_DATA_PATH / "test_param_span_class.py",
+ ),
+ "lineno": find_class_line_number(
+ "TestClass2", TEST_DATA_PATH / "test_param_span_class.py"
+ ),
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+# This is the expected output for the describe_only.py tests.
+# βββ describe_only.py
+# βββ describe_A
+# βββ test_1
+# βββ test_2
+
+describe_only_path = TEST_DATA_PATH / "pytest_describe_plugin" / "describe_only.py"
+pytest_describe_plugin_path = TEST_DATA_PATH / "pytest_describe_plugin"
+
+expected_describe_only_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "pytest_describe_plugin",
+ "path": os.fspath(pytest_describe_plugin_path),
+ "type_": "folder",
+ "id_": os.fspath(pytest_describe_plugin_path),
+ "children": [
+ {
+ "name": "describe_only.py",
+ "path": os.fspath(describe_only_path),
+ "type_": "file",
+ "id_": os.fspath(describe_only_path),
+ "children": [
+ {
+ "name": "describe_A",
+ "path": os.fspath(describe_only_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_1",
+ "path": os.fspath(describe_only_path),
+ "lineno": find_test_line_number(
+ "test_1",
+ describe_only_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_1",
+ describe_only_path,
+ ),
+ "runID": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_1",
+ describe_only_path,
+ ),
+ },
+ {
+ "name": "test_2",
+ "path": os.fspath(describe_only_path),
+ "lineno": find_test_line_number(
+ "test_2",
+ describe_only_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_2",
+ describe_only_path,
+ ),
+ "runID": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_2",
+ describe_only_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A",
+ describe_only_path,
+ ),
+ "lineno": find_class_line_number("describe_A", describe_only_path),
+ }
+ ],
+ }
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+# This is the expected output for the nested_describe.py tests.
+# βββ nested_describe.py
+# βββ describe_list
+# βββ describe_append
+# βββ add_empty
+# βββ remove_empty
+# βββ describe_remove
+# βββ removes
+nested_describe_path = TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py"
+expected_nested_describe_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "pytest_describe_plugin",
+ "path": os.fspath(pytest_describe_plugin_path),
+ "type_": "folder",
+ "id_": os.fspath(pytest_describe_plugin_path),
+ "children": [
+ {
+ "name": "nested_describe.py",
+ "path": os.fspath(nested_describe_path),
+ "type_": "file",
+ "id_": os.fspath(nested_describe_path),
+ "children": [
+ {
+ "name": "describe_list",
+ "path": os.fspath(nested_describe_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "describe_append",
+ "path": os.fspath(nested_describe_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "add_empty",
+ "path": os.fspath(nested_describe_path),
+ "lineno": find_test_line_number(
+ "add_empty",
+ nested_describe_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::add_empty",
+ nested_describe_path,
+ ),
+ "runID": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::add_empty",
+ nested_describe_path,
+ ),
+ },
+ {
+ "name": "remove_empty",
+ "path": os.fspath(nested_describe_path),
+ "lineno": find_test_line_number(
+ "remove_empty",
+ nested_describe_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::remove_empty",
+ nested_describe_path,
+ ),
+ "runID": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::remove_empty",
+ nested_describe_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append",
+ nested_describe_path,
+ ),
+ "lineno": find_class_line_number(
+ "describe_append", nested_describe_path
+ ),
+ },
+ {
+ "name": "describe_remove",
+ "path": os.fspath(nested_describe_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "removes",
+ "path": os.fspath(nested_describe_path),
+ "lineno": find_test_line_number(
+ "removes",
+ nested_describe_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_remove::removes",
+ nested_describe_path,
+ ),
+ "runID": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_remove::removes",
+ nested_describe_path,
+ ),
+ }
+ ],
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_remove",
+ nested_describe_path,
+ ),
+ "lineno": find_class_line_number(
+ "describe_remove", nested_describe_path
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list",
+ nested_describe_path,
+ ),
+ "lineno": find_class_line_number("describe_list", nested_describe_path),
+ }
+ ],
+ }
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+# This is the expected output for the folder_with_script folder when run with ruff
+# βββ .data
+# βββ folder_with_script
+# βββ script_random.py
+# βββ ruff
+# βββ test_simple.py
+# βββ ruff
+# βββ test_function
+ruff_test_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "folder_with_script",
+ "path": os.fspath(TEST_DATA_PATH / "folder_with_script"),
+ "type_": "folder",
+ "id_": os.fspath(TEST_DATA_PATH / "folder_with_script"),
+ "children": [
+ {
+ "name": "script_random.py",
+ "path": os.fspath(TEST_DATA_PATH / "folder_with_script" / "script_random.py"),
+ "type_": "file",
+ "id_": os.fspath(TEST_DATA_PATH / "folder_with_script" / "script_random.py"),
+ "children": [
+ {
+ "name": "ruff",
+ "path": os.fspath(
+ TEST_DATA_PATH / "folder_with_script" / "script_random.py"
+ ),
+ "lineno": "",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "folder_with_script/script_random.py::ruff",
+ TEST_DATA_PATH / "folder_with_script" / "script_random.py",
+ ),
+ "runID": get_absolute_test_id(
+ "folder_with_script/script_random.py::ruff",
+ TEST_DATA_PATH / "folder_with_script" / "script_random.py",
+ ),
+ }
+ ],
+ },
+ {
+ "name": "test_simple.py",
+ "path": os.fspath(TEST_DATA_PATH / "folder_with_script" / "test_simple.py"),
+ "type_": "file",
+ "id_": os.fspath(TEST_DATA_PATH / "folder_with_script" / "test_simple.py"),
+ "children": [
+ {
+ "name": "ruff",
+ "path": os.fspath(
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py"
+ ),
+ "lineno": "",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "folder_with_script/test_simple.py::ruff",
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py",
+ ),
+ "runID": get_absolute_test_id(
+ "folder_with_script/test_simple.py::ruff",
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py",
+ ),
+ },
+ {
+ "name": "test_function",
+ "path": os.fspath(
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py"
+ ),
+ "lineno": find_test_line_number(
+ "test_function",
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py",
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "folder_with_script/test_simple.py::test_function",
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py",
+ ),
+ "runID": get_absolute_test_id(
+ "folder_with_script/test_simple.py::test_function",
+ TEST_DATA_PATH / "folder_with_script" / "test_simple.py",
+ ),
+ },
+ ],
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# This is the expected output for the 2496-black-formatter folder when run with black plugin
+# βββ .data
+# βββ 2496-black-formatter
+# βββ app.py
+# βββ black
+# βββ test_app.py
+# βββ black
+# βββ test_add
+# βββ test_subtract
+black_formatter_folder_path = TEST_DATA_PATH / "2496-black-formatter"
+black_app_path = black_formatter_folder_path / "app.py"
+black_test_app_path = black_formatter_folder_path / "test_app.py"
+black_formatter_expected_output = {
+ "name": ".data",
+ "path": TEST_DATA_PATH_STR,
+ "type_": "folder",
+ "children": [
+ {
+ "name": "2496-black-formatter",
+ "path": os.fspath(black_formatter_folder_path),
+ "type_": "folder",
+ "id_": os.fspath(black_formatter_folder_path),
+ "children": [
+ {
+ "name": "app.py",
+ "path": os.fspath(black_app_path),
+ "type_": "file",
+ "id_": os.fspath(black_app_path),
+ "children": [
+ {
+ "name": "black",
+ "path": os.fspath(black_app_path),
+ "lineno": "0",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "2496-black-formatter/app.py::black",
+ black_app_path,
+ ),
+ "runID": get_absolute_test_id(
+ "2496-black-formatter/app.py::black",
+ black_app_path,
+ ),
+ }
+ ],
+ },
+ {
+ "name": "test_app.py",
+ "path": os.fspath(black_test_app_path),
+ "type_": "file",
+ "id_": os.fspath(black_test_app_path),
+ "children": [
+ {
+ "name": "black",
+ "path": os.fspath(black_test_app_path),
+ "lineno": "0",
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "2496-black-formatter/test_app.py::black",
+ black_test_app_path,
+ ),
+ "runID": get_absolute_test_id(
+ "2496-black-formatter/test_app.py::black",
+ black_test_app_path,
+ ),
+ },
+ {
+ "name": "test_add",
+ "path": os.fspath(black_test_app_path),
+ "lineno": find_test_line_number(
+ "test_add",
+ black_test_app_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "2496-black-formatter/test_app.py::test_add",
+ black_test_app_path,
+ ),
+ "runID": get_absolute_test_id(
+ "2496-black-formatter/test_app.py::test_add",
+ black_test_app_path,
+ ),
+ },
+ {
+ "name": "test_subtract",
+ "path": os.fspath(black_test_app_path),
+ "lineno": find_test_line_number(
+ "test_subtract",
+ black_test_app_path,
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "2496-black-formatter/test_app.py::test_subtract",
+ black_test_app_path,
+ ),
+ "runID": get_absolute_test_id(
+ "2496-black-formatter/test_app.py::test_subtract",
+ black_test_app_path,
+ ),
+ },
+ ],
+ },
+ ],
+ }
+ ],
+ "id_": TEST_DATA_PATH_STR,
+}
+
+# =====================================================================================
+# PROJECT_ROOT_PATH environment variable tests
+# These test the project-based testing feature where PROJECT_ROOT_PATH changes
+# the test tree root from cwd to the specified project path.
+# =====================================================================================
+
+# This is the expected output for unittest_folder when PROJECT_ROOT_PATH is set to unittest_folder.
+# The root of the tree is unittest_folder (not .data), simulating project-based testing.
+#
+# **Project Configuration:**
+# In the VS Code Python extension, projects are defined by the Python Environments extension.
+# Each project has a root directory (identified by pyproject.toml, setup.py, etc.).
+# When PROJECT_ROOT_PATH is set, pytest uses that path as the test tree root instead of cwd.
+#
+# **Test Tree Structure:**
+# Without PROJECT_ROOT_PATH (legacy mode):
+# βββ .data (cwd = workspace root)
+# βββ unittest_folder
+# βββ test_add.py, test_subtract.py...
+#
+# With PROJECT_ROOT_PATH set to unittest_folder (project-based mode):
+# βββ unittest_folder (ROOT - set via PROJECT_ROOT_PATH env var)
+# βββ test_add.py
+# β βββ TestAddFunction
+# β βββ test_add_negative_numbers
+# β βββ test_add_positive_numbers
+# β βββ TestDuplicateFunction
+# β βββ test_dup_a
+# βββ test_subtract.py
+# βββ TestSubtractFunction
+# βββ test_subtract_negative_numbers
+# βββ test_subtract_positive_numbers
+# βββ TestDuplicateFunction
+# βββ test_dup_s
+#
+# Note: This reuses the unittest_folder paths defined earlier in this file.
+project_root_unittest_folder_expected_output = {
+ "name": "unittest_folder",
+ "path": os.fspath(unittest_folder_path),
+ "type_": "folder",
+ "children": [
+ {
+ "name": "test_add.py",
+ "path": os.fspath(test_add_path),
+ "type_": "file",
+ "id_": os.fspath(test_add_path),
+ "children": [
+ {
+ "name": "TestAddFunction",
+ "path": os.fspath(test_add_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_add_negative_numbers",
+ "path": os.fspath(test_add_path),
+ "lineno": find_test_line_number(
+ "test_add_negative_numbers",
+ os.fspath(test_add_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_add.py::TestAddFunction::test_add_negative_numbers",
+ test_add_path,
+ ),
+ "runID": get_absolute_test_id(
+ "test_add.py::TestAddFunction::test_add_negative_numbers",
+ test_add_path,
+ ),
+ },
+ {
+ "name": "test_add_positive_numbers",
+ "path": os.fspath(test_add_path),
+ "lineno": find_test_line_number(
+ "test_add_positive_numbers",
+ os.fspath(test_add_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_add.py::TestAddFunction::test_add_positive_numbers",
+ test_add_path,
+ ),
+ "runID": get_absolute_test_id(
+ "test_add.py::TestAddFunction::test_add_positive_numbers",
+ test_add_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "test_add.py::TestAddFunction",
+ test_add_path,
+ ),
+ "lineno": find_class_line_number("TestAddFunction", test_add_path),
+ },
+ {
+ "name": "TestDuplicateFunction",
+ "path": os.fspath(test_add_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_dup_a",
+ "path": os.fspath(test_add_path),
+ "lineno": find_test_line_number(
+ "test_dup_a",
+ os.fspath(test_add_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_add.py::TestDuplicateFunction::test_dup_a",
+ test_add_path,
+ ),
+ "runID": get_absolute_test_id(
+ "test_add.py::TestDuplicateFunction::test_dup_a",
+ test_add_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "test_add.py::TestDuplicateFunction",
+ test_add_path,
+ ),
+ "lineno": find_class_line_number("TestDuplicateFunction", test_add_path),
+ },
+ ],
+ },
+ {
+ "name": "test_subtract.py",
+ "path": os.fspath(test_subtract_path),
+ "type_": "file",
+ "id_": os.fspath(test_subtract_path),
+ "children": [
+ {
+ "name": "TestSubtractFunction",
+ "path": os.fspath(test_subtract_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_subtract_negative_numbers",
+ "path": os.fspath(test_subtract_path),
+ "lineno": find_test_line_number(
+ "test_subtract_negative_numbers",
+ os.fspath(test_subtract_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
+ test_subtract_path,
+ ),
+ "runID": get_absolute_test_id(
+ "test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
+ test_subtract_path,
+ ),
+ },
+ {
+ "name": "test_subtract_positive_numbers",
+ "path": os.fspath(test_subtract_path),
+ "lineno": find_test_line_number(
+ "test_subtract_positive_numbers",
+ os.fspath(test_subtract_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
+ test_subtract_path,
+ ),
+ "runID": get_absolute_test_id(
+ "test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
+ test_subtract_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "test_subtract.py::TestSubtractFunction",
+ test_subtract_path,
+ ),
+ "lineno": find_class_line_number("TestSubtractFunction", test_subtract_path),
+ },
+ {
+ "name": "TestDuplicateFunction",
+ "path": os.fspath(test_subtract_path),
+ "type_": "class",
+ "children": [
+ {
+ "name": "test_dup_s",
+ "path": os.fspath(test_subtract_path),
+ "lineno": find_test_line_number(
+ "test_dup_s",
+ os.fspath(test_subtract_path),
+ ),
+ "type_": "test",
+ "id_": get_absolute_test_id(
+ "test_subtract.py::TestDuplicateFunction::test_dup_s",
+ test_subtract_path,
+ ),
+ "runID": get_absolute_test_id(
+ "test_subtract.py::TestDuplicateFunction::test_dup_s",
+ test_subtract_path,
+ ),
+ },
+ ],
+ "id_": get_absolute_test_id(
+ "test_subtract.py::TestDuplicateFunction",
+ test_subtract_path,
+ ),
+ "lineno": find_class_line_number("TestDuplicateFunction", test_subtract_path),
+ },
+ ],
+ },
+ ],
+ "id_": os.fspath(unittest_folder_path),
+}
diff --git a/pythonFiles/tests/pytestadapter/expected_execution_test_output.py b/python_files/tests/pytestadapter/expected_execution_test_output.py
similarity index 73%
rename from pythonFiles/tests/pytestadapter/expected_execution_test_output.py
rename to python_files/tests/pytestadapter/expected_execution_test_output.py
index cf8997a252d3..fa6743d0e112 100644
--- a/pythonFiles/tests/pytestadapter/expected_execution_test_output.py
+++ b/python_files/tests/pytestadapter/expected_execution_test_output.py
@@ -20,9 +20,7 @@
test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
test_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py"
uf_execution_expected_output = {
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
),
@@ -31,9 +29,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -80,9 +76,7 @@
test_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
uf_single_file_expected_output = {
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_negative_numbers", test_add_path
),
@@ -91,9 +85,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -111,9 +103,7 @@
# β βββ TestAddFunction
# β βββ test_add_positive_numbers: success
uf_single_method_execution_expected_output = {
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -149,9 +139,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
- ): {
+ get_absolute_test_id(f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path): {
"test": get_absolute_test_id(
f"{TEST_ADD_FUNCTION}test_add_positive_numbers", test_add_path
),
@@ -252,35 +240,27 @@
"subtest": None,
},
get_absolute_test_id("skip_tests.py::test_another_thing", skip_tests_path): {
- "test": get_absolute_test_id(
- "skip_tests.py::test_another_thing", skip_tests_path
- ),
+ "test": get_absolute_test_id("skip_tests.py::test_another_thing", skip_tests_path),
"outcome": "skipped",
"message": None,
"traceback": None,
"subtest": None,
},
get_absolute_test_id("skip_tests.py::test_decorator_thing", skip_tests_path): {
- "test": get_absolute_test_id(
- "skip_tests.py::test_decorator_thing", skip_tests_path
- ),
+ "test": get_absolute_test_id("skip_tests.py::test_decorator_thing", skip_tests_path),
"outcome": "skipped",
"message": None,
"traceback": None,
"subtest": None,
},
get_absolute_test_id("skip_tests.py::test_decorator_thing_2", skip_tests_path): {
- "test": get_absolute_test_id(
- "skip_tests.py::test_decorator_thing_2", skip_tests_path
- ),
+ "test": get_absolute_test_id("skip_tests.py::test_decorator_thing_2", skip_tests_path),
"outcome": "skipped",
"message": None,
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "skip_tests.py::TestClass::test_class_function_a", skip_tests_path
- ): {
+ get_absolute_test_id("skip_tests.py::TestClass::test_class_function_a", skip_tests_path): {
"test": get_absolute_test_id(
"skip_tests.py::TestClass::test_class_function_a", skip_tests_path
),
@@ -289,9 +269,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "skip_tests.py::TestClass::test_class_function_b", skip_tests_path
- ): {
+ get_absolute_test_id("skip_tests.py::TestClass::test_class_function_b", skip_tests_path): {
"test": get_absolute_test_id(
"skip_tests.py::TestClass::test_class_function_b", skip_tests_path
),
@@ -308,7 +286,7 @@
# βββ test_top_folder.py
# βββ test_top_function_t: success
# βββ test_top_function_f: failure
-# βββ z_nested_folder_one
+# βββ nested_folder_one
# βββ test_bottom_folder.py
# βββ test_bottom_function_t: success
# βββ test_bottom_function_f: failure
@@ -316,10 +294,7 @@
TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
)
dual_level_nested_folder_bottom_path = (
- TEST_DATA_PATH
- / "dual_level_nested_folder"
- / "z_nested_folder_one"
- / "test_bottom_folder.py"
+ TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py"
)
dual_level_nested_folder_execution_expected_output = {
get_absolute_test_id(
@@ -345,11 +320,11 @@
"subtest": None,
},
get_absolute_test_id(
- "z_nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
+ "nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
dual_level_nested_folder_bottom_path,
): {
"test": get_absolute_test_id(
- "z_nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
+ "nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
dual_level_nested_folder_bottom_path,
),
"outcome": "success",
@@ -358,11 +333,11 @@
"subtest": None,
},
get_absolute_test_id(
- "z_nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
+ "nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
dual_level_nested_folder_bottom_path,
): {
"test": get_absolute_test_id(
- "z_nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
+ "nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
dual_level_nested_folder_bottom_path,
),
"outcome": "failure",
@@ -379,9 +354,7 @@
# βββ test_nest.py
# βββ test_function: success
-nested_folder_path = (
- TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py"
-)
+nested_folder_path = TEST_DATA_PATH / "folder_a" / "folder_b" / "folder_a" / "test_nest.py"
double_nested_folder_expected_execution_output = {
get_absolute_test_id(
"folder_a/folder_b/folder_a/test_nest.py::test_function", nested_folder_path
@@ -397,6 +370,7 @@
}
# This is the expected output for the nested_folder tests.
# βββ parametrize_tests.py
+# βββ TestClass
# βββ test_adding[3+5-8]: success
# βββ test_adding[2+4-6]: success
# βββ test_adding[6+9-16]: failure
@@ -404,10 +378,10 @@
parametrize_tests_expected_execution_output = {
get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]", parametrize_tests_path
): {
"test": get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]", parametrize_tests_path
),
"outcome": "success",
"message": None,
@@ -415,10 +389,10 @@
"subtest": None,
},
get_absolute_test_id(
- "parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[2+4-6]", parametrize_tests_path
): {
"test": get_absolute_test_id(
- "parametrize_tests.py::test_adding[2+4-6]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[2+4-6]", parametrize_tests_path
),
"outcome": "success",
"message": None,
@@ -426,10 +400,10 @@
"subtest": None,
},
get_absolute_test_id(
- "parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[6+9-16]", parametrize_tests_path
): {
"test": get_absolute_test_id(
- "parametrize_tests.py::test_adding[6+9-16]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[6+9-16]", parametrize_tests_path
),
"outcome": "failure",
"message": "ERROR MESSAGE",
@@ -440,13 +414,14 @@
# This is the expected output for the single parameterized tests.
# βββ parametrize_tests.py
+# βββ TestClass
# βββ test_adding[3+5-8]: success
single_parametrize_tests_expected_execution_output = {
get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]", parametrize_tests_path
): {
"test": get_absolute_test_id(
- "parametrize_tests.py::test_adding[3+5-8]", parametrize_tests_path
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]", parametrize_tests_path
),
"outcome": "success",
"message": None,
@@ -461,9 +436,7 @@
doc_test_path = TEST_DATA_PATH / "text_docstring.txt"
doctest_pytest_expected_execution_output = {
get_absolute_test_id("text_docstring.txt::text_docstring.txt", doc_test_path): {
- "test": get_absolute_test_id(
- "text_docstring.txt::text_docstring.txt", doc_test_path
- ),
+ "test": get_absolute_test_id("text_docstring.txt::text_docstring.txt", doc_test_path),
"outcome": "success",
"message": None,
"traceback": None,
@@ -477,10 +450,7 @@
TEST_DATA_PATH / "dual_level_nested_folder" / "test_top_folder.py"
)
dual_level_nested_folder_bottom_path = (
- TEST_DATA_PATH
- / "dual_level_nested_folder"
- / "z_nested_folder_one"
- / "test_bottom_folder.py"
+ TEST_DATA_PATH / "dual_level_nested_folder" / "nested_folder_one" / "test_bottom_folder.py"
)
unittest_folder_add_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
unittest_folder_subtract_path = TEST_DATA_PATH / "unittest_folder" / "test_subtract.py"
@@ -494,26 +464,20 @@
"subtest": None,
},
get_absolute_test_id("test_top_function_t", dual_level_nested_folder_top_path): {
- "test": get_absolute_test_id(
- "test_top_function_t", dual_level_nested_folder_top_path
- ),
+ "test": get_absolute_test_id("test_top_function_t", dual_level_nested_folder_top_path),
"outcome": "success",
"message": None,
"traceback": None,
"subtest": None,
},
get_absolute_test_id("test_top_function_f", dual_level_nested_folder_top_path): {
- "test": get_absolute_test_id(
- "test_top_function_f", dual_level_nested_folder_top_path
- ),
+ "test": get_absolute_test_id("test_top_function_f", dual_level_nested_folder_top_path),
"outcome": "failure",
"message": "ERROR MESSAGE",
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "test_bottom_function_t", dual_level_nested_folder_bottom_path
- ): {
+ get_absolute_test_id("test_bottom_function_t", dual_level_nested_folder_bottom_path): {
"test": get_absolute_test_id(
"test_bottom_function_t", dual_level_nested_folder_bottom_path
),
@@ -522,9 +486,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "test_bottom_function_f", dual_level_nested_folder_bottom_path
- ): {
+ get_absolute_test_id("test_bottom_function_f", dual_level_nested_folder_bottom_path): {
"test": get_absolute_test_id(
"test_bottom_function_f", dual_level_nested_folder_bottom_path
),
@@ -533,9 +495,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "TestAddFunction::test_add_negative_numbers", unittest_folder_add_path
- ): {
+ get_absolute_test_id("TestAddFunction::test_add_negative_numbers", unittest_folder_add_path): {
"test": get_absolute_test_id(
"TestAddFunction::test_add_negative_numbers", unittest_folder_add_path
),
@@ -544,9 +504,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "TestAddFunction::test_add_positive_numbers", unittest_folder_add_path
- ): {
+ get_absolute_test_id("TestAddFunction::test_add_positive_numbers", unittest_folder_add_path): {
"test": get_absolute_test_id(
"TestAddFunction::test_add_positive_numbers", unittest_folder_add_path
),
@@ -606,18 +564,14 @@
logging_test_expected_execution_output = {
get_absolute_test_id("test_logging.py::test_logging2", test_logging_path): {
- "test": get_absolute_test_id(
- "test_logging.py::test_logging2", test_logging_path
- ),
+ "test": get_absolute_test_id("test_logging.py::test_logging2", test_logging_path),
"outcome": "failure",
"message": "ERROR MESSAGE",
"traceback": None,
"subtest": None,
},
get_absolute_test_id("test_logging.py::test_logging", test_logging_path): {
- "test": get_absolute_test_id(
- "test_logging.py::test_logging", test_logging_path
- ),
+ "test": get_absolute_test_id("test_logging.py::test_logging", test_logging_path),
"outcome": "success",
"message": None,
"traceback": None,
@@ -632,9 +586,7 @@
test_safe_clear_env_vars_path = TEST_DATA_PATH / "test_env_vars.py"
safe_clear_env_vars_expected_execution_output = {
- get_absolute_test_id(
- "test_env_vars.py::test_clear_env", test_safe_clear_env_vars_path
- ): {
+ get_absolute_test_id("test_env_vars.py::test_clear_env", test_safe_clear_env_vars_path): {
"test": get_absolute_test_id(
"test_env_vars.py::test_clear_env", test_safe_clear_env_vars_path
),
@@ -643,9 +595,7 @@
"traceback": None,
"subtest": None,
},
- get_absolute_test_id(
- "test_env_vars.py::test_check_env", test_safe_clear_env_vars_path
- ): {
+ get_absolute_test_id("test_env_vars.py::test_check_env", test_safe_clear_env_vars_path): {
"test": get_absolute_test_id(
"test_env_vars.py::test_check_env", test_safe_clear_env_vars_path
),
@@ -684,3 +634,116 @@
"subtest": None,
},
}
+
+# Constant for the symlink execution test where TEST_DATA_PATH / "root" the target and TEST_DATA_PATH / "symlink_folder" the symlink
+test_a_symlink_path = TEST_DATA_PATH / "symlink_folder" / "tests" / "test_a.py"
+symlink_run_expected_execution_output = {
+ get_absolute_test_id("test_a.py::test_a_function", test_a_symlink_path): {
+ "test": get_absolute_test_id("test_a.py::test_a_function", test_a_symlink_path),
+ "outcome": "success",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ }
+}
+
+
+# This is the expected output for the pytest_describe_plugin/describe_only.py file.
+# βββ pytest_describe_plugin
+# βββ describe_only.py
+# βββ describe_A
+# βββ test_1: success
+# βββ test_2: success
+
+describe_only_expected_execution_output = {
+ get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_1",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "describe_only.py",
+ ): {
+ "test": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_1",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "describe_only.py",
+ ),
+ "outcome": "success",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ },
+ get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_2",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "describe_only.py",
+ ): {
+ "test": get_absolute_test_id(
+ "pytest_describe_plugin/describe_only.py::describe_A::test_2",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "describe_only.py",
+ ),
+ "outcome": "success",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ },
+}
+
+# This is the expected output for the pytest_describe_plugin/nested_describe.py file.
+# βββ pytest_describe_plugin
+# βββ nested_describe.py
+# βββ describe_list
+# βββ describe_append
+# βββ add_empty: success
+# βββ remove_empty: success
+# βββ describe_remove
+# βββ removes: success
+nested_describe_expected_execution_output = {
+ get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::add_empty",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py",
+ ): {
+ "test": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::add_empty",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py",
+ ),
+ "outcome": "success",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ },
+ get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::remove_empty",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py",
+ ): {
+ "test": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::remove_empty",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py",
+ ),
+ "outcome": "success",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ },
+ get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_remove::removes",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py",
+ ): {
+ "test": get_absolute_test_id(
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_remove::removes",
+ TEST_DATA_PATH / "pytest_describe_plugin" / "nested_describe.py",
+ ),
+ "outcome": "success",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ },
+}
+
+skip_test_fixture_path = TEST_DATA_PATH / "skip_test_fixture.py"
+skip_test_fixture_execution_expected_output = {
+ get_absolute_test_id("skip_test_fixture.py::test_docker_client", skip_test_fixture_path): {
+ "test": get_absolute_test_id(
+ "skip_test_fixture.py::test_docker_client", skip_test_fixture_path
+ ),
+ "outcome": "skipped",
+ "message": None,
+ "traceback": None,
+ "subtest": None,
+ }
+}
diff --git a/python_files/tests/pytestadapter/helpers.py b/python_files/tests/pytestadapter/helpers.py
new file mode 100644
index 000000000000..03f1187149df
--- /dev/null
+++ b/python_files/tests/pytestadapter/helpers.py
@@ -0,0 +1,469 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import contextlib
+import io
+import json
+import os
+import pathlib
+import socket
+import subprocess
+import sys
+import tempfile
+import threading
+import uuid
+from typing import Any, Dict, List, Optional, Tuple
+
+if sys.platform == "win32":
+ from namedpipe import NPopen
+
+
+script_dir = pathlib.Path(__file__).parent.parent.parent
+script_dir_child = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
+sys.path.append(os.fspath(script_dir_child))
+sys.path.append(os.fspath(script_dir / "lib" / "python"))
+print("sys add path", script_dir)
+
+TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
+CONTENT_LENGTH: str = "Content-Length:"
+CONTENT_TYPE: str = "Content-Type:"
+
+
+@contextlib.contextmanager
+def text_to_python_file(text_file_path: pathlib.Path):
+ """Convert a text file to a python file and yield the python file path."""
+ python_file = None
+ try:
+ contents = text_file_path.read_text(encoding="utf-8")
+ python_file = text_file_path.with_suffix(".py")
+ python_file.write_text(contents, encoding="utf-8")
+ yield python_file
+ finally:
+ if python_file:
+ python_file.unlink()
+
+
+@contextlib.contextmanager
+def create_symlink(root: pathlib.Path, target_ext: str, destination_ext: str):
+ destination = None
+ try:
+ destination = root / destination_ext
+ target = root / target_ext
+ if destination and destination.exists():
+ print("destination already exists", destination)
+ try:
+ destination.symlink_to(target)
+ except Exception as e:
+ print("error occurred when attempting to create a symlink", e)
+ yield target, destination
+ finally:
+ if destination and destination.exists():
+ destination.unlink()
+ print("destination unlinked", destination)
+
+
+def process_data_received(data: str) -> List[Dict[str, Any]]:
+ """Process the all JSON data which comes from the server.
+
+ After listen is finished, this function will be called.
+ Here the data must be split into individual JSON messages and then parsed.
+
+ This function also:
+ - Checks that the jsonrpc value is 2.0
+ """
+ json_messages = []
+ remaining = data
+ while remaining:
+ json_data, remaining = parse_rpc_message(remaining)
+ # here json_data is a single rpc payload, now check its jsonrpc 2 and save the param data
+ if "params" not in json_data or "jsonrpc" not in json_data:
+ raise ValueError("Invalid JSON-RPC message received, missing params or jsonrpc key")
+ elif json_data["jsonrpc"] != "2.0":
+ raise ValueError("Invalid JSON-RPC version received, not version 2.0")
+ else:
+ json_messages.append(json_data["params"])
+
+ return json_messages # return the list of json messages
+
+
+def parse_rpc_message(data: str) -> Tuple[Dict[str, str], str]:
+ """Process the JSON data which comes from the server.
+
+ A single rpc payload is in the format:
+ content-length: #LEN# \r\ncontent-type: application/json\r\n\r\n{"jsonrpc": "2.0", "params": ENTIRE_DATA}
+
+ returns:
+ json_data: A single rpc payload of JSON data from the server.
+ remaining: The remaining data after the JSON data.
+ """
+ str_stream: io.StringIO = io.StringIO(data)
+
+ length: int = 0
+ while True:
+ line: str = str_stream.readline()
+ if CONTENT_LENGTH.lower() in line.lower():
+ length = int(line[len(CONTENT_LENGTH) :])
+
+ line: str = str_stream.readline()
+ if CONTENT_TYPE.lower() not in line.lower():
+ raise ValueError("Header does not contain Content-Type")
+
+ line = str_stream.readline()
+ if line not in ["\r\n", "\n"]:
+ raise ValueError("Header does not contain space to separate header and body")
+ # if it passes all these checks then it has the right headers
+ break
+
+ if not line or line.isspace():
+ raise ValueError("Header does not contain Content-Length")
+
+ while True: # keep reading until the number of bytes is the CONTENT_LENGTH
+ line: str = str_stream.readline(length)
+ try:
+ # try to parse the json, if successful it is single payload so return with remaining data
+ json_data: dict[str, str] = json.loads(line)
+ return json_data, str_stream.read()
+ except json.JSONDecodeError:
+ print("json decode error")
+
+
+def _listen_on_fifo(pipe_name: str, result: List[str], completed: threading.Event):
+ # Open the FIFO for reading
+ fifo_path = pathlib.Path(pipe_name)
+ with fifo_path.open() as fifo:
+ print("Waiting for data...")
+ while True:
+ if completed.is_set():
+ break # Exit loop if completed event is set
+ data = fifo.read() # This will block until data is available
+ if len(data) == 0:
+ # If data is empty, assume EOF
+ break
+ print(f"Received: {data}")
+ result.append(data)
+
+
+def _listen_on_pipe_new(listener, result: List[str], completed: threading.Event):
+ """Listen on the named pipe or Unix domain socket for JSON data from the server.
+
+ Created as a separate function for clarity in threading context.
+ """
+ # Windows design
+ if sys.platform == "win32":
+ all_data: list = []
+ stream = listener.wait()
+ while True:
+ # Read data from collection
+ close = stream.closed
+ if close:
+ break
+ data = stream.readlines()
+ if not data:
+ if completed.is_set():
+ break # Exit loop if completed event is set
+ else:
+ try:
+ # Attempt to accept another connection if the current one closes unexpectedly
+ print("attempt another connection")
+ except socket.timeout:
+ # On timeout, append all collected data to result and return
+ # result.append("".join(all_data))
+ return
+ data_decoded = "".join(data)
+ all_data.append(data_decoded)
+ # Append all collected data to result array
+ result.append("".join(all_data))
+ else: # Unix design
+ connection, _ = listener.socket.accept()
+ listener.socket.settimeout(1)
+ all_data: list = []
+ while True:
+ # Reading from connection
+ data: bytes = connection.recv(1024 * 1024)
+ if not data:
+ if completed.is_set():
+ break # Exit loop if completed event is set
+ else:
+ try:
+ # Attempt to accept another connection if the current one closes unexpectedly
+ connection, _ = listener.socket.accept()
+ except socket.timeout:
+ # On timeout, append all collected data to result and return
+ result.append("".join(all_data))
+ return
+ all_data.append(data.decode("utf-8"))
+ # Append all collected data to result array
+ result.append("".join(all_data))
+
+
+def _run_test_code(proc_args: List[str], proc_env, proc_cwd: str, completed: threading.Event):
+ result = subprocess.run(proc_args, env=proc_env, cwd=proc_cwd)
+ completed.set()
+ return result
+
+
+def runner(args: List[str]) -> Optional[List[Dict[str, Any]]]:
+ """Run a subprocess and a named-pipe to listen for messages at the same time with threading."""
+ print("\n Running python test subprocess with cwd set to: ", TEST_DATA_PATH)
+ return runner_with_cwd(args, TEST_DATA_PATH)
+
+
+def runner_with_cwd(args: List[str], path: pathlib.Path) -> Optional[List[Dict[str, Any]]]:
+ """Run a subprocess and a named-pipe to listen for messages at the same time with threading."""
+ return runner_with_cwd_env(args, path, {})
+
+
+def split_array_at_item(arr: List[str], item: str) -> Tuple[List[str], List[str]]:
+ """
+ Splits an array into two subarrays at the specified item.
+
+ Args:
+ arr (List[str]): The array to be split.
+ item (str): The item at which to split the array.
+
+ Returns:
+ Tuple[List[str], List[str]]: A tuple containing two subarrays. The first subarray includes the item and all elements before it. The second subarray includes all elements after the item. If the item is not found, the first subarray is the original array and the second subarray is empty.
+ """
+ if item in arr:
+ index = arr.index(item)
+ before = arr[: index + 1]
+ after = arr[index + 1 :]
+ return before, after
+ else:
+ return arr, []
+
+
+def runner_with_cwd_env(
+ args: List[str], path: pathlib.Path, env_add: Dict[str, str]
+) -> Optional[List[Dict[str, Any]]]:
+ """
+ Run a subprocess and a named-pipe to listen for messages at the same time with threading.
+
+ Includes environment variables to add to the test environment.
+ """
+ process_args: List[str]
+ pipe_name: str
+ if "MANAGE_PY_PATH" in env_add and "COVERAGE_ENABLED" not in env_add:
+ # If we are running Django, generate a unittest-specific pipe name.
+ process_args = [sys.executable, *args]
+ pipe_name = generate_random_pipe_name("unittest-discovery-test")
+ elif "_TEST_VAR_UNITTEST" in env_add:
+ before_args, after_ids = split_array_at_item(args, "*test*.py")
+ process_args = [sys.executable, *before_args]
+ pipe_name = generate_random_pipe_name("unittest-execution-test")
+ test_ids_pipe = os.fspath(
+ script_dir / "tests" / "unittestadapter" / ".data" / "coverage_ex" / "10943021.txt"
+ )
+ env_add.update({"RUN_TEST_IDS_PIPE": test_ids_pipe})
+ test_ids_arr = after_ids
+ with open(test_ids_pipe, "w") as f: # noqa: PTH123
+ f.write("\n".join(test_ids_arr))
+ else:
+ process_args = [sys.executable, "-m", "pytest", "-p", "vscode_pytest", "-s", *args]
+ pipe_name = generate_random_pipe_name("pytest-discovery-test")
+
+ if "COVERAGE_ENABLED" in env_add and "_TEST_VAR_UNITTEST" not in env_add:
+ if "_PYTEST_MANUAL_PLUGIN_LOAD" in env_add:
+ # Test manual plugin loading scenario for issue #25590
+ process_args = [
+ sys.executable,
+ "-m",
+ "pytest",
+ "--disable-plugin-autoload",
+ "-p",
+ "pytest_cov.plugin",
+ "-p",
+ "vscode_pytest",
+ "--cov=.",
+ "--cov-branch",
+ "-s",
+ *args,
+ ]
+ else:
+ process_args = [
+ sys.executable,
+ "-m",
+ "pytest",
+ "-p",
+ "vscode_pytest",
+ "--cov=.",
+ "--cov-branch",
+ "-s",
+ *args,
+ ]
+
+ # Generate pipe name, pipe name specific per OS type.
+
+ # Windows design
+ if sys.platform == "win32":
+ with NPopen("r+t", name=pipe_name, bufsize=0) as pipe:
+ # Update the environment with the pipe name and PYTHONPATH.
+ env = os.environ.copy()
+ env.update(
+ {
+ "TEST_RUN_PIPE": pipe.path,
+ "PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
+ }
+ )
+ # if additional environment variables are passed, add them to the environment
+ if env_add:
+ env.update(env_add)
+
+ completed = threading.Event()
+
+ result = [] # result is a string array to store the data during threading
+ t1: threading.Thread = threading.Thread(
+ target=_listen_on_pipe_new, args=(pipe, result, completed)
+ )
+ t1.start()
+
+ t2 = threading.Thread(
+ target=_run_test_code,
+ args=(process_args, env, path, completed),
+ )
+ t2.start()
+
+ t1.join()
+ t2.join()
+
+ return process_data_received(result[0]) if result else None
+ else: # Unix design
+ # Update the environment with the pipe name and PYTHONPATH.
+ env = os.environ.copy()
+ env.update(
+ {
+ "TEST_RUN_PIPE": pipe_name,
+ "PYTHONPATH": os.fspath(pathlib.Path(__file__).parent.parent.parent),
+ }
+ )
+ # if additional environment variables are passed, add them to the environment
+ if env_add:
+ env.update(env_add)
+ # server = UnixPipeServer(pipe_name)
+ # server.start()
+ #################
+ # Create the FIFO (named pipe) if it doesn't exist
+ # if not pathlib.Path.exists(pipe_name):
+ os.mkfifo(pipe_name)
+ #################
+
+ completed = threading.Event()
+
+ result = [] # result is a string array to store the data during threading
+ t1: threading.Thread = threading.Thread(
+ target=_listen_on_fifo, args=(pipe_name, result, completed)
+ )
+ t1.start()
+
+ t2: threading.Thread = threading.Thread(
+ target=_run_test_code,
+ args=(process_args, env, path, completed),
+ )
+
+ t2.start()
+
+ t1.join()
+ t2.join()
+
+ return process_data_received(result[0]) if result else None
+
+
+def find_test_line_number(test_name: str, test_file_path) -> str:
+ """Function which finds the correct line number for a test by looking for the "test_marker--[test_name]" string.
+
+ The test_name is split on the "[" character to remove the parameterization information.
+
+ Args:
+ test_name: The name of the test to find the line number for, will be unique per file.
+ test_file_path: The path to the test file where the test is located.
+ """
+ test_file_unique_id: str = "test_marker--" + test_name.split("[")[0]
+ with open(test_file_path) as f: # noqa: PTH123
+ for i, line in enumerate(f):
+ if test_file_unique_id in line:
+ return str(i + 1)
+ error_str: str = f"Test {test_name!r} not found on any line in {test_file_path}"
+ raise ValueError(error_str)
+
+
+def find_class_line_number(class_name: str, test_file_path) -> str:
+ """Function which finds the correct line number for a class definition.
+
+ Args:
+ class_name: The name of the class to find the line number for.
+ test_file_path: The path to the test file where the class is located.
+ """
+ # Look for the class definition line (or function for pytest-describe)
+ with open(test_file_path) as f: # noqa: PTH123
+ for i, line in enumerate(f):
+ # Match "class ClassName" or "class ClassName(" or "class ClassName:"
+ # Also match "def ClassName(" for pytest-describe blocks
+ if (
+ line.strip().startswith(f"class {class_name}")
+ or line.strip().startswith(f"class {class_name}(")
+ or line.strip().startswith(f"def {class_name}(")
+ ):
+ return str(i + 1)
+ error_str: str = f"Class {class_name!r} not found on any line in {test_file_path}"
+ raise ValueError(error_str)
+
+
+def get_absolute_test_id(test_id: str, test_path: pathlib.Path) -> str:
+ """Get the absolute test id by joining the testPath with the test_id."""
+ split_id = test_id.split("::")[1:]
+ return "::".join([str(test_path), *split_id])
+
+
+def generate_random_pipe_name(prefix=""):
+ # Generate a random suffix using UUID4, ensuring uniqueness.
+ random_suffix = uuid.uuid4().hex[:10]
+ # Default prefix if not provided.
+ if not prefix:
+ prefix = "python-ext-rpc"
+
+ # For Windows, named pipes have a specific naming convention.
+ if sys.platform == "win32":
+ return f"\\\\.\\pipe\\{prefix}-{random_suffix}"
+
+ # For Unix-like systems, use either the XDG_RUNTIME_DIR or a temporary directory.
+ xdg_runtime_dir = os.getenv("XDG_RUNTIME_DIR")
+ if xdg_runtime_dir:
+ return os.path.join(xdg_runtime_dir, f"{prefix}-{random_suffix}") # noqa: PTH118
+ else:
+ return os.path.join(tempfile.gettempdir(), f"{prefix}-{random_suffix}") # noqa: PTH118
+
+
+class UnixPipeServer:
+ def __init__(self, name):
+ self.name = name
+ self.is_windows = sys.platform == "win32"
+ if self.is_windows:
+ raise NotImplementedError(
+ "This class is only intended for Unix-like systems, not Windows."
+ )
+ else:
+ # For Unix-like systems, use a Unix domain socket.
+ self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ # Ensure the socket does not already exist
+ try:
+ os.unlink(self.name) # noqa: PTH108
+ except OSError:
+ if os.path.exists(self.name): # noqa: PTH110
+ raise
+
+ def start(self):
+ if self.is_windows:
+ raise NotImplementedError(
+ "This class is only intended for Unix-like systems, not Windows."
+ )
+ else:
+ # Bind the socket to the address and listen for incoming connections.
+ self.socket.bind(self.name)
+ self.socket.listen(1)
+ print(f"Server listening on {self.name}")
+
+ def stop(self):
+ # Clean up the server socket.
+ self.socket.close()
+ print("Server stopped.")
diff --git a/python_files/tests/pytestadapter/test_coverage.py b/python_files/tests/pytestadapter/test_coverage.py
new file mode 100644
index 000000000000..f2387527698f
--- /dev/null
+++ b/python_files/tests/pytestadapter/test_coverage.py
@@ -0,0 +1,164 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import json
+import os
+import pathlib
+import sys
+
+import coverage
+import pytest
+from packaging.version import Version
+
+script_dir = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
+
+from .helpers import ( # noqa: E402
+ TEST_DATA_PATH,
+ runner_with_cwd_env,
+)
+
+
+def test_simple_pytest_coverage():
+ """
+ Test coverage payload is correct for simple pytest example. Output of coverage run is below.
+
+ Name Stmts Miss Branch BrPart Cover
+ ---------------------------------------------------
+ __init__.py 0 0 0 0 100%
+ reverse.py 13 3 8 2 76%
+ test_reverse.py 11 0 0 0 100%
+ ---------------------------------------------------
+ TOTAL 24 3 8 2 84%
+
+ """
+ args = []
+ env_add = {"COVERAGE_ENABLED": "True"}
+ cov_folder_path = TEST_DATA_PATH / "coverage_gen"
+ actual = runner_with_cwd_env(args, cov_folder_path, env_add)
+ assert actual
+ cov = actual[-1]
+ assert cov
+ results = cov["result"]
+ assert results
+ assert len(results) == 3
+ focal_function_coverage = results.get(os.fspath(TEST_DATA_PATH / "coverage_gen" / "reverse.py"))
+ assert focal_function_coverage
+ assert focal_function_coverage.get("lines_covered") is not None
+ assert focal_function_coverage.get("lines_missed") is not None
+ assert set(focal_function_coverage.get("lines_covered")) == {4, 5, 7, 9, 10, 11, 12, 13, 14, 17}
+ assert len(set(focal_function_coverage.get("lines_missed"))) >= 3
+
+ coverage_version = Version(coverage.__version__)
+ # only include check for branches if the version is >= 7.7.0
+ if coverage_version >= Version("7.7.0"):
+ assert focal_function_coverage.get("executed_branches") == 4
+ assert focal_function_coverage.get("total_branches") == 6
+
+
+coverage_gen_file_path = TEST_DATA_PATH / "coverage_gen" / "coverage.json"
+
+
+@pytest.fixture
+def cleanup_coverage_gen_file():
+ # delete the coverage file if it exists as part of test cleanup
+ yield
+ if os.path.exists(coverage_gen_file_path): # noqa: PTH110
+ os.remove(coverage_gen_file_path) # noqa: PTH107
+
+
+def test_coverage_gen_report(cleanup_coverage_gen_file): # noqa: ARG001
+ """
+ Test coverage payload is correct for simple pytest example. Output of coverage run is below.
+
+ Name Stmts Miss Branch BrPart Cover
+ ---------------------------------------------------
+ __init__.py 0 0 0 0 100%
+ reverse.py 13 3 8 2 76%
+ test_reverse.py 11 0 0 0 100%
+ ---------------------------------------------------
+ TOTAL 24 3 8 2 84%
+
+ """
+ args = ["--cov-report=json"]
+ env_add = {"COVERAGE_ENABLED": "True"}
+ cov_folder_path = TEST_DATA_PATH / "coverage_gen"
+ print("cov_folder_path", cov_folder_path)
+ actual = runner_with_cwd_env(args, cov_folder_path, env_add)
+ assert actual
+ cov = actual[-1]
+ assert cov
+ results = cov["result"]
+ assert results
+ assert len(results) == 3
+ focal_function_coverage = results.get(os.fspath(TEST_DATA_PATH / "coverage_gen" / "reverse.py"))
+ assert focal_function_coverage
+ assert focal_function_coverage.get("lines_covered") is not None
+ assert focal_function_coverage.get("lines_missed") is not None
+ assert set(focal_function_coverage.get("lines_covered")) == {4, 5, 7, 9, 10, 11, 12, 13, 14, 17}
+ assert set(focal_function_coverage.get("lines_missed")) == {18, 19, 6}
+ coverage_version = Version(coverage.__version__)
+ # only include check for branches if the version is >= 7.7.0
+ if coverage_version >= Version("7.7.0"):
+ assert focal_function_coverage.get("executed_branches") == 4
+ assert focal_function_coverage.get("total_branches") == 6
+ # assert that the coverage file was created at the right path
+ assert os.path.exists(coverage_gen_file_path) # noqa: PTH110
+
+
+def test_coverage_w_omit_config():
+ """
+ Test the coverage report generation with omit configuration.
+
+ folder structure of coverage_w_config
+ βββ coverage_w_config
+ β βββ test_ignore.py
+ β βββ test_ran.py
+ β βββ pyproject.toml
+ β βββ tests
+ β β βββ test_disregard.py
+
+ pyproject.toml file with the following content:
+ [tool.coverage.report]
+ omit = [
+ "test_ignore.py",
+ "tests/*.py" (this will ignore the coverage in the file tests/test_disregard.py)
+ ]
+
+
+ Assertions:
+ - The coverage report is generated.
+ - The coverage report contains results.
+ - Only one file is reported in the coverage results.
+ """
+ env_add = {"COVERAGE_ENABLED": "True"}
+ cov_folder_path = TEST_DATA_PATH / "coverage_w_config"
+ print("cov_folder_path", cov_folder_path)
+ actual = runner_with_cwd_env([], cov_folder_path, env_add)
+ assert actual
+ print("actual", json.dumps(actual, indent=2))
+ cov = actual[-1]
+ assert cov
+ results = cov["result"]
+ assert results
+ # assert one file is reported and one file (as specified in pyproject.toml) is omitted
+ assert len(results) == 1
+
+
+def test_pytest_cov_manual_plugin_loading():
+ """
+ Test that pytest-cov is detected when loaded manually via -p pytest_cov.plugin.
+
+ This test verifies the fix for issue #25590, where pytest-cov detection failed
+ when using --disable-plugin-autoload with -p pytest_cov.plugin. The plugin is
+ registered under its module name (pytest_cov.plugin) instead of entry point name
+ (pytest_cov) in this scenario.
+ """
+ args = ["--collect-only"]
+ env_add = {"COVERAGE_ENABLED": "True", "_PYTEST_MANUAL_PLUGIN_LOAD": "True"}
+ cov_folder_path = TEST_DATA_PATH / "coverage_gen"
+
+ # Should NOT raise VSCodePytestError about pytest-cov not being installed
+ actual = runner_with_cwd_env(args, cov_folder_path, env_add)
+ assert actual is not None
+ # Verify discovery succeeded (status != "error")
+ assert actual[0].get("status") != "error"
diff --git a/python_files/tests/pytestadapter/test_discovery.py b/python_files/tests/pytestadapter/test_discovery.py
new file mode 100644
index 000000000000..cf777399fed9
--- /dev/null
+++ b/python_files/tests/pytestadapter/test_discovery.py
@@ -0,0 +1,482 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import json
+import os
+import sys
+from typing import Any, Dict, List, Optional
+
+import pytest
+
+from tests.tree_comparison_helper import is_same_tree
+
+from . import expected_discovery_test_output, helpers
+
+
+def test_import_error():
+ """Test pytest discovery on a file that has a pytest marker but does not import pytest.
+
+ Copies the contents of a .txt file to a .py file in the temporary directory
+ to then run pytest discovery on.
+
+ The json should still be returned but the errors list should be present.
+
+ Keyword arguments:
+ tmp_path -- pytest fixture that creates a temporary directory.
+ """
+ file_path = helpers.TEST_DATA_PATH / "error_pytest_import.txt"
+ with helpers.text_to_python_file(file_path) as p:
+ actual: Optional[List[Dict[str, Any]]] = helpers.runner(["--collect-only", os.fspath(p)])
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ for actual_item in actual_list:
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "error"
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
+
+ # Ensure that 'error' is a list and then check its length
+ error_content = actual_item.get("error")
+ if error_content is not None and isinstance(
+ error_content, (list, tuple, str)
+ ): # You can add other types if needed
+ assert len(error_content) == 2
+ else:
+ pytest.fail(f"{error_content} is None or not a list, str, or tuple")
+
+
+def test_syntax_error(tmp_path): # noqa: ARG001
+ """Test pytest discovery on a file that has a syntax error.
+
+ Copies the contents of a .txt file to a .py file in the temporary directory
+ to then run pytest discovery on.
+
+ The json should still be returned but the errors list should be present.
+
+ Keyword arguments:
+ tmp_path -- pytest fixture that creates a temporary directory.
+ """
+ # Saving some files as .txt to avoid that file displaying a syntax error for
+ # the extension as a whole. Instead, rename it before running this test
+ # in order to test the error handling.
+ file_path = helpers.TEST_DATA_PATH / "error_syntax_discovery.txt"
+ with helpers.text_to_python_file(file_path) as p:
+ actual = helpers.runner(["--collect-only", os.fspath(p)])
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ for actual_item in actual_list:
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "error"
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
+
+ # Ensure that 'error' is a list and then check its length
+ error_content = actual_item.get("error")
+ if error_content is not None and isinstance(
+ error_content, (list, tuple, str)
+ ): # You can add other types if needed
+ assert len(error_content) == 2
+ else:
+ pytest.fail(f"{error_content} is None or not a list, str, or tuple")
+
+
+def test_parameterized_error_collect():
+ """Tests pytest discovery on specific file that incorrectly uses parametrize.
+
+ The json should still be returned but the errors list should be present.
+ """
+ file_path_str = "error_parametrize_discovery.py"
+ actual = helpers.runner(["--collect-only", file_path_str])
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ for actual_item in actual_list:
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "error"
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
+
+ # Ensure that 'error' is a list and then check its length
+ error_content = actual_item.get("error")
+ if error_content is not None and isinstance(
+ error_content, (list, tuple, str)
+ ): # You can add other types if needed
+ assert len(error_content) == 2
+ else:
+ pytest.fail(f"{error_content} is None or not a list, str, or tuple")
+
+
+@pytest.mark.parametrize(
+ ("file", "expected_const"),
+ [
+ (
+ "test_param_span_class.py",
+ expected_discovery_test_output.test_param_span_class_expected_output,
+ ),
+ (
+ "test_multi_class_nest.py",
+ expected_discovery_test_output.nested_classes_expected_test_output,
+ ),
+ (
+ "same_function_new_class_param.py",
+ expected_discovery_test_output.same_function_new_class_param_expected_output,
+ ),
+ (
+ "unittest_skiptest_file_level.py",
+ expected_discovery_test_output.unittest_skip_file_level_expected_output,
+ ),
+ (
+ "param_same_name",
+ expected_discovery_test_output.param_same_name_expected_output,
+ ),
+ (
+ "parametrize_tests.py",
+ expected_discovery_test_output.parametrize_tests_expected_output,
+ ),
+ (
+ "empty_discovery.py",
+ expected_discovery_test_output.empty_discovery_pytest_expected_output,
+ ),
+ (
+ "simple_pytest.py",
+ expected_discovery_test_output.simple_discovery_pytest_expected_output,
+ ),
+ (
+ "unittest_pytest_same_file.py",
+ expected_discovery_test_output.unit_pytest_same_file_discovery_expected_output,
+ ),
+ (
+ "unittest_folder",
+ expected_discovery_test_output.unittest_folder_discovery_expected_output,
+ ),
+ (
+ "dual_level_nested_folder",
+ expected_discovery_test_output.dual_level_nested_folder_expected_output,
+ ),
+ (
+ "folder_a",
+ expected_discovery_test_output.double_nested_folder_expected_output,
+ ),
+ (
+ "text_docstring.txt",
+ expected_discovery_test_output.doctest_pytest_expected_output,
+ ),
+ (
+ "pytest_describe_plugin" + os.path.sep + "describe_only.py",
+ expected_discovery_test_output.expected_describe_only_output,
+ ),
+ (
+ "pytest_describe_plugin" + os.path.sep + "nested_describe.py",
+ expected_discovery_test_output.expected_nested_describe_output,
+ ),
+ ],
+)
+def test_pytest_collect(file, expected_const):
+ """Test to test pytest discovery on a variety of test files/ folder structures.
+
+ Uses variables from expected_discovery_test_output.py to store the expected
+ dictionary return. Only handles discovery and therefore already contains the arg
+ --collect-only. All test discovery will succeed, be in the correct cwd, and match
+ expected test output.
+
+ Keyword arguments:
+ file -- a string with the file or folder to run pytest discovery on.
+ expected_const -- the expected output from running pytest discovery on the file.
+ """
+ actual = helpers.runner(
+ [
+ os.fspath(helpers.TEST_DATA_PATH / file),
+ "--collect-only",
+ ]
+ )
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "success", (
+ f"Status is not 'success', error is: {actual_item.get('error')}"
+ )
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
+ assert is_same_tree(
+ actual_item.get("tests"),
+ expected_const,
+ ["id_", "lineno", "name", "runID"],
+ ), (
+ f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_const, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
+ )
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="See https://stackoverflow.com/questions/32877260/privlege-error-trying-to-create-symlink-using-python-on-windows-10",
+)
+def test_symlink_root_dir():
+ """Test to test pytest discovery with the command line arg --rootdir specified as a symlink path.
+
+ Discovery should succeed and testids should be relative to the symlinked root directory.
+ """
+ with helpers.create_symlink(helpers.TEST_DATA_PATH, "root", "symlink_folder") as (
+ source,
+ destination,
+ ):
+ assert destination.is_symlink()
+
+ # Run pytest with the cwd being the resolved symlink path (as it will be when we run the subprocess from node).
+ actual = helpers.runner_with_cwd(
+ ["--collect-only", f"--rootdir={os.fspath(destination)}"], source
+ )
+ expected = expected_discovery_test_output.symlink_expected_discovery_output
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ try:
+ # Check if all requirements
+ assert all(item in actual_item for item in ("status", "cwd", "error")), (
+ "Required keys are missing"
+ )
+ assert actual_item.get("status") == "success", "Status is not 'success'"
+ assert actual_item.get("cwd") == os.fspath(destination), (
+ f"CWD does not match: {os.fspath(destination)}"
+ )
+ assert actual_item.get("tests") == expected, "Tests do not match expected value"
+ except AssertionError as e:
+ # Print the actual_item in JSON format if an assertion fails
+ print(json.dumps(actual_item, indent=4))
+ pytest.fail(str(e))
+
+
+def test_pytest_root_dir():
+ """Test to test pytest discovery with the command line arg --rootdir specified to be a subfolder of the workspace root.
+
+ Discovery should succeed and testids should be relative to workspace root.
+ """
+ rd = f"--rootdir={helpers.TEST_DATA_PATH / 'root' / 'tests'}"
+ actual = helpers.runner_with_cwd(
+ [
+ "--collect-only",
+ rd,
+ ],
+ helpers.TEST_DATA_PATH / "root",
+ )
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "success"
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH / "root")
+ assert is_same_tree(
+ actual_item.get("tests"),
+ expected_discovery_test_output.root_with_config_expected_output,
+ ["id_", "lineno", "name", "runID"],
+ ), (
+ f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_discovery_test_output.root_with_config_expected_output, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
+ )
+
+
+def test_pytest_config_file():
+ """Test to test pytest discovery with the command line arg -c with a specified config file which changes the workspace root.
+
+ Discovery should succeed and testids should be relative to workspace root.
+ """
+ actual = helpers.runner_with_cwd(
+ [
+ "--collect-only",
+ "tests/",
+ ],
+ helpers.TEST_DATA_PATH / "root",
+ )
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "success"
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH / "root")
+ assert is_same_tree(
+ actual_item.get("tests"),
+ expected_discovery_test_output.root_with_config_expected_output,
+ ["id_", "lineno", "name", "runID"],
+ ), (
+ f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_discovery_test_output.root_with_config_expected_output, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
+ )
+
+
+def test_config_sub_folder():
+ """Here the session node will be a subfolder of the workspace root and the test are in another subfolder.
+
+ This tests checks to see if test node path are under the session node and if so the
+ session node is correctly updated to the common path.
+ """
+ folder_path = helpers.TEST_DATA_PATH / "config_sub_folder"
+ actual = helpers.runner_with_cwd(
+ [
+ "--collect-only",
+ "-c=config/pytest.ini",
+ "--rootdir=config/",
+ "-vv",
+ ],
+ folder_path,
+ )
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "success"
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH / "config_sub_folder")
+ assert actual_item.get("tests") is not None
+ if actual_item.get("tests") is not None:
+ tests: Any = actual_item.get("tests")
+ assert tests.get("name") == "config_sub_folder"
+
+
+@pytest.mark.parametrize(
+ ("file", "expected_const", "extra_arg"),
+ [
+ (
+ "folder_with_script",
+ expected_discovery_test_output.ruff_test_expected_output,
+ "--ruff",
+ ),
+ (
+ "2496-black-formatter",
+ expected_discovery_test_output.black_formatter_expected_output,
+ "--black",
+ ),
+ ],
+)
+def test_plugin_collect(file, expected_const, extra_arg):
+ """Test pytest discovery on a folder with a plugin argument (e.g., --ruff, --black).
+
+ Uses variables from expected_discovery_test_output.py to store the expected
+ dictionary return. Only handles discovery and therefore already contains the arg
+ --collect-only. All test discovery will succeed, be in the correct cwd, and match
+ expected test output.
+
+ Keyword arguments:
+ file -- a string with the file or folder to run pytest discovery on.
+ expected_const -- the expected output from running pytest discovery on the file.
+ extra_arg -- the extra plugin argument to pass (e.g., --ruff, --black)
+ """
+ file_path = helpers.TEST_DATA_PATH / file
+ actual = helpers.runner(
+ [os.fspath(file_path), "--collect-only", extra_arg],
+ )
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "success", (
+ f"Status is not 'success', error is: {actual_item.get('error')}"
+ )
+ assert actual_item.get("cwd") == os.fspath(helpers.TEST_DATA_PATH)
+ assert is_same_tree(
+ actual_item.get("tests"),
+ expected_const,
+ ["id_", "lineno", "name", "runID"],
+ ), (
+ f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_const, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
+ )
+
+
+def test_project_root_path_env_var():
+ """Test pytest discovery with PROJECT_ROOT_PATH environment variable set.
+
+ This simulates project-based testing where the test tree root should be
+ the project root (PROJECT_ROOT_PATH) rather than the workspace cwd.
+
+ When PROJECT_ROOT_PATH is set:
+ - The test tree root (name, path, id_) should match PROJECT_ROOT_PATH
+ - The cwd in the response should match PROJECT_ROOT_PATH
+ - Test files should be direct children of the root (not nested under a subfolder)
+ """
+ # Use unittest_folder as our "project" subdirectory
+ project_path = helpers.TEST_DATA_PATH / "unittest_folder"
+
+ actual = helpers.runner_with_cwd_env(
+ [os.fspath(project_path), "--collect-only"],
+ helpers.TEST_DATA_PATH, # cwd is parent of project
+ {"PROJECT_ROOT_PATH": os.fspath(project_path)}, # Set project root
+ )
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+
+ assert all(item in actual_item for item in ("status", "cwd", "error"))
+ assert actual_item.get("status") == "success", (
+ f"Status is not 'success', error is: {actual_item.get('error')}"
+ )
+ # cwd in response should be PROJECT_ROOT_PATH
+ assert actual_item.get("cwd") == os.fspath(project_path), (
+ f"Expected cwd '{os.fspath(project_path)}', got '{actual_item.get('cwd')}'"
+ )
+ assert is_same_tree(
+ actual_item.get("tests"),
+ expected_discovery_test_output.project_root_unittest_folder_expected_output,
+ ["id_", "lineno", "name", "runID"],
+ ), (
+ f"Tests tree does not match expected value. \n Expected: {json.dumps(expected_discovery_test_output.project_root_unittest_folder_expected_output, indent=4)}. \n Actual: {json.dumps(actual_item.get('tests'), indent=4)}"
+ )
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="Symlinks require elevated privileges on Windows",
+)
+def test_symlink_with_project_root_path():
+ """Test pytest discovery with both symlink and PROJECT_ROOT_PATH set.
+
+ This tests the combination of:
+ 1. A symlinked test directory (--rootdir points to symlink)
+ 2. PROJECT_ROOT_PATH set to the symlink path
+
+ This simulates project-based testing where the project root is a symlink,
+ ensuring test IDs and paths are correctly resolved through the symlink.
+ """
+ with helpers.create_symlink(helpers.TEST_DATA_PATH, "root", "symlink_folder") as (
+ source,
+ destination,
+ ):
+ assert destination.is_symlink()
+
+ # Run pytest with:
+ # - cwd being the resolved symlink path (simulating subprocess from node)
+ # - PROJECT_ROOT_PATH set to the symlink destination
+ actual = helpers.runner_with_cwd_env(
+ ["--collect-only", f"--rootdir={os.fspath(destination)}"],
+ source, # cwd is the resolved (non-symlink) path
+ {"PROJECT_ROOT_PATH": os.fspath(destination)}, # Project root is the symlink
+ )
+
+ expected = expected_discovery_test_output.symlink_expected_discovery_output
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ try:
+ assert all(item in actual_item for item in ("status", "cwd", "error")), (
+ "Required keys are missing"
+ )
+ assert actual_item.get("status") == "success", (
+ f"Status is not 'success', error is: {actual_item.get('error')}"
+ )
+ # cwd should be the PROJECT_ROOT_PATH (the symlink destination)
+ assert actual_item.get("cwd") == os.fspath(destination), (
+ f"CWD does not match symlink path: expected {os.fspath(destination)}, got {actual_item.get('cwd')}"
+ )
+ assert actual_item.get("tests") == expected, "Tests do not match expected value"
+ except AssertionError as e:
+ # Print the actual_item in JSON format if an assertion fails
+ print(json.dumps(actual_item, indent=4))
+ pytest.fail(str(e))
diff --git a/pythonFiles/tests/pytestadapter/test_execution.py b/python_files/tests/pytestadapter/test_execution.py
similarity index 53%
rename from pythonFiles/tests/pytestadapter/test_execution.py
rename to python_files/tests/pytestadapter/test_execution.py
index 767d54a6cabe..95a66e0e7b87 100644
--- a/pythonFiles/tests/pytestadapter/test_execution.py
+++ b/python_files/tests/pytestadapter/test_execution.py
@@ -1,14 +1,25 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
+import json
import os
-import shutil
+import pathlib
+import sys
from typing import Any, Dict, List
import pytest
-from tests.pytestadapter import expected_execution_test_output
+script_dir = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
-from .helpers import TEST_DATA_PATH, runner, runner_with_cwd
+from tests.pytestadapter import expected_execution_test_output # noqa: E402
+
+from .helpers import ( # noqa: E402
+ TEST_DATA_PATH,
+ create_symlink,
+ get_absolute_test_id,
+ runner,
+ runner_with_cwd,
+)
def test_config_file():
@@ -20,19 +31,14 @@ def test_config_file():
]
new_cwd = TEST_DATA_PATH / "root"
actual = runner_with_cwd(args, new_cwd)
- expected_const = (
- expected_execution_test_output.config_file_pytest_expected_execution_output
- )
+ expected_const = expected_execution_test_output.config_file_pytest_expected_execution_output
assert actual
actual_list: List[Dict[str, Any]] = actual
- assert actual_list.pop(-1).get("eot")
assert len(actual_list) == len(expected_const)
- actual_result_dict = dict()
+ actual_result_dict = {}
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "result")
- )
+ assert all(item in actual_item for item in ("status", "cwd", "result"))
assert actual_item.get("status") == "success"
assert actual_item.get("cwd") == os.fspath(new_cwd)
actual_result_dict.update(actual_item["result"])
@@ -45,100 +51,32 @@ def test_rootdir_specified():
args = [rd, "tests/test_a.py::test_a_function"]
new_cwd = TEST_DATA_PATH / "root"
actual = runner_with_cwd(args, new_cwd)
- expected_const = (
- expected_execution_test_output.config_file_pytest_expected_execution_output
- )
+ expected_const = expected_execution_test_output.config_file_pytest_expected_execution_output
assert actual
- actual_list: List[Dict[str, Any]] = actual
- assert actual_list.pop(-1).get("eot")
+ actual_list: List[Dict[str, Dict[str, Any]]] = actual
assert len(actual_list) == len(expected_const)
- actual_result_dict = dict()
+ actual_result_dict = {}
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "result")
- )
+ assert all(item in actual_item for item in ("status", "cwd", "result"))
assert actual_item.get("status") == "success"
assert actual_item.get("cwd") == os.fspath(new_cwd)
actual_result_dict.update(actual_item["result"])
assert actual_result_dict == expected_const
-def test_syntax_error_execution(tmp_path):
- """Test pytest execution on a file that has a syntax error.
-
- Copies the contents of a .txt file to a .py file in the temporary directory
- to then run pytest execution on.
-
- The json should still be returned but the errors list should be present.
-
- Keyword arguments:
- tmp_path -- pytest fixture that creates a temporary directory.
- """
- # Saving some files as .txt to avoid that file displaying a syntax error for
- # the extension as a whole. Instead, rename it before running this test
- # in order to test the error handling.
- file_path = TEST_DATA_PATH / "error_syntax_discovery.txt"
- temp_dir = tmp_path / "temp_data"
- temp_dir.mkdir()
- p = temp_dir / "error_syntax_discovery.py"
- shutil.copyfile(file_path, p)
- actual = runner(["error_syntax_discover.py::test_function"])
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- assert actual_list.pop(-1).get("eot")
- if actual_list is not None:
- for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
- assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
- error_content = actual_item.get("error")
- if error_content is not None and isinstance(
- error_content, (list, tuple, str)
- ): # You can add other types if needed
- assert len(error_content) == 1
- else:
- assert False
-
-
-def test_bad_id_error_execution():
- """Test pytest discovery with a non-existent test_id.
-
- The json should still be returned but the errors list should be present.
- """
- actual = runner(["not/a/real::test_id"])
- assert actual
- actual_list: List[Dict[str, Any]] = actual
- assert actual_list.pop(-1).get("eot")
- if actual_list is not None:
- for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "error")
- )
- assert actual_item.get("status") == "error"
- assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
- error_content = actual_item.get("error")
- if error_content is not None and isinstance(
- error_content, (list, tuple, str)
- ): # You can add other types if needed
- assert len(error_content) == 1
- else:
- assert False
-
-
@pytest.mark.parametrize(
- "test_ids, expected_const",
+ ("test_ids", "expected_const"),
[
- (
+ pytest.param(
[
"test_env_vars.py::test_clear_env",
"test_env_vars.py::test_check_env",
],
expected_execution_test_output.safe_clear_env_vars_expected_execution_output,
+ id="safe_clear_env_vars",
),
- (
+ pytest.param(
[
"skip_tests.py::test_something",
"skip_tests.py::test_another_thing",
@@ -148,12 +86,14 @@ def test_bad_id_error_execution():
"skip_tests.py::TestClass::test_class_function_b",
],
expected_execution_test_output.skip_tests_execution_expected_output,
+ id="skip_tests_execution",
),
- (
+ pytest.param(
["error_raise_exception.py::TestSomething::test_a"],
expected_execution_test_output.error_raised_exception_execution_expected_output,
+ id="error_raised_exception",
),
- (
+ pytest.param(
[
"unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
"unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers",
@@ -161,92 +101,109 @@ def test_bad_id_error_execution():
"unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_negative_numbers",
],
expected_execution_test_output.uf_execution_expected_output,
+ id="unittest_multiple_files",
),
- (
+ pytest.param(
[
"unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
"unittest_folder/test_add.py::TestAddFunction::test_add_negative_numbers",
],
expected_execution_test_output.uf_single_file_expected_output,
+ id="unittest_single_file",
),
- (
+ pytest.param(
[
"unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
],
expected_execution_test_output.uf_single_method_execution_expected_output,
+ id="unittest_single_method",
),
- (
+ pytest.param(
[
"unittest_folder/test_add.py::TestAddFunction::test_add_positive_numbers",
"unittest_folder/test_subtract.py::TestSubtractFunction::test_subtract_positive_numbers",
],
expected_execution_test_output.uf_non_adjacent_tests_execution_expected_output,
+ id="unittest_non_adjacent_tests",
),
- (
+ pytest.param(
[
"unittest_pytest_same_file.py::TestExample::test_true_unittest",
"unittest_pytest_same_file.py::test_true_pytest",
],
expected_execution_test_output.unit_pytest_same_file_execution_expected_output,
+ id="unittest_pytest_same_file",
),
- (
+ pytest.param(
[
"dual_level_nested_folder/test_top_folder.py::test_top_function_t",
"dual_level_nested_folder/test_top_folder.py::test_top_function_f",
- "dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
- "dual_level_nested_folder/z_nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
+ "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_t",
+ "dual_level_nested_folder/nested_folder_one/test_bottom_folder.py::test_bottom_function_f",
],
expected_execution_test_output.dual_level_nested_folder_execution_expected_output,
+ id="dual_level_nested_folder",
),
- (
+ pytest.param(
["folder_a/folder_b/folder_a/test_nest.py::test_function"],
expected_execution_test_output.double_nested_folder_expected_execution_output,
+ id="double_nested_folder",
),
- (
+ pytest.param(
[
- "parametrize_tests.py::test_adding[3+5-8]",
- "parametrize_tests.py::test_adding[2+4-6]",
- "parametrize_tests.py::test_adding[6+9-16]",
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]",
+ "parametrize_tests.py::TestClass::test_adding[2+4-6]",
+ "parametrize_tests.py::TestClass::test_adding[6+9-16]",
],
expected_execution_test_output.parametrize_tests_expected_execution_output,
+ id="parametrize_tests",
),
- (
+ pytest.param(
[
- "parametrize_tests.py::test_adding[3+5-8]",
+ "parametrize_tests.py::TestClass::test_adding[3+5-8]",
],
expected_execution_test_output.single_parametrize_tests_expected_execution_output,
+ id="single_parametrize_test",
),
- (
+ pytest.param(
[
"text_docstring.txt::text_docstring.txt",
],
expected_execution_test_output.doctest_pytest_expected_execution_output,
+ id="doctest_pytest",
),
- (
+ pytest.param(
["test_logging.py::test_logging2", "test_logging.py::test_logging"],
expected_execution_test_output.logging_test_expected_execution_output,
+ id="logging_tests",
+ ),
+ pytest.param(
+ [
+ "pytest_describe_plugin/describe_only.py::describe_A::test_1",
+ "pytest_describe_plugin/describe_only.py::describe_A::test_2",
+ ],
+ expected_execution_test_output.describe_only_expected_execution_output,
+ id="describe_only",
+ ),
+ pytest.param(
+ [
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::add_empty",
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_append::remove_empty",
+ "pytest_describe_plugin/nested_describe.py::describe_list::describe_remove::removes",
+ ],
+ expected_execution_test_output.nested_describe_expected_execution_output,
+ id="nested_describe_plugin",
+ ),
+ pytest.param(
+ ["skip_test_fixture.py::test_docker_client"],
+ expected_execution_test_output.skip_test_fixture_execution_expected_output,
+ id="skip_test_fixture",
),
],
)
def test_pytest_execution(test_ids, expected_const):
"""
- Test that pytest discovery works as expected where run pytest is always successful
- but the actual test results are both successes and failures.:
- 1: skip_tests_execution_expected_output: test run on a file with skipped tests.
- 2. error_raised_exception_execution_expected_output: test run on a file that raises an exception.
- 3. uf_execution_expected_output: unittest tests run on multiple files.
- 4. uf_single_file_expected_output: test run on a single file.
- 5. uf_single_method_execution_expected_output: test run on a single method in a file.
- 6. uf_non_adjacent_tests_execution_expected_output: test run on unittests in two files with single selection in test explorer.
- 7. unit_pytest_same_file_execution_expected_output: test run on a file with both unittest and pytest tests.
- 8. dual_level_nested_folder_execution_expected_output: test run on a file with one test file
- at the top level and one test file in a nested folder.
- 9. double_nested_folder_expected_execution_output: test run on a double nested folder.
- 10. parametrize_tests_expected_execution_output: test run on a parametrize test with 3 inputs.
- 11. single_parametrize_tests_expected_execution_output: test run on single parametrize test.
- 12. doctest_pytest_expected_execution_output: test run on doctest file.
- 13. logging_test_expected_execution_output: test run on a file with logging.
-
+ Test that pytest discovery works as expected where run pytest is always successful, but the actual test results are both successes and failures.
Keyword arguments:
test_ids -- an array of test_ids to run.
@@ -255,15 +212,12 @@ def test_pytest_execution(test_ids, expected_const):
args = test_ids
actual = runner(args)
assert actual
- actual_list: List[Dict[str, Any]] = actual
- assert actual_list.pop(-1).get("eot")
+ actual_list: List[Dict[str, Dict[str, Any]]] = actual
assert len(actual_list) == len(expected_const)
- actual_result_dict = dict()
+ actual_result_dict = {}
if actual_list is not None:
for actual_item in actual_list:
- assert all(
- item in actual_item.keys() for item in ("status", "cwd", "result")
- )
+ assert all(item in actual_item for item in ("status", "cwd", "result"))
assert actual_item.get("status") == "success"
assert actual_item.get("cwd") == os.fspath(TEST_DATA_PATH)
actual_result_dict.update(actual_item["result"])
@@ -276,3 +230,45 @@ def test_pytest_execution(test_ids, expected_const):
if actual_result_dict[key]["traceback"] is not None:
actual_result_dict[key]["traceback"] = "TRACEBACK"
assert actual_result_dict == expected_const
+
+
+def test_symlink_run():
+ """Test to test pytest discovery with the command line arg --rootdir specified as a symlink path.
+
+ Discovery should succeed and testids should be relative to the symlinked root directory.
+ """
+ with create_symlink(TEST_DATA_PATH, "root", "symlink_folder") as (
+ source,
+ destination,
+ ):
+ assert destination.is_symlink()
+ test_a_path = TEST_DATA_PATH / "symlink_folder" / "tests" / "test_a.py"
+ test_a_id = get_absolute_test_id(
+ "tests/test_a.py::test_a_function",
+ test_a_path,
+ )
+
+ # Run pytest with the cwd being the resolved symlink path (as it will be when we run the subprocess from node).
+ actual = runner_with_cwd([f"--rootdir={os.fspath(destination)}", test_a_id], source)
+
+ expected_const = expected_execution_test_output.symlink_run_expected_execution_output
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ try:
+ # Check if all requirements
+ assert all(item in actual_item for item in ("status", "cwd", "result")), (
+ "Required keys are missing"
+ )
+ assert actual_item.get("status") == "success", "Status is not 'success'"
+ assert actual_item.get("cwd") == os.fspath(destination), (
+ f"CWD does not match: {os.fspath(destination)}"
+ )
+ actual_result_dict = {}
+ actual_result_dict.update(actual_item["result"])
+ assert actual_result_dict == expected_const
+ except AssertionError as e:
+ # Print the actual_item in JSON format if an assertion fails
+ print(json.dumps(actual_item, indent=4))
+ pytest.fail(str(e))
diff --git a/python_files/tests/pytestadapter/test_utils.py b/python_files/tests/pytestadapter/test_utils.py
new file mode 100644
index 000000000000..70201db7d097
--- /dev/null
+++ b/python_files/tests/pytestadapter/test_utils.py
@@ -0,0 +1,57 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+import tempfile
+
+from .helpers import (
+ TEST_DATA_PATH,
+)
+
+script_dir = pathlib.Path(__file__).parent.parent.parent
+sys.path.append(os.fspath(script_dir))
+from vscode_pytest import cached_fsdecode, has_symlink_parent # noqa: E402
+
+
+def test_has_symlink_parent_with_symlink():
+ # Create a temporary directory and a file in it
+ with tempfile.TemporaryDirectory() as temp_dir:
+ file_path = pathlib.Path(temp_dir) / "file"
+ file_path.touch()
+
+ # Create a symbolic link to the temporary directory
+ symlink_path = pathlib.Path(temp_dir) / "symlink"
+ symlink_path.symlink_to(temp_dir)
+
+ # Check that has_symlink_parent correctly identifies the symbolic link
+ assert has_symlink_parent(symlink_path / "file")
+
+
+def test_has_symlink_parent_without_symlink():
+ folder_path = TEST_DATA_PATH / "unittest_folder" / "test_add.py"
+ # Check that has_symlink_parent correctly identifies that there are no symbolic links
+ assert not has_symlink_parent(folder_path)
+
+
+def test_cached_fsdecode():
+ """Test that cached_fsdecode correctly caches path-to-string conversions."""
+ # Create a test path
+ test_path = TEST_DATA_PATH / "simple_pytest.py"
+
+ # First call should compute and cache
+ result1 = cached_fsdecode(test_path)
+ assert result1 == os.fspath(test_path)
+ assert isinstance(result1, str)
+
+ # Second call should return cached value (same object)
+ result2 = cached_fsdecode(test_path)
+ assert result2 == result1
+ assert result2 is result1 # Should be the same object from cache
+
+ # Different path should be cached independently
+ test_path2 = TEST_DATA_PATH / "parametrize_tests.py"
+ result3 = cached_fsdecode(test_path2)
+ assert result3 == os.fspath(test_path2)
+ assert result3 != result1
diff --git a/pythonFiles/tests/run_all.py b/python_files/tests/run_all.py
similarity index 63%
rename from pythonFiles/tests/run_all.py
rename to python_files/tests/run_all.py
index ce5a62649962..3edb3cd3440c 100644
--- a/pythonFiles/tests/run_all.py
+++ b/python_files/tests/run_all.py
@@ -2,13 +2,13 @@
# Licensed under the MIT License.
# Replace the "." entry.
-import os.path
+import os
+import pathlib
import sys
-sys.path[0] = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-from tests.__main__ import main, parse_args
+sys.path[0] = os.fsdecode(pathlib.Path(__file__).parent.parent)
+from tests.__main__ import main, parse_args # noqa: E402
if __name__ == "__main__":
mainkwargs, pytestargs = parse_args()
diff --git a/pythonFiles/tests/test_create_conda.py b/python_files/tests/test_create_conda.py
similarity index 94%
rename from pythonFiles/tests/test_create_conda.py
rename to python_files/tests/test_create_conda.py
index 29dc323402eb..82daafbea9dc 100644
--- a/pythonFiles/tests/test_create_conda.py
+++ b/python_files/tests/test_create_conda.py
@@ -4,9 +4,10 @@
import importlib
import sys
-import create_conda
import pytest
+import create_conda
+
@pytest.mark.parametrize("env_exists", [True, False])
@pytest.mark.parametrize("git_ignore", [True, False])
@@ -29,9 +30,7 @@ def install_packages(_name):
def run_process(args, error_message):
nonlocal run_process_called
run_process_called = True
- version = (
- "12345" if python else f"{sys.version_info.major}.{sys.version_info.minor}"
- )
+ version = "12345" if python else f"{sys.version_info.major}.{sys.version_info.minor}"
if not env_exists:
assert args == [
sys.executable,
diff --git a/pythonFiles/tests/test_create_microvenv.py b/python_files/tests/test_create_microvenv.py
similarity index 100%
rename from pythonFiles/tests/test_create_microvenv.py
rename to python_files/tests/test_create_microvenv.py
diff --git a/pythonFiles/tests/test_create_venv.py b/python_files/tests/test_create_venv.py
similarity index 89%
rename from pythonFiles/tests/test_create_venv.py
rename to python_files/tests/test_create_venv.py
index 446d6da8bc55..6308934d71a0 100644
--- a/pythonFiles/tests/test_create_venv.py
+++ b/python_files/tests/test_create_venv.py
@@ -14,9 +14,7 @@
import create_venv
-@pytest.mark.skipif(
- sys.platform == "win32", reason="Windows does not have micro venv fallback."
-)
+@pytest.mark.skipif(sys.platform == "win32", reason="Windows does not have micro venv fallback.")
def test_venv_not_installed_unix():
importlib.reload(create_venv)
create_venv.is_installed = lambda module: module != "venv"
@@ -43,9 +41,7 @@ def run_process(args, error_message):
assert run_process_called is True
-@pytest.mark.skipif(
- sys.platform != "win32", reason="Windows does not have microvenv fallback."
-)
+@pytest.mark.skipif(sys.platform != "win32", reason="Windows does not have microvenv fallback.")
def test_venv_not_installed_windows():
importlib.reload(create_venv)
create_venv.is_installed = lambda module: module != "venv"
@@ -55,13 +51,14 @@ def test_venv_not_installed_windows():
@pytest.mark.parametrize("env_exists", ["hasEnv", "noEnv"])
-@pytest.mark.parametrize("git_ignore", ["useGitIgnore", "skipGitIgnore"])
+@pytest.mark.parametrize("git_ignore", ["useGitIgnore", "skipGitIgnore", "gitIgnoreExists"])
@pytest.mark.parametrize("install", ["requirements", "toml", "skipInstall"])
def test_create_env(env_exists, git_ignore, install):
importlib.reload(create_venv)
create_venv.is_installed = lambda _x: True
create_venv.venv_exists = lambda _n: env_exists == "hasEnv"
create_venv.upgrade_pip = lambda _x: None
+ create_venv.is_file = lambda _x: git_ignore == "gitIgnoreExists"
install_packages_called = False
@@ -88,9 +85,19 @@ def run_process(args, error_message):
def add_gitignore(_name):
nonlocal add_gitignore_called
add_gitignore_called = True
+ if not create_venv.is_file(_name):
+ create_venv.create_gitignore(_name)
create_venv.add_gitignore = add_gitignore
+ create_gitignore_called = False
+
+ def create_gitignore(_p):
+ nonlocal create_gitignore_called
+ create_gitignore_called = True
+
+ create_venv.create_gitignore = create_gitignore
+
args = []
if git_ignore == "useGitIgnore":
args += ["--git-ignore"]
@@ -106,16 +113,16 @@ def add_gitignore(_name):
assert run_process_called == (env_exists == "noEnv")
# add_gitignore is called when new venv is created and git_ignore is True
- assert add_gitignore_called == (
- (env_exists == "noEnv") and (git_ignore == "useGitIgnore")
- )
+ assert add_gitignore_called == ((env_exists == "noEnv") and (git_ignore == "useGitIgnore"))
+
+ assert create_gitignore_called == (add_gitignore_called and (git_ignore != "gitIgnoreExists"))
@pytest.mark.parametrize("install_type", ["requirements", "pyproject", "both"])
def test_install_packages(install_type):
importlib.reload(create_venv)
create_venv.is_installed = lambda _x: True
- create_venv.file_exists = lambda x: install_type in x
+ create_venv.file_exists = lambda x: install_type in str(x)
pip_upgraded = False
installing = None
@@ -174,7 +181,7 @@ def test_toml_args(extras, expected):
actual = []
- def run_process(args, error_message):
+ def run_process(args, error_message): # noqa: ARG001
nonlocal actual
actual = args[1:]
@@ -207,7 +214,7 @@ def test_requirements_args(extras, expected):
actual = []
- def run_process(args, error_message):
+ def run_process(args, error_message): # noqa: ARG001
nonlocal actual
actual.append(args)
@@ -238,9 +245,7 @@ def run_process(args, error_message):
if "install" in args and "pip" in args:
nonlocal run_process_called
run_process_called = True
- pip_pyz_path = os.fspath(
- create_venv.CWD / create_venv.VENV_NAME / "pip.pyz"
- )
+ pip_pyz_path = os.fspath(create_venv.CWD / create_venv.VENV_NAME / "pip.pyz")
assert args[1:] == [pip_pyz_path, "install", "pip"]
assert error_message == "CREATE_VENV.INSTALL_PIP_FAILED"
diff --git a/pythonFiles/tests/test_data/missing-deps.data b/python_files/tests/test_data/missing-deps.data
similarity index 100%
rename from pythonFiles/tests/test_data/missing-deps.data
rename to python_files/tests/test_data/missing-deps.data
diff --git a/pythonFiles/tests/test_data/no-missing-deps.data b/python_files/tests/test_data/no-missing-deps.data
similarity index 100%
rename from pythonFiles/tests/test_data/no-missing-deps.data
rename to python_files/tests/test_data/no-missing-deps.data
diff --git a/pythonFiles/tests/test_data/pyproject-missing-deps.data b/python_files/tests/test_data/pyproject-missing-deps.data
similarity index 100%
rename from pythonFiles/tests/test_data/pyproject-missing-deps.data
rename to python_files/tests/test_data/pyproject-missing-deps.data
diff --git a/pythonFiles/tests/test_data/pyproject-no-missing-deps.data b/python_files/tests/test_data/pyproject-no-missing-deps.data
similarity index 100%
rename from pythonFiles/tests/test_data/pyproject-no-missing-deps.data
rename to python_files/tests/test_data/pyproject-no-missing-deps.data
diff --git a/pythonFiles/tests/test_dynamic_cursor.py b/python_files/tests/test_dynamic_cursor.py
similarity index 74%
rename from pythonFiles/tests/test_dynamic_cursor.py
rename to python_files/tests/test_dynamic_cursor.py
index 7aea59427aa6..d30887c24d5b 100644
--- a/pythonFiles/tests/test_dynamic_cursor.py
+++ b/python_files/tests/test_dynamic_cursor.py
@@ -5,13 +5,7 @@
def test_dictionary_mouse_mover():
- """
- Having the mouse cursor on second line,
- 'my_dict = {'
- and pressing shift+enter should bring the
- mouse cursor to line 6, on and to be able to run
- 'print('only send the dictionary')'
- """
+ """Having the mouse cursor on second line, 'my_dict = {' and pressing shift+enter should bring the mouse cursor to line 6, on and to be able to run 'print('only send the dictionary')'."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -24,18 +18,16 @@ def test_dictionary_mouse_mover():
"""
)
- result = normalizeSelection.traverse_file(src, 2, 2, False)
+ result = normalizeSelection.traverse_file(src, 2, 2, was_highlighted=False)
assert result["which_line_next"] == 6
def test_beginning_func():
- """
- Pressing shift+enter on the very first line,
- of function definition, such as 'my_func():'
- It should properly skip the comment and assert the
- next executable line to be executed is line 5 at
- 'my_dict = {'
+ """Pressing shift+enter on the very first line, of function definition, such as 'my_func():'.
+
+ It should properly skip the comment and assert the next executable line to be
+ executed is line 5 at 'my_dict = {'.
"""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
@@ -51,7 +43,7 @@ def my_func():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["which_line_next"] == 5
@@ -69,7 +61,7 @@ def test_cursor_forloop():
"""
)
- result = normalizeSelection.traverse_file(src, 2, 2, False)
+ result = normalizeSelection.traverse_file(src, 2, 2, was_highlighted=False)
assert result["which_line_next"] == 6
@@ -85,7 +77,7 @@ def test_inside_forloop():
"""
)
- result = normalizeSelection.traverse_file(src, 2, 2, False)
+ result = normalizeSelection.traverse_file(src, 2, 2, was_highlighted=False)
assert result["which_line_next"] == 3
@@ -98,7 +90,7 @@ def test_skip_sameline_statements():
print("Next line to be run is here!")
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["which_line_next"] == 2
@@ -119,17 +111,14 @@ def test_skip_multi_comp_lambda():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
# Shift enter from the very first ( should make
# next executable statement as the lambda expression
assert result["which_line_next"] == 7
def test_move_whole_class():
- """
- Shift+enter on a class definition
- should move the cursor after running whole class.
- """
+ """Shift+enter on a class definition should move the cursor after running whole class."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -142,7 +131,7 @@ def add_call(self, name, args=None, kwargs=None):
print("We should be here after running whole class")
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["which_line_next"] == 7
@@ -163,7 +152,7 @@ def next_func():
print("Not here but above")
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["which_line_next"] == 9
@@ -181,7 +170,7 @@ def test_try_catch_move():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["which_line_next"] == 6
@@ -199,5 +188,5 @@ def test_skip_nested():
print("Cursor should be here after running line 1")
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["which_line_next"] == 8
diff --git a/python_files/tests/test_get_variable_info.py b/python_files/tests/test_get_variable_info.py
new file mode 100644
index 000000000000..73f94fe26f06
--- /dev/null
+++ b/python_files/tests/test_get_variable_info.py
@@ -0,0 +1,114 @@
+import get_variable_info
+
+
+def set_global_variable(value):
+ # setting on the module allows tests to set a variable that the module under test can access
+ get_variable_info.test_variable = value # pyright: ignore[reportGeneralTypeIssues]
+
+
+def get_global_variable():
+ results = get_variable_info.getVariableDescriptions()
+ for variable in results:
+ if variable["name"] == "test_variable":
+ return variable
+ return None
+
+
+def assert_variable_found(variable, expected_value, expected_type, expected_count=None):
+ set_global_variable(variable)
+ variable = get_global_variable()
+ assert variable is not None
+ if expected_value is not None:
+ assert variable["value"] == expected_value
+ assert variable["type"] == expected_type
+ if expected_count is not None:
+ assert variable["count"] == expected_count
+ else:
+ assert "count" not in variable
+ return variable
+
+
+def assert_indexed_child(variable, start_index, expected_index, expected_child_value=None):
+ children = get_variable_info.getAllChildrenDescriptions(
+ variable["root"], variable["propertyChain"], start_index
+ )
+ child = children[expected_index]
+
+ if expected_child_value is not None:
+ assert child["value"] == expected_child_value
+ return child
+
+
+def assert_property(variable, expected_property_name, expected_property_value=None):
+ children = get_variable_info.getAllChildrenDescriptions(
+ variable["root"], variable["propertyChain"], 0
+ )
+ found = None
+ for child in children:
+ chain = child["propertyChain"]
+ property_name = chain[-1] if chain else None
+ if property_name == expected_property_name:
+ found = child
+ break
+
+ assert found is not None
+ if expected_property_value is not None:
+ assert found["value"] == expected_property_value
+ return found
+
+
+def test_simple():
+ assert_variable_found(1, "1", "int", None)
+
+
+def test_list():
+ found = assert_variable_found([1, 2, 3], "[1, 2, 3]", "list", 3)
+ assert_indexed_child(found, 0, 0, "1")
+
+
+def test_dict():
+ found = assert_variable_found({"a": 1, "b": 2}, "{'a': 1, 'b': 2}", "dict", None)
+ assert found["hasNamedChildren"]
+ assert_property(found, "a", "1")
+ assert_property(found, "b", "2")
+
+
+def test_tuple():
+ found = assert_variable_found((1, 2, 3), "(1, 2, 3)", "tuple", 3)
+ assert_indexed_child(found, 0, 0, "1")
+
+
+def test_set():
+ found = assert_variable_found({1, 2, 3}, "{1, 2, 3}", "set", 3)
+ assert_indexed_child(found, 0, 0, "1")
+
+
+def test_self_referencing_dict():
+ d = {}
+ d["self"] = d
+ found = assert_variable_found(d, "{'self': {...}}", "dict", None)
+ assert_property(found, "self", "{'self': {...}}")
+
+
+def test_nested_list():
+ found = assert_variable_found([[1, 2], [3, 4]], "[[1, 2], [3, 4]]", "list", 2)
+ assert_indexed_child(found, 0, 0, "[1, 2]")
+
+
+def test_long_list():
+ child = assert_variable_found(list(range(1_000_000)), None, "list", 1_000_000)
+ value = child["value"]
+ assert value.startswith("[0, 1, 2, 3")
+ assert value.endswith("...]")
+ assert_indexed_child(child, 400_000, 10, "400010")
+ assert_indexed_child(child, 999_950, 10, "999960")
+
+
+def test_get_nested_children():
+ d = [{"a": {("hello")}}]
+ found = assert_variable_found(d, "[{'a': {...}}]", "list", 1)
+
+ found = assert_indexed_child(found, 0, 0)
+ found = assert_property(found, "a")
+ found = assert_indexed_child(found, 0, 0)
+ assert found["value"] == "'hello'"
diff --git a/pythonFiles/tests/test_installed_check.py b/python_files/tests/test_installed_check.py
similarity index 96%
rename from pythonFiles/tests/test_installed_check.py
rename to python_files/tests/test_installed_check.py
index dae019359e08..607e02f34abd 100644
--- a/pythonFiles/tests/test_installed_check.py
+++ b/python_files/tests/test_installed_check.py
@@ -7,9 +7,9 @@
import pathlib
import subprocess
import sys
+from typing import Dict, List, Optional, Union
import pytest
-from typing import Dict, List, Optional, Union
SCRIPT_PATH = pathlib.Path(__file__).parent.parent / "installed_check.py"
TEST_DATA = pathlib.Path(__file__).parent / "test_data"
@@ -21,12 +21,12 @@ def generate_file(base_file: pathlib.Path):
basename = "pyproject.toml" if "pyproject" in base_file.name else "requirements.txt"
fullpath = base_file.parent / basename
if fullpath.exists():
- os.unlink(os.fspath(fullpath))
+ fullpath.unlink()
fullpath.write_text(base_file.read_text(encoding="utf-8"))
try:
yield fullpath
finally:
- os.unlink(str(fullpath))
+ fullpath.unlink()
def run_on_file(
@@ -41,8 +41,7 @@ def run_on_file(
os.fspath(SCRIPT_PATH),
os.fspath(file_path),
],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
+ capture_output=True,
check=True,
env=env,
)
diff --git a/pythonFiles/tests/test_normalize_selection.py b/python_files/tests/test_normalize_selection.py
similarity index 78%
rename from pythonFiles/tests/test_normalize_selection.py
rename to python_files/tests/test_normalize_selection.py
index 5f4d6d7d4a1f..779bb9720bfa 100644
--- a/pythonFiles/tests/test_normalize_selection.py
+++ b/python_files/tests/test_normalize_selection.py
@@ -5,21 +5,21 @@
import importlib
import textwrap
-# __file__ = "/Users/anthonykim/Desktop/vscode-python/pythonFiles/normalizeSelection.py"
+# __file__ = "/Users/anthonykim/Desktop/vscode-python/python_files/normalizeSelection.py"
# sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__))))
import normalizeSelection
-class TestNormalizationScript(object):
+class TestNormalizationScript:
"""Unit tests for the normalization script."""
- def test_basicNormalization(self):
+ def test_basic_normalization(self):
src = 'print("this is a test")'
expected = src + "\n"
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_moreThanOneLine(self):
+ def test_more_than_one_line(self):
src = textwrap.dedent(
"""\
# Some rando comment
@@ -38,7 +38,7 @@ def show_something():
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_withHangingIndent(self):
+ def test_with_hanging_indent(self):
src = textwrap.dedent(
"""\
x = 22
@@ -64,7 +64,7 @@ def test_withHangingIndent(self):
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_clearOutExtraneousNewlines(self):
+ def test_clear_out_extraneous_newlines(self):
src = textwrap.dedent(
"""\
value_x = 22
@@ -88,7 +88,7 @@ def test_clearOutExtraneousNewlines(self):
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_clearOutExtraLinesAndWhitespace(self):
+ def test_clear_out_extra_lines_and_whitespace(self):
src = textwrap.dedent(
"""\
if True:
@@ -115,13 +115,13 @@ def test_clearOutExtraLinesAndWhitespace(self):
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_partialSingleLine(self):
+ def test_partial_single_line(self):
src = " print('foo')"
expected = textwrap.dedent(src) + "\n"
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_multiLineWithIndent(self):
+ def test_multiline_with_indent(self):
src = """\
if (x > 0
@@ -146,7 +146,7 @@ def test_multiLineWithIndent(self):
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_multiLineWithComment(self):
+ def test_multiline_with_comment(self):
src = textwrap.dedent(
"""\
@@ -172,7 +172,7 @@ def test_exception(self):
result = normalizeSelection.normalize_lines(src)
assert result == expected
- def test_multilineException(self):
+ def test_multiline_exception(self):
src = textwrap.dedent(
"""\
@@ -268,3 +268,50 @@ def test_list_comp(self):
result = normalizeSelection.normalize_lines(src)
assert result == expected
+
+ def test_return_dict(self):
+ importlib.reload(normalizeSelection)
+ src = textwrap.dedent(
+ """\
+ def get_dog(name, breed):
+ return {'name': name, 'breed': breed}
+ """
+ )
+
+ expected = textwrap.dedent(
+ """\
+ def get_dog(name, breed):
+ return {'name': name, 'breed': breed}
+
+ """
+ )
+
+ result = normalizeSelection.normalize_lines(src)
+
+ assert result == expected
+
+ def test_return_dict2(self):
+ importlib.reload(normalizeSelection)
+ src = textwrap.dedent(
+ """\
+ def get_dog(name, breed):
+ return {'name': name, 'breed': breed}
+
+ dog = get_dog('Ahri', 'Pomeranian')
+ print(dog)
+ """
+ )
+
+ expected = textwrap.dedent(
+ """\
+ def get_dog(name, breed):
+ return {'name': name, 'breed': breed}
+
+ dog = get_dog('Ahri', 'Pomeranian')
+ print(dog)
+ """
+ )
+
+ result = normalizeSelection.normalize_lines(src)
+
+ assert result == expected
diff --git a/python_files/tests/test_python_server.py b/python_files/tests/test_python_server.py
new file mode 100644
index 000000000000..ca542b8ea292
--- /dev/null
+++ b/python_files/tests/test_python_server.py
@@ -0,0 +1,162 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+"""Tests for python_server.py, specifically EOF handling to prevent infinite loops."""
+
+import io
+from unittest import mock
+
+import pytest
+
+
+class TestGetHeaders:
+ """Tests for the get_headers function."""
+
+ def test_get_headers_normal(self):
+ """Test get_headers with valid headers."""
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin with valid headers
+ mock_input = b"Content-Length: 100\r\nContent-Type: application/json\r\n\r\n"
+ mock_stdin = io.BytesIO(mock_input)
+
+ # Act
+ with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)):
+ headers = python_server.get_headers()
+
+ # Assert
+ assert headers == {"Content-Length": "100", "Content-Type": "application/json"}
+
+ def test_get_headers_eof_raises_error(self):
+ """Test that get_headers raises EOFError when stdin is closed (EOF)."""
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin that returns empty bytes (EOF)
+ mock_stdin = io.BytesIO(b"")
+
+ # Act & Assert
+ with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)), pytest.raises(
+ EOFError, match="EOF reached while reading headers"
+ ):
+ python_server.get_headers()
+
+ def test_get_headers_eof_mid_headers_raises_error(self):
+ """Test that get_headers raises EOFError when EOF occurs mid-headers."""
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin with partial headers then EOF
+ mock_input = b"Content-Length: 100\r\n" # No terminating empty line
+ mock_stdin = io.BytesIO(mock_input)
+
+ # Act & Assert
+ with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)), pytest.raises(
+ EOFError, match="EOF reached while reading headers"
+ ):
+ python_server.get_headers()
+
+ def test_get_headers_empty_line_terminates(self):
+ """Test that an empty line (not EOF) properly terminates header reading."""
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin with headers followed by empty line
+ mock_input = b"Content-Length: 50\r\n\r\nsome body content"
+ mock_stdin = io.BytesIO(mock_input)
+
+ # Act
+ with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)):
+ headers = python_server.get_headers()
+
+ # Assert
+ assert headers == {"Content-Length": "50"}
+
+
+class TestEOFHandling:
+ """Tests for EOF handling in various functions that use get_headers."""
+
+ def test_custom_input_exits_on_eof(self):
+ """Test that custom_input exits gracefully on EOF."""
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin that returns empty bytes (EOF)
+ mock_stdin = io.BytesIO(b"")
+ mock_stdout = io.BytesIO()
+
+ # Act & Assert
+ with mock.patch.object(
+ python_server, "STDIN", mock.Mock(buffer=mock_stdin)
+ ), mock.patch.object(python_server, "STDOUT", mock.Mock(buffer=mock_stdout)), pytest.raises(
+ SystemExit
+ ) as exc_info:
+ python_server.custom_input("prompt> ")
+
+ # Should exit with code 0 (graceful exit)
+ assert exc_info.value.code == 0
+
+ def test_handle_response_exits_on_eof(self):
+ """Test that handle_response exits gracefully on EOF."""
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin that returns empty bytes (EOF)
+ mock_stdin = io.BytesIO(b"")
+
+ # Act & Assert
+ with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)), pytest.raises(
+ SystemExit
+ ) as exc_info:
+ python_server.handle_response("test-request-id")
+
+ # Should exit with code 0 (graceful exit)
+ assert exc_info.value.code == 0
+
+
+class TestMainLoopEOFHandling:
+ """Tests that simulate the main loop EOF scenario."""
+
+ def test_main_loop_exits_on_eof(self):
+ """Test that the main loop pattern exits gracefully on EOF.
+
+ This test verifies the fix for GitHub issue #25620 where the server
+ would spin at 100% CPU instead of exiting when VS Code closes.
+ """
+ # Arrange: Import the module
+ import python_server
+
+ # Create a mock stdin that returns empty bytes (EOF)
+ mock_stdin = io.BytesIO(b"")
+
+ # Simulate what happens in the main loop
+ with mock.patch.object(python_server, "STDIN", mock.Mock(buffer=mock_stdin)):
+ try:
+ python_server.get_headers()
+ # If we get here without raising EOFError, the fix isn't working
+ pytest.fail("Expected EOFError to be raised on EOF")
+ except EOFError:
+ # This is the expected behavior - the fix is working
+ pass
+
+ def test_readline_eof_vs_empty_line(self):
+ """Test that we correctly distinguish between EOF and empty line.
+
+ EOF: readline() returns b'' (empty bytes)
+ Empty line: readline() returns b'\\r\\n' or b'\\n' (newline bytes)
+ """
+ # Test EOF case
+ eof_stream = io.BytesIO(b"")
+ result = eof_stream.readline()
+ assert result == b"", "EOF should return empty bytes"
+
+ # Test empty line case
+ empty_line_stream = io.BytesIO(b"\r\n")
+ result = empty_line_stream.readline()
+ assert result == b"\r\n", "Empty line should return newline bytes"
+
+ # Test empty line with just newline
+ empty_line_stream2 = io.BytesIO(b"\n")
+ result = empty_line_stream2.readline()
+ assert result == b"\n", "Empty line should return newline bytes"
diff --git a/python_files/tests/test_shell_integration.py b/python_files/tests/test_shell_integration.py
new file mode 100644
index 000000000000..7503a725b6d1
--- /dev/null
+++ b/python_files/tests/test_shell_integration.py
@@ -0,0 +1,83 @@
+import importlib
+import platform
+import sys
+from unittest.mock import Mock
+
+import pythonrc
+
+is_wsl = "microsoft-standard-WSL" in platform.release()
+
+
+def test_decoration_success():
+ importlib.reload(pythonrc)
+ ps1 = pythonrc.PS1()
+
+ ps1.hooks.failure_flag = False
+ result = str(ps1)
+ if sys.platform != "win32" and (not is_wsl):
+ assert (
+ result
+ == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;0\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02"
+ )
+ else:
+ pass
+
+
+def test_decoration_failure():
+ importlib.reload(pythonrc)
+ ps1 = pythonrc.PS1()
+
+ ps1.hooks.failure_flag = True
+ result = str(ps1)
+ if sys.platform != "win32" and (not is_wsl):
+ assert (
+ result
+ == "\x01\x1b]633;C\x07\x1b]633;E;None\x07\x1b]633;D;1\x07\x1b]633;A\x07\x02>>> \x01\x1b]633;B\x07\x02"
+ )
+ else:
+ pass
+
+
+def test_displayhook_call():
+ importlib.reload(pythonrc)
+ pythonrc.PS1()
+ mock_displayhook = Mock()
+
+ hooks = pythonrc.REPLHooks()
+ hooks.original_displayhook = mock_displayhook
+
+ hooks.my_displayhook("mock_value")
+
+ mock_displayhook.assert_called_once_with("mock_value")
+
+
+def test_excepthook_call():
+ importlib.reload(pythonrc)
+ pythonrc.PS1()
+ mock_excepthook = Mock()
+
+ hooks = pythonrc.REPLHooks()
+ hooks.original_excepthook = mock_excepthook
+
+ hooks.my_excepthook("mock_type", "mock_value", "mock_traceback")
+ mock_excepthook.assert_called_once_with("mock_type", "mock_value", "mock_traceback")
+
+
+if sys.platform == "darwin":
+
+ def test_print_statement_darwin(monkeypatch):
+ importlib.reload(pythonrc)
+ with monkeypatch.context() as m:
+ m.setattr("builtins.print", Mock())
+ importlib.reload(sys.modules["pythonrc"])
+ print.assert_any_call("Cmd click to launch VS Code Native REPL")
+
+
+if sys.platform == "win32":
+
+ def test_print_statement_non_darwin(monkeypatch):
+ importlib.reload(pythonrc)
+ with monkeypatch.context() as m:
+ m.setattr("builtins.print", Mock())
+ importlib.reload(sys.modules["pythonrc"])
+ print.assert_any_call("Ctrl click to launch VS Code Native REPL")
diff --git a/pythonFiles/tests/test_smart_selection.py b/python_files/tests/test_smart_selection.py
similarity index 80%
rename from pythonFiles/tests/test_smart_selection.py
rename to python_files/tests/test_smart_selection.py
index b86e6f9dc82e..15b1b1a3ec02 100644
--- a/pythonFiles/tests/test_smart_selection.py
+++ b/python_files/tests/test_smart_selection.py
@@ -26,7 +26,7 @@ def test_part_dictionary():
"""
)
- result = normalizeSelection.traverse_file(src, 3, 3, False)
+ result = normalizeSelection.traverse_file(src, 3, 3, was_highlighted=False)
assert result["normalized_smart_result"] == expected
@@ -53,7 +53,7 @@ def test_nested_loop():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
@@ -84,7 +84,7 @@ def test_smart_shift_enter_multiple_statements():
print("Mercedes")
"""
)
- result = normalizeSelection.traverse_file(src, 8, 8, False)
+ result = normalizeSelection.traverse_file(src, 8, 8, was_highlighted=False)
assert result["normalized_smart_result"] == expected
@@ -128,7 +128,7 @@ def test_two_layer_dictionary():
}
"""
)
- result = normalizeSelection.traverse_file(src, 6, 7, False)
+ result = normalizeSelection.traverse_file(src, 6, 7, was_highlighted=False)
assert result["normalized_smart_result"] == expected
@@ -158,7 +158,7 @@ def my_dogs():
"""
)
- result = normalizeSelection.traverse_file(src, 2, 2, False)
+ result = normalizeSelection.traverse_file(src, 2, 2, was_highlighted=False)
assert result["normalized_smart_result"] == expected
@@ -183,18 +183,13 @@ def test_small_forloop():
# Cover the whole for loop block with multiple inner statements
# Make sure to contain all of the print statements included.
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
def inner_for_loop_component():
- """
- Pressing shift+enter inside a for loop,
- specifically on a viable expression
- by itself, such as print(i)
- should only return that exact expression
- """
+ """Pressing shift+enter inside a for loop, specifically on a viable expression by itself, such as print(i) should only return that exact expression."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -203,7 +198,7 @@ def inner_for_loop_component():
print("Please also send this print statement")
"""
)
- result = normalizeSelection.traverse_file(src, 2, 2, False)
+ result = normalizeSelection.traverse_file(src, 2, 2, was_highlighted=False)
expected = textwrap.dedent(
"""\
print(i)
@@ -214,13 +209,7 @@ def inner_for_loop_component():
def test_dict_comprehension():
- """
- Having the mouse cursor on the first line,
- and pressing shift+enter should return the
- whole dictionary comp, respecting user's code style.
- """
-
- importlib.reload
+ """Having the mouse cursor on the first line, and pressing shift+enter should return the whole dictionary comp, respecting user's code style."""
src = textwrap.dedent(
"""\
my_dict_comp = {temp_mover:
@@ -235,17 +224,13 @@ def test_dict_comprehension():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
def test_send_whole_generator():
- """
- Pressing shift+enter on the first line, which is the '('
- should be returning the whole generator expression instead of just the '('
- """
-
+ """Pressing shift+enter on the first line, which is the '(' should be returning the whole generator expression instead of just the '('."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -268,19 +253,13 @@ def test_send_whole_generator():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
def test_multiline_lambda():
- """
- Shift+enter on part of the lambda expression
- should return the whole lambda expression,
- regardless of whether all the component of
- lambda expression is on the same or not.
- """
-
+ """Shift+enter on part of the lambda expression should return the whole lambda expression, regardless of whether all the component of lambda expression is on the same or not."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -298,15 +277,12 @@ def test_multiline_lambda():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
def test_send_whole_class():
- """
- Shift+enter on a class definition
- should send the whole class definition
- """
+ """Shift+enter on a class definition should send the whole class definition."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -319,7 +295,7 @@ def add_call(self, name, args=None, kwargs=None):
print("We should be here after running whole class")
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
expected = textwrap.dedent(
"""\
class Stub(object):
@@ -334,11 +310,7 @@ def add_call(self, name, args=None, kwargs=None):
def test_send_whole_if_statement():
- """
- Shift+enter on an if statement
- should send the whole if statement
- including statements inside and else.
- """
+ """Shift+enter on an if statement should send the whole if statement including statements inside and else."""
importlib.reload(normalizeSelection)
src = textwrap.dedent(
"""\
@@ -359,7 +331,7 @@ def test_send_whole_if_statement():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
@@ -384,5 +356,5 @@ def test_send_try():
"""
)
- result = normalizeSelection.traverse_file(src, 1, 1, False)
+ result = normalizeSelection.traverse_file(src, 1, 1, was_highlighted=False)
assert result["normalized_smart_result"] == expected
diff --git a/python_files/tests/tree_comparison_helper.py b/python_files/tests/tree_comparison_helper.py
new file mode 100644
index 000000000000..3d9d1d39194b
--- /dev/null
+++ b/python_files/tests/tree_comparison_helper.py
@@ -0,0 +1,39 @@
+def is_same_tree(tree1, tree2, test_key_arr, path="root") -> bool:
+ """Helper function to test if two test trees are the same with detailed error logs.
+
+ `is_same_tree` starts by comparing the root attributes, and then checks if all children are the same.
+ """
+ # Compare the root.
+ for key in ["path", "name", "type_", "id_"]:
+ if tree1.get(key) != tree2.get(key):
+ print(
+ f"Difference found at {path}: '{key}' is '{tree1.get(key)}' in tree1 and '{tree2.get(key)}' in tree2."
+ )
+ return False
+
+ # Compare child test nodes if they exist, otherwise compare test items.
+ if "children" in tree1 and "children" in tree2:
+ # Sort children by path before comparing since order doesn't matter of children
+ children1 = sorted(tree1["children"], key=lambda x: x["path"])
+ children2 = sorted(tree2["children"], key=lambda x: x["path"])
+
+ # Compare test nodes.
+ if len(children1) != len(children2):
+ print(
+ f"Difference in number of children at {path}: {len(children1)} in tree1 and {len(children2)} in tree2."
+ )
+ return False
+ else:
+ for i, (child1, child2) in enumerate(zip(children1, children2)):
+ if not is_same_tree(child1, child2, test_key_arr, path=f"{path} -> child {i}"):
+ return False
+ elif "id_" in tree1 and "id_" in tree2:
+ # Compare test items.
+ for key in test_key_arr:
+ if tree1.get(key) != tree2.get(key):
+ print(
+ f"Difference found at {path}: '{key}' is '{tree1.get(key)}' in tree1 and '{tree2.get(key)}' in tree2."
+ )
+ return False
+
+ return True
diff --git a/pythonFiles/tests/pytestadapter/__init__.py b/python_files/tests/unittestadapter/.data/coverage_ex/__init__.py
similarity index 100%
rename from pythonFiles/tests/pytestadapter/__init__.py
rename to python_files/tests/unittestadapter/.data/coverage_ex/__init__.py
diff --git a/python_files/tests/unittestadapter/.data/coverage_ex/reverse.py b/python_files/tests/unittestadapter/.data/coverage_ex/reverse.py
new file mode 100644
index 000000000000..4840b7d05bf3
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/coverage_ex/reverse.py
@@ -0,0 +1,14 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+def reverse_string(s):
+ if s is None or s == "":
+ return "Error: Input is None"
+ return s[::-1]
+
+def reverse_sentence(sentence):
+ if sentence is None or sentence == "":
+ return "Error: Input is None"
+ words = sentence.split()
+ reversed_words = [reverse_string(word) for word in words]
+ return " ".join(reversed_words)
diff --git a/python_files/tests/unittestadapter/.data/coverage_ex/test_reverse.py b/python_files/tests/unittestadapter/.data/coverage_ex/test_reverse.py
new file mode 100644
index 000000000000..2521e3dc1935
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/coverage_ex/test_reverse.py
@@ -0,0 +1,32 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import unittest
+from reverse import reverse_sentence, reverse_string
+
+class TestReverseFunctions(unittest.TestCase):
+
+ def test_reverse_sentence(self):
+ """
+ Tests the reverse_sentence function to ensure it correctly reverses each word in a sentence.
+
+ Test cases:
+ - "hello world" should be reversed to "olleh dlrow"
+ - "Python is fun" should be reversed to "nohtyP si nuf"
+ - "a b c" should remain "a b c" as each character is a single word
+ """
+ self.assertEqual(reverse_sentence("hello world"), "olleh dlrow")
+ self.assertEqual(reverse_sentence("Python is fun"), "nohtyP si nuf")
+ self.assertEqual(reverse_sentence("a b c"), "a b c")
+
+ def test_reverse_sentence_error(self):
+ self.assertEqual(reverse_sentence(""), "Error: Input is None")
+ self.assertEqual(reverse_sentence(None), "Error: Input is None")
+
+ def test_reverse_string(self):
+ self.assertEqual(reverse_string("hello"), "olleh")
+ self.assertEqual(reverse_string("Python"), "nohtyP")
+ # this test specifically does not cover the error cases
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/pythonFiles/tests/unittestadapter/.data/discovery_empty.py b/python_files/tests/unittestadapter/.data/discovery_empty.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/discovery_empty.py
rename to python_files/tests/unittestadapter/.data/discovery_empty.py
diff --git a/pythonFiles/tests/unittestadapter/.data/discovery_error/file_one.py b/python_files/tests/unittestadapter/.data/discovery_error/file_one.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/discovery_error/file_one.py
rename to python_files/tests/unittestadapter/.data/discovery_error/file_one.py
diff --git a/pythonFiles/tests/unittestadapter/.data/discovery_error/file_two.py b/python_files/tests/unittestadapter/.data/discovery_error/file_two.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/discovery_error/file_two.py
rename to python_files/tests/unittestadapter/.data/discovery_error/file_two.py
diff --git a/pythonFiles/tests/unittestadapter/.data/discovery_simple.py b/python_files/tests/unittestadapter/.data/discovery_simple.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/discovery_simple.py
rename to python_files/tests/unittestadapter/.data/discovery_simple.py
diff --git a/python_files/tests/unittestadapter/.data/doctest_patched_module.py b/python_files/tests/unittestadapter/.data/doctest_patched_module.py
new file mode 100644
index 000000000000..636c5320b6d6
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/doctest_patched_module.py
@@ -0,0 +1,17 @@
+"""
+Patched doctest module.
+This module's doctests will be patched to have proper IDs.
+
+>>> 2 + 2
+4
+"""
+
+
+def example_function():
+ """
+ Example function with doctest.
+
+ >>> example_function()
+ 'works'
+ """
+ return "works"
diff --git a/python_files/tests/unittestadapter/.data/doctest_standard.py b/python_files/tests/unittestadapter/.data/doctest_standard.py
new file mode 100644
index 000000000000..52a10aa46a7f
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/doctest_standard.py
@@ -0,0 +1,7 @@
+"""
+Standard doctest module that should be blocked.
+This has a simple doctest with short ID.
+
+>>> 2 + 2
+4
+"""
diff --git a/python_files/tests/unittestadapter/.data/simple_django/db.sqlite3 b/python_files/tests/unittestadapter/.data/simple_django/db.sqlite3
new file mode 100644
index 000000000000..519ec5e1a11c
Binary files /dev/null and b/python_files/tests/unittestadapter/.data/simple_django/db.sqlite3 differ
diff --git a/python_files/tests/unittestadapter/.data/simple_django/manage.py b/python_files/tests/unittestadapter/.data/simple_django/manage.py
new file mode 100755
index 000000000000..c5734a6babee
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/manage.py
@@ -0,0 +1,23 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/pythonFiles/tests/testing_tools/__init__.py b/python_files/tests/unittestadapter/.data/simple_django/mysite/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/__init__.py
rename to python_files/tests/unittestadapter/.data/simple_django/mysite/__init__.py
diff --git a/python_files/tests/unittestadapter/.data/simple_django/mysite/asgi.py b/python_files/tests/unittestadapter/.data/simple_django/mysite/asgi.py
new file mode 100644
index 000000000000..bb01f607934c
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/mysite/asgi.py
@@ -0,0 +1,9 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
+
+application = get_asgi_application()
diff --git a/python_files/tests/unittestadapter/.data/simple_django/mysite/settings.py b/python_files/tests/unittestadapter/.data/simple_django/mysite/settings.py
new file mode 100644
index 000000000000..3120fb4e829f
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/mysite/settings.py
@@ -0,0 +1,102 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+"""
+Django settings for mysite project.
+
+Generated by 'django-admin startproject' using Django 3.2.22.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.2/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.2/ref/settings/
+"""
+
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ "polls.apps.PollsConfig",
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.messages",
+ "django.contrib.staticfiles",
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'mysite.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'mysite.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+
+
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/3.2/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.2/howto/static-files/
+
+STATIC_URL = '/static/'
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
+
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
diff --git a/python_files/tests/unittestadapter/.data/simple_django/mysite/urls.py b/python_files/tests/unittestadapter/.data/simple_django/mysite/urls.py
new file mode 100644
index 000000000000..02e76f125c72
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/mysite/urls.py
@@ -0,0 +1,9 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+from django.contrib import admin
+from django.urls import include, path
+
+urlpatterns = [
+ path("polls/", include("polls.urls")),
+ path("admin/", admin.site.urls),
+]
diff --git a/python_files/tests/unittestadapter/.data/simple_django/mysite/wsgi.py b/python_files/tests/unittestadapter/.data/simple_django/mysite/wsgi.py
new file mode 100644
index 000000000000..e932bff6649e
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/mysite/wsgi.py
@@ -0,0 +1,7 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+application = get_wsgi_application()
diff --git a/python_files/tests/unittestadapter/.data/simple_django/old_manage.py b/python_files/tests/unittestadapter/.data/simple_django/old_manage.py
new file mode 100755
index 000000000000..844b98b4edba
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/old_manage.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+import os
+import sys
+if __name__ == "__main__":
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError:
+ # The above import may fail for some other reason. Ensure that the
+ # issue is really that Django is missing to avoid masking other
+ # exceptions on Python 2.
+ try:
+ import django
+ except ImportError:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ )
+ raise
+ execute_from_command_line(sys.argv)
diff --git a/pythonFiles/tests/testing_tools/adapter/__init__.py b/python_files/tests/unittestadapter/.data/simple_django/polls/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/__init__.py
rename to python_files/tests/unittestadapter/.data/simple_django/polls/__init__.py
diff --git a/pythonFiles/tests/testing_tools/adapter/pytest/__init__.py b/python_files/tests/unittestadapter/.data/simple_django/polls/admin.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/pytest/__init__.py
rename to python_files/tests/unittestadapter/.data/simple_django/polls/admin.py
diff --git a/python_files/tests/unittestadapter/.data/simple_django/polls/apps.py b/python_files/tests/unittestadapter/.data/simple_django/polls/apps.py
new file mode 100644
index 000000000000..e31968ce16c0
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/polls/apps.py
@@ -0,0 +1,13 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+from django.apps import AppConfig
+from django.utils.functional import cached_property
+
+
+class PollsConfig(AppConfig):
+ @cached_property
+ def default_auto_field(self):
+ return "django.db.models.BigAutoField"
+
+ name = "polls"
diff --git a/python_files/tests/unittestadapter/.data/simple_django/polls/migrations/0001_initial.py b/python_files/tests/unittestadapter/.data/simple_django/polls/migrations/0001_initial.py
new file mode 100644
index 000000000000..e33d24a3f704
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/polls/migrations/0001_initial.py
@@ -0,0 +1,52 @@
+# Generated by Django 5.0.8 on 2024-08-09 20:04
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = []
+
+ operations = [
+ migrations.CreateModel(
+ name="Question",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("question_text", models.CharField(max_length=200, default="")),
+ ("pub_date", models.DateTimeField(verbose_name="date published", auto_now_add=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name="Choice",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("choice_text", models.CharField(max_length=200)),
+ ("votes", models.IntegerField(default=0)),
+ (
+ "question",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE, to="polls.question"
+ ),
+ ),
+ ],
+ ),
+ ]
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py b/python_files/tests/unittestadapter/.data/simple_django/polls/migrations/__init__.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py
rename to python_files/tests/unittestadapter/.data/simple_django/polls/migrations/__init__.py
diff --git a/python_files/tests/unittestadapter/.data/simple_django/polls/models.py b/python_files/tests/unittestadapter/.data/simple_django/polls/models.py
new file mode 100644
index 000000000000..260a3da60f99
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/polls/models.py
@@ -0,0 +1,25 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+from django.db import models
+from django.utils import timezone
+import datetime
+
+
+class Question(models.Model):
+ question_text = models.CharField(max_length=200)
+ pub_date = models.DateTimeField("date published")
+ def __str__(self):
+ return self.question_text
+ def was_published_recently(self):
+ if self.pub_date > timezone.now():
+ return False
+ return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
+
+
+class Choice(models.Model):
+ question = models.ForeignKey(Question, on_delete=models.CASCADE)
+ choice_text = models.CharField(max_length=200)
+ votes = models.IntegerField()
+ def __str__(self):
+ return self.choice_text
diff --git a/python_files/tests/unittestadapter/.data/simple_django/polls/tests.py b/python_files/tests/unittestadapter/.data/simple_django/polls/tests.py
new file mode 100644
index 000000000000..243262f195a8
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/polls/tests.py
@@ -0,0 +1,38 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+from django.utils import timezone
+from django.test import TestCase
+from .models import Question
+import datetime
+
+class QuestionModelTests(TestCase):
+ def test_was_published_recently_with_future_question(self):
+ """
+ was_published_recently() returns False for questions whose pub_date
+ is in the future.
+ """
+ time = timezone.now() + datetime.timedelta(days=30)
+ future_question: Question = Question.objects.create(pub_date=time)
+ self.assertIs(future_question.was_published_recently(), False)
+
+ def test_was_published_recently_with_future_question_2(self):
+ """
+ was_published_recently() returns False for questions whose pub_date
+ is in the future.
+ """
+ time = timezone.now() + datetime.timedelta(days=30)
+ future_question = Question.objects.create(pub_date=time)
+ self.assertIs(future_question.was_published_recently(), True)
+
+ def test_question_creation_and_retrieval(self):
+ """
+ Test that a Question can be created and retrieved from the database.
+ """
+ time = timezone.now()
+ question = Question.objects.create(pub_date=time, question_text="What's new?")
+ retrieved_question = Question.objects.get(question_text=question.question_text)
+ self.assertEqual(question, retrieved_question)
+ self.assertEqual(retrieved_question.question_text, "What's new?")
+ self.assertEqual(retrieved_question.pub_date, time)
+
diff --git a/python_files/tests/unittestadapter/.data/simple_django/polls/urls.py b/python_files/tests/unittestadapter/.data/simple_django/polls/urls.py
new file mode 100644
index 000000000000..5756c7daa847
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/polls/urls.py
@@ -0,0 +1,11 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+from django.urls import path
+
+from . import views
+
+urlpatterns = [
+ # ex: /polls/
+ path("", views.index, name="index"),
+]
diff --git a/python_files/tests/unittestadapter/.data/simple_django/polls/views.py b/python_files/tests/unittestadapter/.data/simple_django/polls/views.py
new file mode 100644
index 000000000000..cccb6b3b0685
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/simple_django/polls/views.py
@@ -0,0 +1,7 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+from django.http import HttpResponse
+from .models import Question # noqa: F401
+
+def index(request):
+ return HttpResponse("Hello, world. You're at the polls index.")
diff --git a/python_files/tests/unittestadapter/.data/test_doctest_patched.py b/python_files/tests/unittestadapter/.data/test_doctest_patched.py
new file mode 100644
index 000000000000..3a719c7139ca
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/test_doctest_patched.py
@@ -0,0 +1,50 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+"""Test file with patched doctest integration that should work."""
+
+import unittest
+import doctest
+import sys
+import doctest_patched_module
+
+
+# Patch DocTestCase to modify test IDs to be compatible with the extension
+original_init = doctest.DocTestCase.__init__
+
+
+def patched_init(self, test, optionflags=0, setUp=None, tearDown=None, checker=None):
+ """Patch to modify doctest names to have proper hierarchy."""
+ if hasattr(test, 'name'):
+ # Get module name
+ module_hierarchy = test.name.split('.')
+ module_name = module_hierarchy[0] if module_hierarchy else 'unknown'
+
+ # Reconstruct with proper formatting to have enough components
+ # Format: module.file.class.function
+ if test.filename.endswith('.py'):
+ file_base = test.filename.split('/')[-1].replace('.py', '')
+ test_name = test.name.split('.')[-1] if '.' in test.name else test.name
+ # Create a properly formatted ID with enough components
+ test.name = f"{module_name}.{file_base}._DocTests.{test_name}"
+
+ # Call original init
+ original_init(self, test, optionflags, setUp, tearDown, checker)
+
+
+# Apply the patch
+doctest.DocTestCase.__init__ = patched_init
+
+
+def load_tests(loader, tests, ignore):
+ """
+ Standard hook for unittest to load tests.
+ This uses patched doctest to create compatible test IDs.
+ """
+ tests.addTests(doctest.DocTestSuite(doctest_patched_module))
+ return tests
+
+
+# Clean up the patch after loading
+def tearDownModule():
+ """Restore original DocTestCase.__init__"""
+ doctest.DocTestCase.__init__ = original_init
diff --git a/python_files/tests/unittestadapter/.data/test_doctest_standard.py b/python_files/tests/unittestadapter/.data/test_doctest_standard.py
new file mode 100644
index 000000000000..f5dba1209b98
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/test_doctest_standard.py
@@ -0,0 +1,16 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+"""Test file with standard doctest integration that should be blocked."""
+
+import unittest
+import doctest
+import doctest_standard
+
+
+def load_tests(loader, tests, ignore):
+ """
+ Standard hook for unittest to load tests.
+ This uses standard doctest without any patching.
+ """
+ tests.addTests(doctest.DocTestSuite(doctest_standard))
+ return tests
diff --git a/pythonFiles/tests/unittestadapter/.data/test_fail_simple.py b/python_files/tests/unittestadapter/.data/test_fail_simple.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/test_fail_simple.py
rename to python_files/tests/unittestadapter/.data/test_fail_simple.py
diff --git a/pythonFiles/tests/unittestadapter/__init__.py b/python_files/tests/unittestadapter/.data/test_scenarios/tests/__init__.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/__init__.py
rename to python_files/tests/unittestadapter/.data/test_scenarios/tests/__init__.py
diff --git a/python_files/tests/unittestadapter/.data/test_scenarios/tests/test_scene.py b/python_files/tests/unittestadapter/.data/test_scenarios/tests/test_scene.py
new file mode 100644
index 000000000000..35c1c7002319
--- /dev/null
+++ b/python_files/tests/unittestadapter/.data/test_scenarios/tests/test_scene.py
@@ -0,0 +1,39 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import unittest
+
+from testscenarios import TestWithScenarios, generate_scenarios
+
+
+def load_tests(loader, standard_tests, pattern): # noqa: ARG001
+ # Pre-expand ``TestWithScenarios`` scenarios at load time so individual
+ # scenario-multiplied test IDs (e.g. ``test_operations(add)``) can be
+ # resolved by ``unittest.TestLoader.loadTestsFromName``. Without this,
+ # ``TestWithScenarios`` only multiplies scenarios at ``run()`` time and
+ # loading a specific scenario by name raises ``AttributeError``.
+ result = unittest.TestSuite()
+ result.addTests(generate_scenarios(standard_tests))
+ return result
+
+
+class TestMathOperations(TestWithScenarios):
+ scenarios = [
+ ('add', {'test_id': 'test_add', 'a': 5, 'b': 3, 'expected': 8}),
+ ('subtract', {'test_id': 'test_subtract', 'a': 5, 'b': 3, 'expected': 2}),
+ ('multiply', {'test_id': 'test_multiply', 'a': 5, 'b': 3, 'expected': 15}),
+ ]
+ a: int = 0
+ b: int = 0
+ expected: int = 0
+ test_id: str = ""
+
+ def test_operations(self):
+ result = None
+ if self.test_id == 'test_add':
+ result = self.a + self.b
+ elif self.test_id == 'test_subtract':
+ result = self.a - self.b
+ elif self.test_id == 'test_multiply':
+ result = self.a * self.b
+ self.assertEqual(result, self.expected)
diff --git a/pythonFiles/tests/unittestadapter/.data/test_subtest.py b/python_files/tests/unittestadapter/.data/test_subtest.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/test_subtest.py
rename to python_files/tests/unittestadapter/.data/test_subtest.py
diff --git a/pythonFiles/tests/unittestadapter/.data/test_two_classes.py b/python_files/tests/unittestadapter/.data/test_two_classes.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/test_two_classes.py
rename to python_files/tests/unittestadapter/.data/test_two_classes.py
diff --git a/pythonFiles/tests/unittestadapter/.data/two_patterns/pattern_a_test.py b/python_files/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
similarity index 95%
rename from pythonFiles/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
rename to python_files/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
index 4f3f77e1056e..52641360b526 100644
--- a/pythonFiles/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
+++ b/python_files/tests/unittestadapter/.data/two_patterns/pattern_a_test.py
@@ -7,7 +7,6 @@
# and the two tests with their outcome as "success".
-
class DiscoveryA(unittest.TestCase):
"""Test class for the two file pattern test. It is pattern *test.py
@@ -19,4 +18,4 @@ def test_one_a(self) -> None:
self.assertGreater(2, 1)
def test_two_a(self) -> None:
- self.assertNotEqual(2, 1)
\ No newline at end of file
+ self.assertNotEqual(2, 1)
diff --git a/pythonFiles/tests/unittestadapter/.data/two_patterns/test_pattern_b.py b/python_files/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
similarity index 93%
rename from pythonFiles/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
rename to python_files/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
index a912699383ca..06b6a818537d 100644
--- a/pythonFiles/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
+++ b/python_files/tests/unittestadapter/.data/two_patterns/test_pattern_b.py
@@ -6,10 +6,10 @@
# The test_ids_multiple_runs function should return a dictionary with a "success" status,
# and the two tests with their outcome as "success".
-class DiscoveryB(unittest.TestCase):
+class DiscoveryB(unittest.TestCase):
def test_one_b(self) -> None:
self.assertGreater(2, 1)
def test_two_b(self) -> None:
- self.assertNotEqual(2, 1)
\ No newline at end of file
+ self.assertNotEqual(2, 1)
diff --git a/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_add.py b/python_files/tests/unittestadapter/.data/unittest_folder/test_add.py
similarity index 81%
rename from pythonFiles/tests/unittestadapter/.data/unittest_folder/test_add.py
rename to python_files/tests/unittestadapter/.data/unittest_folder/test_add.py
index 2e616077ec40..f562474b596a 100644
--- a/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_add.py
+++ b/python_files/tests/unittestadapter/.data/unittest_folder/test_add.py
@@ -6,17 +6,16 @@
# files in the same folder. The cwd is set to the parent folder. This should return
# a dictionary with a "success" status and the two tests with their outcome as "success".
+
def add(a, b):
return a + b
class TestAddFunction(unittest.TestCase):
-
- def test_add_positive_numbers(self):
+ def test_add_positive_numbers(self):
result = add(2, 3)
self.assertEqual(result, 5)
-
- def test_add_negative_numbers(self):
+ def test_add_negative_numbers(self):
result = add(-2, -3)
- self.assertEqual(result, -5)
\ No newline at end of file
+ self.assertEqual(result, -5)
diff --git a/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_subtract.py b/python_files/tests/unittestadapter/.data/unittest_folder/test_subtract.py
similarity index 94%
rename from pythonFiles/tests/unittestadapter/.data/unittest_folder/test_subtract.py
rename to python_files/tests/unittestadapter/.data/unittest_folder/test_subtract.py
index 4028e25825d1..8ac3988a3251 100644
--- a/pythonFiles/tests/unittestadapter/.data/unittest_folder/test_subtract.py
+++ b/python_files/tests/unittestadapter/.data/unittest_folder/test_subtract.py
@@ -6,6 +6,7 @@
# files in the same folder. The cwd is set to the parent folder. This should return
# a dictionary with a "success" status and the two tests with their outcome as "success".
+
def subtract(a, b):
return a - b
@@ -15,7 +16,6 @@ def test_subtract_positive_numbers(self):
result = subtract(5, 3)
self.assertEqual(result, 2)
-
def test_subtract_negative_numbers(self):
result = subtract(-2, -3)
- self.assertEqual(result, 1)
\ No newline at end of file
+ self.assertEqual(result, 1)
diff --git a/pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py b/python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py
rename to python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_file.py
diff --git a/pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py b/python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py
rename to python_files/tests/unittestadapter/.data/unittest_skip/unittest_skip_function.py
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/__init__.py b/python_files/tests/unittestadapter/.data/utils_complex_tree/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/__init__.py
rename to python_files/tests/unittestadapter/.data/utils_complex_tree/__init__.py
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/__init__.py b/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/C/__init__.py
rename to python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/__init__.py
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/__init__.py b/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/A/b/__init__.py
rename to python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/__init__.py
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py b/python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py
rename to python_files/tests/unittestadapter/.data/utils_complex_tree/test_outer_folder/test_inner_folder/test_utils_complex_tree.py
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_decorated_tree.py b/python_files/tests/unittestadapter/.data/utils_decorated_tree.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_decorated_tree.py
rename to python_files/tests/unittestadapter/.data/utils_decorated_tree.py
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/file_one.py b/python_files/tests/unittestadapter/.data/utils_nested_cases/file_one.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_nested_cases/file_one.py
rename to python_files/tests/unittestadapter/.data/utils_nested_cases/file_one.py
diff --git a/pythonFiles/unittestadapter/__init__.py b/python_files/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py
similarity index 100%
rename from pythonFiles/unittestadapter/__init__.py
rename to python_files/tests/unittestadapter/.data/utils_nested_cases/folder/__init__.py
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py b/python_files/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py
rename to python_files/tests/unittestadapter/.data/utils_nested_cases/folder/file_two.py
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_simple_cases.py b/python_files/tests/unittestadapter/.data/utils_simple_cases.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_simple_cases.py
rename to python_files/tests/unittestadapter/.data/utils_simple_cases.py
diff --git a/pythonFiles/tests/unittestadapter/.data/utils_simple_tree.py b/python_files/tests/unittestadapter/.data/utils_simple_tree.py
similarity index 100%
rename from pythonFiles/tests/unittestadapter/.data/utils_simple_tree.py
rename to python_files/tests/unittestadapter/.data/utils_simple_tree.py
diff --git a/python_files/tests/unittestadapter/__init__.py b/python_files/tests/unittestadapter/__init__.py
new file mode 100644
index 000000000000..5b7f7a925cc0
--- /dev/null
+++ b/python_files/tests/unittestadapter/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
diff --git a/python_files/tests/unittestadapter/conftest.py b/python_files/tests/unittestadapter/conftest.py
new file mode 100644
index 000000000000..5b7f7a925cc0
--- /dev/null
+++ b/python_files/tests/unittestadapter/conftest.py
@@ -0,0 +1,2 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
diff --git a/python_files/tests/unittestadapter/django_test_execution_script.py b/python_files/tests/unittestadapter/django_test_execution_script.py
new file mode 100644
index 000000000000..21dd945224ea
--- /dev/null
+++ b/python_files/tests/unittestadapter/django_test_execution_script.py
@@ -0,0 +1,17 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+
+sys.path.append(os.fspath(pathlib.Path(__file__).parent.parent))
+
+from unittestadapter.django_handler import django_execution_runner
+
+if __name__ == "__main__":
+ args = sys.argv[1:]
+ manage_py_path = args[0]
+ test_ids = args[1:]
+ # currently doesn't support additional args past test_ids.
+ django_execution_runner(manage_py_path, test_ids, [])
diff --git a/pythonFiles/tests/unittestadapter/expected_discovery_test_output.py b/python_files/tests/unittestadapter/expected_discovery_test_output.py
similarity index 66%
rename from pythonFiles/tests/unittestadapter/expected_discovery_test_output.py
rename to python_files/tests/unittestadapter/expected_discovery_test_output.py
index db509ebeca3c..0901f21bfbc2 100644
--- a/pythonFiles/tests/unittestadapter/expected_discovery_test_output.py
+++ b/python_files/tests/unittestadapter/expected_discovery_test_output.py
@@ -2,30 +2,46 @@
# Licensed under the MIT License.
import os
-from unittestadapter.pvsc_utils import TestNodeTypeEnum
-from .helpers import TEST_DATA_PATH
import pathlib
+from unittestadapter.pvsc_utils import TestNodeTypeEnum
+
+TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
+
+
+def find_class_line_number(class_name: str, test_file_path) -> str:
+ """Function which finds the correct line number for a class definition.
+
+ Args:
+ class_name: The name of the class to find the line number for.
+ test_file_path: The path to the test file where the class is located.
+ """
+ # Look for the class definition line
+ with pathlib.Path(test_file_path).open() as f:
+ for i, line in enumerate(f):
+ # Match "class ClassName" or "class ClassName(" or "class ClassName:"
+ if line.strip().startswith(f"class {class_name}") or line.strip().startswith(
+ f"class {class_name}("
+ ):
+ return str(i + 1)
+ error_str: str = f"Class {class_name!r} not found on any line in {test_file_path}"
+ raise ValueError(error_str)
+
+
skip_unittest_folder_discovery_output = {
"path": os.fspath(TEST_DATA_PATH / "unittest_skip"),
"name": "unittest_skip",
"type_": TestNodeTypeEnum.folder,
"children": [
{
- "path": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"
- ),
+ "path": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"),
"name": "unittest_skip_file.py",
"type_": TestNodeTypeEnum.file,
"children": [],
- "id_": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"
- ),
+ "id_": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_file.py"),
},
{
- "path": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
- ),
+ "path": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"),
"name": "unittest_skip_function.py",
"type_": TestNodeTypeEnum.file,
"children": [
@@ -39,30 +55,26 @@
{
"name": "testadd1",
"path": os.fspath(
- TEST_DATA_PATH
- / "unittest_skip"
- / "unittest_skip_function.py"
+ TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
),
"lineno": "13",
"type_": TestNodeTypeEnum.test,
"id_": os.fspath(
- TEST_DATA_PATH
- / "unittest_skip"
- / "unittest_skip_function.py"
+ TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
)
+ "\\SimpleTest\\testadd1",
"runID": "unittest_skip_function.SimpleTest.testadd1",
}
],
- "id_": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
- )
+ "id_": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py")
+ "\\SimpleTest",
+ "lineno": find_class_line_number(
+ "SimpleTest",
+ TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py",
+ ),
}
],
- "id_": os.fspath(
- TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"
- ),
+ "id_": os.fspath(TEST_DATA_PATH / "unittest_skip" / "unittest_skip_function.py"),
},
],
"id_": os.fspath(TEST_DATA_PATH / "unittest_skip"),
@@ -86,9 +98,7 @@
"name": "test_outer_folder",
"type_": TestNodeTypeEnum.folder,
"path": os.fsdecode(
- pathlib.PurePath(
- TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder"
- )
+ pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder")
),
"children": [
{
@@ -127,6 +137,16 @@
},
],
"id_": complex_tree_file_path + "\\" + "TreeOne",
+ "lineno": find_class_line_number(
+ "TreeOne",
+ pathlib.PurePath(
+ TEST_DATA_PATH,
+ "utils_complex_tree",
+ "test_outer_folder",
+ "test_inner_folder",
+ "test_utils_complex_tree.py",
+ ),
+ ),
}
],
"id_": complex_tree_file_path,
@@ -143,9 +163,7 @@
},
],
"id_": os.fsdecode(
- pathlib.PurePath(
- TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder"
- )
+ pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree", "test_outer_folder")
),
}
],
diff --git a/python_files/tests/unittestadapter/test_coverage.py b/python_files/tests/unittestadapter/test_coverage.py
new file mode 100644
index 000000000000..76fdfec43376
--- /dev/null
+++ b/python_files/tests/unittestadapter/test_coverage.py
@@ -0,0 +1,106 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+
+import coverage
+import pytest
+from packaging.version import Version
+
+sys.path.append(os.fspath(pathlib.Path(__file__).parent))
+
+python_files_path = pathlib.Path(__file__).parent.parent.parent
+sys.path.insert(0, os.fspath(python_files_path))
+sys.path.insert(0, os.fspath(python_files_path / "lib" / "python"))
+
+from tests.pytestadapter import helpers # noqa: E402
+
+TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
+
+
+def test_basic_coverage():
+ """This test runs on a simple django project with three tests, two of which pass and one that fails."""
+ coverage_ex_folder: pathlib.Path = TEST_DATA_PATH / "coverage_ex"
+ execution_script: pathlib.Path = python_files_path / "unittestadapter" / "execution.py"
+ test_ids = [
+ "test_reverse.TestReverseFunctions.test_reverse_sentence",
+ "test_reverse.TestReverseFunctions.test_reverse_sentence_error",
+ "test_reverse.TestReverseFunctions.test_reverse_string",
+ ]
+ argv = [os.fsdecode(execution_script), "--udiscovery", "-vv", "-s", ".", "-p", "*test*.py"]
+ argv = argv + test_ids
+
+ actual = helpers.runner_with_cwd_env(
+ argv,
+ coverage_ex_folder,
+ {"COVERAGE_ENABLED": os.fspath(coverage_ex_folder), "_TEST_VAR_UNITTEST": "True"},
+ )
+
+ assert actual
+ cov = actual[-1]
+ assert cov
+ results = cov["result"]
+ assert results
+ assert len(results) == 3
+ focal_function_coverage = results.get(os.fspath(TEST_DATA_PATH / "coverage_ex" / "reverse.py"))
+ assert focal_function_coverage
+ assert focal_function_coverage.get("lines_covered") is not None
+ assert focal_function_coverage.get("lines_missed") is not None
+ assert set(focal_function_coverage.get("lines_covered")) == {4, 5, 7, 9, 10, 11, 12, 13, 14}
+ assert set(focal_function_coverage.get("lines_missed")) == {6}
+ coverage_version = Version(coverage.__version__)
+ # only include check for branches if the version is >= 7.7.0
+ if coverage_version >= Version("7.7.0"):
+ assert focal_function_coverage.get("executed_branches") == 3
+ assert focal_function_coverage.get("total_branches") == 4
+
+
+@pytest.mark.parametrize("manage_py_file", ["manage.py", "old_manage.py"])
+@pytest.mark.timeout(30)
+def test_basic_django_coverage(manage_py_file):
+ """This test validates that the coverage is correctly calculated for a Django project."""
+ data_path: pathlib.Path = TEST_DATA_PATH / "simple_django"
+ manage_py_path: str = os.fsdecode(data_path / manage_py_file)
+ execution_script: pathlib.Path = python_files_path / "unittestadapter" / "execution.py"
+
+ test_ids = [
+ "polls.tests.QuestionModelTests.test_was_published_recently_with_future_question",
+ "polls.tests.QuestionModelTests.test_was_published_recently_with_future_question_2",
+ "polls.tests.QuestionModelTests.test_question_creation_and_retrieval",
+ ]
+
+ script_str = os.fsdecode(execution_script)
+ actual = helpers.runner_with_cwd_env(
+ [script_str, "--udiscovery", "-p", "*test*.py", *test_ids],
+ data_path,
+ {
+ "MANAGE_PY_PATH": manage_py_path,
+ "_TEST_VAR_UNITTEST": "True",
+ "COVERAGE_ENABLED": os.fspath(data_path),
+ },
+ )
+
+ assert actual
+ cov = actual[-1]
+ assert cov
+ results = cov["result"]
+ assert results
+ assert len(results) == 16
+ polls_views_coverage = results.get(str(data_path / "polls" / "views.py"))
+ assert polls_views_coverage
+ assert polls_views_coverage.get("lines_covered") is not None
+ assert polls_views_coverage.get("lines_missed") is not None
+ assert set(polls_views_coverage.get("lines_covered")) == {3, 4, 6}
+ assert set(polls_views_coverage.get("lines_missed")) == {7}
+
+ model_cov = results.get(str(data_path / "polls" / "models.py"))
+ coverage_version = Version(coverage.__version__)
+ # only include check for branches if the version is >= 7.7.0
+ if coverage_version >= Version("7.7.0"):
+ assert model_cov.get("executed_branches") == 1
+ assert model_cov.get("total_branches") == 2
diff --git a/python_files/tests/unittestadapter/test_discovery.py b/python_files/tests/unittestadapter/test_discovery.py
new file mode 100644
index 000000000000..ab028ef176c3
--- /dev/null
+++ b/python_files/tests/unittestadapter/test_discovery.py
@@ -0,0 +1,447 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+from typing import Any, Dict, List
+
+import pytest
+
+from unittestadapter.discovery import discover_tests
+from unittestadapter.pvsc_utils import TestNodeTypeEnum, parse_unittest_args
+
+script_dir = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
+
+from tests.pytestadapter import helpers # noqa: E402
+from tests.tree_comparison_helper import is_same_tree # noqa: E402
+
+from . import expected_discovery_test_output # noqa: E402
+
+TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
+
+
+@pytest.mark.parametrize(
+ ("args", "expected"),
+ [
+ (
+ ["-s", "something", "-p", "other*", "-t", "else"],
+ ("something", "other*", "else", 1, None, None),
+ ),
+ (
+ [
+ "--start-directory",
+ "foo",
+ "--pattern",
+ "bar*",
+ "--top-level-directory",
+ "baz",
+ ],
+ ("foo", "bar*", "baz", 1, None, None),
+ ),
+ (
+ ["--foo", "something"],
+ (".", "test*.py", None, 1, None, None),
+ ),
+ (
+ ["--foo", "something", "-v"],
+ (".", "test*.py", None, 2, None, None),
+ ),
+ (
+ ["--foo", "something", "-f"],
+ (".", "test*.py", None, 1, True, None),
+ ),
+ (
+ ["--foo", "something", "--verbose", "-f"],
+ (".", "test*.py", None, 2, True, None),
+ ),
+ (
+ ["--foo", "something", "-q", "--failfast"],
+ (".", "test*.py", None, 0, True, None),
+ ),
+ (
+ ["--foo", "something", "--quiet"],
+ (".", "test*.py", None, 0, None, None),
+ ),
+ (
+ ["--foo", "something", "--quiet", "--locals"],
+ (".", "test*.py", None, 0, None, True),
+ ),
+ ],
+)
+def test_parse_unittest_args(args: List[str], expected: List[str]) -> None:
+ """The parse_unittest_args function should return values for the start_dir, pattern, and top_level_dir arguments when passed as command-line options, and ignore unrecognized arguments."""
+ actual = parse_unittest_args(args)
+
+ assert actual == expected
+
+
+def test_simple_discovery() -> None:
+ """The discover_tests function should return a dictionary with a "success" status, no errors, and a test tree if unittest discovery was performed successfully."""
+ start_dir = os.fsdecode(TEST_DATA_PATH)
+ pattern = "discovery_simple*"
+ file_path = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH / "discovery_simple.py"))
+
+ expected = {
+ "path": start_dir,
+ "type_": TestNodeTypeEnum.folder,
+ "name": ".data",
+ "children": [
+ {
+ "name": "discovery_simple.py",
+ "type_": TestNodeTypeEnum.file,
+ "path": file_path,
+ "children": [
+ {
+ "name": "DiscoverySimple",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.class_,
+ "children": [
+ {
+ "name": "test_one",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.test,
+ "lineno": "14",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_one",
+ },
+ {
+ "name": "test_two",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.test,
+ "lineno": "17",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_two",
+ },
+ ],
+ "id_": file_path + "\\" + "DiscoverySimple",
+ }
+ ],
+ "id_": file_path,
+ }
+ ],
+ "id_": start_dir,
+ }
+
+ actual = discover_tests(start_dir, pattern, None)
+
+ assert actual["status"] == "success"
+ assert is_same_tree(actual.get("tests"), expected, ["id_", "lineno", "name"])
+ assert "error" not in actual
+
+
+def test_simple_discovery_with_top_dir_calculated() -> None:
+ """The discover_tests function should return a dictionary with a "success" status, no errors, and a test tree if unittest discovery was performed successfully."""
+ start_dir = "."
+ pattern = "discovery_simple*"
+ file_path = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH / "discovery_simple.py"))
+
+ expected = {
+ "path": os.fsdecode(pathlib.PurePath(TEST_DATA_PATH)),
+ "type_": TestNodeTypeEnum.folder,
+ "name": ".data",
+ "children": [
+ {
+ "name": "discovery_simple.py",
+ "type_": TestNodeTypeEnum.file,
+ "path": file_path,
+ "children": [
+ {
+ "name": "DiscoverySimple",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.class_,
+ "children": [
+ {
+ "name": "test_one",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.test,
+ "lineno": "14",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_one",
+ },
+ {
+ "name": "test_two",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.test,
+ "lineno": "17",
+ "id_": file_path + "\\" + "DiscoverySimple" + "\\" + "test_two",
+ },
+ ],
+ "id_": file_path + "\\" + "DiscoverySimple",
+ }
+ ],
+ "id_": file_path,
+ }
+ ],
+ "id_": os.fsdecode(pathlib.PurePath(TEST_DATA_PATH)),
+ }
+
+ # Define the CWD to be the root of the test data folder.
+ os.chdir(os.fsdecode(pathlib.PurePath(TEST_DATA_PATH)))
+ actual = discover_tests(start_dir, pattern, None)
+
+ assert actual["status"] == "success"
+ assert is_same_tree(actual.get("tests"), expected, ["id_", "lineno", "name"])
+ assert "error" not in actual
+
+
+def test_empty_discovery() -> None:
+ """The discover_tests function should return a dictionary with a "success" status, no errors, and no test tree if unittest discovery was performed successfully but no tests were found."""
+ start_dir = os.fsdecode(TEST_DATA_PATH)
+ pattern = "discovery_empty*"
+
+ actual = discover_tests(start_dir, pattern, None)
+
+ assert actual["status"] == "success"
+ assert "tests" in actual
+ assert "error" not in actual
+
+
+def test_error_discovery() -> None:
+ """The discover_tests function should return a dictionary with an "error" status, the discovered tests, and a list of errors if unittest discovery failed at some point."""
+ # Discover tests in .data/discovery_error/.
+ start_path = pathlib.PurePath(TEST_DATA_PATH / "discovery_error")
+ start_dir = os.fsdecode(start_path)
+ pattern = "file*"
+
+ file_path = os.fsdecode(start_path / "file_two.py")
+
+ expected = {
+ "path": start_dir,
+ "type_": TestNodeTypeEnum.folder,
+ "name": "discovery_error",
+ "children": [
+ {
+ "name": "file_two.py",
+ "type_": TestNodeTypeEnum.file,
+ "path": file_path,
+ "children": [
+ {
+ "name": "DiscoveryErrorTwo",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.class_,
+ "children": [
+ {
+ "name": "test_one",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.test,
+ "lineno": "14",
+ "id_": file_path + "\\" + "DiscoveryErrorTwo" + "\\" + "test_one",
+ },
+ {
+ "name": "test_two",
+ "path": file_path,
+ "type_": TestNodeTypeEnum.test,
+ "lineno": "17",
+ "id_": file_path + "\\" + "DiscoveryErrorTwo" + "\\" + "test_two",
+ },
+ ],
+ "id_": file_path + "\\" + "DiscoveryErrorTwo",
+ }
+ ],
+ "id_": file_path,
+ }
+ ],
+ "id_": start_dir,
+ }
+
+ actual = discover_tests(start_dir, pattern, None)
+
+ assert actual["status"] == "error"
+ assert is_same_tree(expected, actual.get("tests"), ["id_", "lineno", "name"])
+ assert len(actual.get("error", [])) == 1
+
+
+def test_unit_skip() -> None:
+ """The discover_tests function should return a dictionary with a "success" status, no errors, and test tree.
+
+ if unittest discovery was performed and found a test in one file marked as skipped and another file marked as skipped.
+ """
+ start_dir = os.fsdecode(TEST_DATA_PATH / "unittest_skip")
+ pattern = "unittest_*"
+
+ actual = discover_tests(start_dir, pattern, None)
+
+ assert actual["status"] == "success"
+ assert "tests" in actual
+ assert is_same_tree(
+ actual.get("tests"),
+ expected_discovery_test_output.skip_unittest_folder_discovery_output,
+ ["id_", "lineno", "name"],
+ )
+ assert "error" not in actual
+
+
+def test_complex_tree() -> None:
+ """This test specifically tests when different start_dir and top_level_dir are provided."""
+ start_dir = os.fsdecode(
+ pathlib.PurePath(
+ TEST_DATA_PATH,
+ "utils_complex_tree",
+ "test_outer_folder",
+ "test_inner_folder",
+ )
+ )
+ pattern = "test_*.py"
+ top_level_dir = os.fsdecode(pathlib.PurePath(TEST_DATA_PATH, "utils_complex_tree"))
+ actual = discover_tests(start_dir, pattern, top_level_dir)
+ assert actual["status"] == "success"
+ assert "error" not in actual
+ assert is_same_tree(
+ actual.get("tests"),
+ expected_discovery_test_output.complex_tree_expected_output,
+ ["id_", "lineno", "name"],
+ )
+
+
+def test_simple_django_collect():
+ test_data_path: pathlib.Path = pathlib.Path(__file__).parent / ".data"
+ python_files_path: pathlib.Path = pathlib.Path(__file__).parent.parent.parent
+ discovery_script_path: str = os.fsdecode(python_files_path / "unittestadapter" / "discovery.py")
+ data_path: pathlib.Path = test_data_path / "simple_django"
+ manage_py_path: str = os.fsdecode(pathlib.Path(data_path, "manage.py"))
+
+ actual = helpers.runner_with_cwd_env(
+ [
+ discovery_script_path,
+ "--udiscovery",
+ ],
+ data_path,
+ {"MANAGE_PY_PATH": manage_py_path},
+ )
+
+ assert actual
+ actual_list: List[Dict[str, Any]] = actual
+ assert actual_list is not None
+ if actual_list is not None:
+ actual_item = actual_list.pop(0)
+ assert all(item in actual_item for item in ("status", "cwd"))
+ assert actual_item.get("status") == "success", (
+ f"Status is not 'success', error is: {actual_item.get('error')}"
+ )
+ assert actual_item.get("cwd") == os.fspath(data_path)
+ assert len(actual_item["tests"]["children"]) == 1
+ assert actual_item["tests"]["children"][0]["children"][0]["id_"] == os.fsdecode(
+ pathlib.PurePath(test_data_path, "simple_django", "polls", "tests.py")
+ )
+ assert (
+ len(actual_item["tests"]["children"][0]["children"][0]["children"][0]["children"]) == 3
+ )
+
+
+def test_project_root_path_with_cwd_override() -> None:
+ """Test unittest discovery with project_root_path parameter.
+
+ This simulates project-based testing where the cwd in the payload should be
+ the project root (project_root_path) rather than the start_dir.
+
+ When project_root_path is provided:
+ - The cwd in the response should match project_root_path
+ - The test tree root should still be built correctly based on top_level_dir
+ """
+ # Use unittest_skip folder as our "project" directory
+ project_path = TEST_DATA_PATH / "unittest_skip"
+ start_dir = os.fsdecode(project_path)
+ pattern = "unittest_*"
+
+ # Call discover_tests with project_root_path to simulate PROJECT_ROOT_PATH
+ actual = discover_tests(start_dir, pattern, None, project_root_path=start_dir)
+
+ assert actual["status"] == "success"
+ # cwd in response should match the project_root_path (project root)
+ assert actual["cwd"] == os.fsdecode(project_path), (
+ f"Expected cwd '{os.fsdecode(project_path)}', got '{actual['cwd']}'"
+ )
+ assert "tests" in actual
+ # Verify the test tree structure matches expected output
+ assert is_same_tree(
+ actual.get("tests"),
+ expected_discovery_test_output.skip_unittest_folder_discovery_output,
+ ["id_", "lineno", "name"],
+ )
+ assert "error" not in actual
+
+
+def test_project_root_path_with_different_cwd_and_start_dir() -> None:
+ """Test unittest discovery where project_root_path differs from start_dir.
+
+ This simulates the scenario where:
+ - start_dir points to a subfolder where tests are located
+ - project_root_path (PROJECT_ROOT_PATH) points to the project root
+
+ The cwd in the response should be the project root, while discovery
+ still runs from the start_dir.
+ """
+ # Use utils_complex_tree as our test case - discovery from a subfolder
+ project_path = TEST_DATA_PATH / "utils_complex_tree"
+ start_dir = os.fsdecode(
+ pathlib.PurePath(
+ TEST_DATA_PATH,
+ "utils_complex_tree",
+ "test_outer_folder",
+ "test_inner_folder",
+ )
+ )
+ pattern = "test_*.py"
+ top_level_dir = os.fsdecode(project_path)
+
+ # Call discover_tests with project_root_path set to project root
+ actual = discover_tests(start_dir, pattern, top_level_dir, project_root_path=top_level_dir)
+
+ assert actual["status"] == "success"
+ # cwd should be the project root (project_root_path), not the start_dir
+ assert actual["cwd"] == os.fsdecode(project_path), (
+ f"Expected cwd '{os.fsdecode(project_path)}', got '{actual['cwd']}'"
+ )
+ assert "error" not in actual
+ # Test tree should still be structured correctly with top_level_dir as root
+ assert is_same_tree(
+ actual.get("tests"),
+ expected_discovery_test_output.complex_tree_expected_output,
+ ["id_", "lineno", "name"],
+ )
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="Symlinks require elevated privileges on Windows",
+)
+def test_symlink_with_project_root_path() -> None:
+ """Test unittest discovery with both symlink and PROJECT_ROOT_PATH set.
+
+ This tests the combination of:
+ 1. A symlinked test directory
+ 2. project_root_path (PROJECT_ROOT_PATH) set to the symlink path
+
+ This simulates project-based testing where the project root is a symlink,
+ ensuring test IDs and paths are correctly resolved through the symlink.
+ """
+ with helpers.create_symlink(TEST_DATA_PATH, "unittest_skip", "symlink_unittest") as (
+ _source,
+ destination,
+ ):
+ assert destination.is_symlink()
+
+ # Run discovery with:
+ # - start_dir pointing to the symlink destination
+ # - project_root_path set to the symlink destination (simulating PROJECT_ROOT_PATH)
+ start_dir = os.fsdecode(destination)
+ pattern = "unittest_*"
+
+ actual = discover_tests(start_dir, pattern, None, project_root_path=start_dir)
+
+ assert actual["status"] == "success", (
+ f"Status is not 'success', error is: {actual.get('error')}"
+ )
+ # cwd should be the symlink path (project_root_path)
+ assert actual["cwd"] == os.fsdecode(destination), (
+ f"CWD does not match symlink path: expected {os.fsdecode(destination)}, got {actual['cwd']}"
+ )
+ assert "tests" in actual
+ assert actual["tests"] is not None
+ # The test tree root should be named after the symlink directory
+ assert actual["tests"]["name"] == "symlink_unittest", (
+ f"Expected root name 'symlink_unittest', got '{actual['tests']['name']}'"
+ )
+ # The test tree root path should use the symlink path
+ assert actual["tests"]["path"] == os.fsdecode(destination), (
+ f"Expected root path to be symlink, got '{actual['tests']['path']}'"
+ )
diff --git a/python_files/tests/unittestadapter/test_execution.py b/python_files/tests/unittestadapter/test_execution.py
new file mode 100644
index 000000000000..cab03f0b5dc4
--- /dev/null
+++ b/python_files/tests/unittestadapter/test_execution.py
@@ -0,0 +1,474 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+from typing import TYPE_CHECKING, Any, Dict, List, Optional
+from unittest.mock import patch
+
+import pytest
+
+sys.path.append(os.fspath(pathlib.Path(__file__).parent))
+
+python_files_path = pathlib.Path(__file__).parent.parent.parent
+sys.path.insert(0, os.fspath(python_files_path))
+sys.path.insert(0, os.fspath(python_files_path / "lib" / "python"))
+
+from tests.pytestadapter import helpers # noqa: E402
+from unittestadapter.execution import run_tests # noqa: E402
+
+if TYPE_CHECKING:
+ from unittestadapter.pvsc_utils import ExecutionPayloadDict
+
+TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
+
+
+def test_no_ids_run() -> None:
+ """This test runs on an empty array of test_ids, therefore it should return an empty dict for the result."""
+ start_dir: str = os.fspath(TEST_DATA_PATH)
+ testids = []
+ pattern = "discovery_simple*"
+ actual = run_tests(start_dir, testids, pattern, None, 1, None)
+ assert actual
+ assert all(item in actual for item in ("cwd", "status"))
+ assert actual["status"] == "success"
+ assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
+ if actual["result"] is not None:
+ assert len(actual["result"]) == 0
+ else:
+ raise AssertionError("actual['result'] is None")
+
+
+@pytest.fixture
+def mock_send_run_data():
+ with patch("unittestadapter.execution.send_run_data") as mock:
+ yield mock
+
+
+def test_single_ids_run(mock_send_run_data):
+ """This test runs on a single test_id, therefore it should return a dict with a single key-value pair for the result.
+
+ This single test passes so the outcome should be 'success'.
+ """
+ id_ = "discovery_simple.DiscoverySimple.test_one"
+ os.environ["TEST_RUN_PIPE"] = "fake"
+ actual: ExecutionPayloadDict = run_tests(
+ os.fspath(TEST_DATA_PATH),
+ [id_],
+ "discovery_simple*",
+ None,
+ 1,
+ None,
+ )
+
+ # Access the arguments
+ args, _ = mock_send_run_data.call_args
+ test_actual = args[0] # first argument is the result
+
+ assert test_actual
+ actual_result: Optional[Dict[str, Dict[str, Optional[str]]]] = actual["result"]
+ if actual_result is None:
+ raise AssertionError("actual_result is None")
+ else:
+ if not isinstance(actual_result, Dict):
+ raise AssertionError("actual_result is not a Dict")
+ assert len(actual_result) == 1
+ assert id_ in actual_result
+ id_result = actual_result[id_]
+ assert id_result is not None
+ assert "outcome" in id_result
+ assert id_result["outcome"] == "success"
+
+
+def test_subtest_run(mock_send_run_data) -> None: # noqa: ARG001
+ """This test runs on a the test_subtest which has a single method, test_even, that uses unittest subtest.
+
+ The actual result of run should return a dict payload with 6 entry for the 6 subtests.
+ """
+ id_ = "test_subtest.NumbersTest.test_even"
+ os.environ["TEST_RUN_PIPE"] = "fake"
+ actual = run_tests(
+ os.fspath(TEST_DATA_PATH),
+ [id_],
+ "test_subtest.py",
+ None,
+ 1,
+ None,
+ )
+ subtests_ids = [
+ "test_subtest.NumbersTest.test_even (i=0)",
+ "test_subtest.NumbersTest.test_even (i=1)",
+ "test_subtest.NumbersTest.test_even (i=2)",
+ "test_subtest.NumbersTest.test_even (i=3)",
+ "test_subtest.NumbersTest.test_even (i=4)",
+ "test_subtest.NumbersTest.test_even (i=5)",
+ ]
+ assert actual
+ assert all(item in actual for item in ("cwd", "status"))
+ assert actual["status"] == "success"
+ assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
+ assert actual["result"] is not None
+ result = actual["result"]
+ assert len(result) == 6
+ for id_ in subtests_ids:
+ assert id_ in result
+
+
+@pytest.mark.parametrize(
+ ("test_ids", "pattern", "cwd", "expected_outcome"),
+ [
+ (
+ [
+ "test_add.TestAddFunction.test_add_negative_numbers",
+ "test_add.TestAddFunction.test_add_positive_numbers",
+ ],
+ "test_add.py",
+ os.fspath(TEST_DATA_PATH / "unittest_folder"),
+ "success",
+ ),
+ (
+ [
+ "test_add.TestAddFunction.test_add_negative_numbers",
+ "test_add.TestAddFunction.test_add_positive_numbers",
+ "test_subtract.TestSubtractFunction.test_subtract_negative_numbers",
+ "test_subtract.TestSubtractFunction.test_subtract_positive_numbers",
+ ],
+ "test*",
+ os.fspath(TEST_DATA_PATH / "unittest_folder"),
+ "success",
+ ),
+ (
+ [
+ "pattern_a_test.DiscoveryA.test_one_a",
+ "pattern_a_test.DiscoveryA.test_two_a",
+ ],
+ "*test.py",
+ os.fspath(TEST_DATA_PATH / "two_patterns"),
+ "success",
+ ),
+ (
+ [
+ "test_pattern_b.DiscoveryB.test_one_b",
+ "test_pattern_b.DiscoveryB.test_two_b",
+ ],
+ "test_*",
+ os.fspath(TEST_DATA_PATH / "two_patterns"),
+ "success",
+ ),
+ (
+ [
+ "file_one.CaseTwoFileOne.test_one",
+ "file_one.CaseTwoFileOne.test_two",
+ "folder.file_two.CaseTwoFileTwo.test_one",
+ "folder.file_two.CaseTwoFileTwo.test_two",
+ ],
+ "*",
+ os.fspath(TEST_DATA_PATH / "utils_nested_cases"),
+ "success",
+ ),
+ (
+ [
+ "test_two_classes.ClassOne.test_one",
+ "test_two_classes.ClassTwo.test_two",
+ ],
+ "test_two_classes.py",
+ os.fspath(TEST_DATA_PATH),
+ "success",
+ ),
+ (
+ [
+ "test_scene.TestMathOperations.test_operations(add)",
+ "test_scene.TestMathOperations.test_operations(subtract)",
+ "test_scene.TestMathOperations.test_operations(multiply)",
+ ],
+ "*",
+ os.fspath(TEST_DATA_PATH / "test_scenarios" / "tests"),
+ "success",
+ ),
+ ],
+)
+def test_multiple_ids_run(mock_send_run_data, test_ids, pattern, cwd, expected_outcome) -> None: # noqa: ARG001
+ """
+ The following are all successful tests of different formats.
+
+ # 1. Two tests with the `pattern` specified as a file
+ # 2. Two test files in the same folder called `unittest_folder`
+ # 3. A folder with two different test file patterns, this test gathers pattern `*test`
+ # 4. A folder with two different test file patterns, this test gathers pattern `test_*`
+ # 5. A nested structure where a test file is on the same level as a folder containing a test file
+ # 6. Test file with two test classes
+
+ All tests should have the outcome of `success`.
+ """
+ os.environ["TEST_RUN_PIPE"] = "fake"
+ actual = run_tests(cwd, test_ids, pattern, None, 1, None)
+ assert actual
+ assert all(item in actual for item in ("cwd", "status"))
+ assert actual["status"] == "success"
+ assert actual["cwd"] == cwd
+ assert actual["result"] is not None
+ result = actual["result"]
+ assert len(result) == len(test_ids)
+ for test_id in test_ids:
+ assert test_id in result
+ id_result = result[test_id]
+ assert id_result is not None
+ assert "outcome" in id_result
+ assert id_result["outcome"] == expected_outcome
+ assert True
+
+
+def test_failed_tests(mock_send_run_data): # noqa: ARG001
+ """This test runs on a single file `test_fail` with two tests that fail."""
+ os.environ["TEST_RUN_PIPE"] = "fake"
+ test_ids = [
+ "test_fail_simple.RunFailSimple.test_one_fail",
+ "test_fail_simple.RunFailSimple.test_two_fail",
+ ]
+ actual = run_tests(
+ os.fspath(TEST_DATA_PATH),
+ test_ids,
+ "test_fail_simple*",
+ None,
+ 1,
+ None,
+ )
+ assert actual
+ assert all(item in actual for item in ("cwd", "status"))
+ assert actual["status"] == "success"
+ assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
+ assert actual["result"] is not None
+ result = actual["result"]
+ assert len(result) == len(test_ids)
+ for test_id in test_ids:
+ assert test_id in result
+ id_result = result[test_id]
+ assert id_result is not None
+ assert "outcome" in id_result
+ assert id_result["outcome"] == "failure"
+ assert "message" in id_result
+ assert "traceback" in id_result
+ assert "2 not greater than 3" in str(id_result["message"]) or "1 == 1" in str(
+ id_result["traceback"]
+ )
+ assert True
+
+
+def test_unknown_id(mock_send_run_data): # noqa: ARG001
+ """This test runs on a unknown test_id, therefore it should return an error as the outcome as it attempts to find the given test."""
+ os.environ["TEST_RUN_PIPE"] = "fake"
+ test_ids = ["unknown_id"]
+ actual = run_tests(
+ os.fspath(TEST_DATA_PATH),
+ test_ids,
+ "test_fail_simple*",
+ None,
+ 1,
+ None,
+ )
+ assert actual
+ assert all(item in actual for item in ("cwd", "status"))
+ assert actual["status"] == "success"
+ assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
+ assert actual["result"] is not None
+ result = actual["result"]
+ assert len(result) == len(test_ids)
+ assert "unittest.loader._FailedTest.unknown_id" in result
+ id_result = result["unittest.loader._FailedTest.unknown_id"]
+ assert id_result is not None
+ assert "outcome" in id_result
+ assert id_result["outcome"] == "error"
+ assert "message" in id_result
+ assert "traceback" in id_result
+
+
+def test_incorrect_path():
+ """This test runs on a non existent path, therefore it should return an error as the outcome as it attempts to find the given folder."""
+ test_ids = ["unknown_id"]
+ os.environ["TEST_RUN_PIPE"] = "fake"
+
+ actual = run_tests(
+ os.fspath(TEST_DATA_PATH / "unknown_folder"),
+ test_ids,
+ "test_fail_simple*",
+ None,
+ 1,
+ None,
+ )
+ assert actual
+ assert all(item in actual for item in ("cwd", "status", "error"))
+ assert actual["status"] == "error"
+ assert actual["cwd"] == os.fspath(TEST_DATA_PATH / "unknown_folder")
+
+
+def test_basic_run_django():
+ """This test runs on a simple django project with three tests, two of which pass and one that fails."""
+ data_path: pathlib.Path = TEST_DATA_PATH / "simple_django"
+ manage_py_path: str = os.fsdecode(data_path / "manage.py")
+ execution_script: pathlib.Path = (
+ pathlib.Path(__file__).parent / "django_test_execution_script.py"
+ )
+
+ test_ids = [
+ "polls.tests.QuestionModelTests.test_was_published_recently_with_future_question",
+ "polls.tests.QuestionModelTests.test_was_published_recently_with_future_question_2",
+ "polls.tests.QuestionModelTests.test_question_creation_and_retrieval",
+ ]
+ script_str = os.fsdecode(execution_script)
+ actual = helpers.runner_with_cwd_env(
+ [script_str, manage_py_path, *test_ids],
+ data_path,
+ {"MANAGE_PY_PATH": manage_py_path},
+ )
+ assert actual
+ actual_list: List[Dict[str, Dict[str, Any]]] = actual
+ actual_result_dict = {}
+ assert len(actual_list) == 3
+ for actual_item in actual_list:
+ assert all(item in actual_item for item in ("status", "cwd", "result"))
+ assert actual_item.get("cwd") == os.fspath(data_path)
+ actual_result_dict.update(actual_item["result"])
+ for test_id in test_ids:
+ assert test_id in actual_result_dict
+ id_result = actual_result_dict[test_id]
+ assert id_result is not None
+ assert "outcome" in id_result
+ if (
+ test_id
+ == "polls.tests.QuestionModelTests.test_was_published_recently_with_future_question_2"
+ ):
+ assert id_result["outcome"] == "failure"
+ else:
+ assert id_result["outcome"] == "success"
+
+
+def test_project_root_path_with_cwd_override(mock_send_run_data) -> None: # noqa: ARG001
+ """Test unittest execution with project_root_path parameter.
+
+ This simulates project-based testing where the cwd in the payload should be
+ the project root (project_root_path) rather than the start_dir.
+
+ When project_root_path is provided:
+ - The cwd in the response should match project_root_path
+ - Test execution should still work correctly with start_dir
+ """
+ # Use unittest_folder as our "project" directory
+ project_path = TEST_DATA_PATH / "unittest_folder"
+ start_dir = os.fsdecode(project_path)
+ pattern = "test_add*"
+ test_ids = [
+ "test_add.TestAddFunction.test_add_positive_numbers",
+ ]
+
+ os.environ["TEST_RUN_PIPE"] = "fake"
+
+ # Call run_tests with project_root_path to simulate PROJECT_ROOT_PATH
+ actual = run_tests(
+ start_dir,
+ test_ids,
+ pattern,
+ None,
+ 1,
+ None,
+ project_root_path=start_dir,
+ )
+
+ assert actual["status"] == "success"
+ # cwd in response should match the project_root_path (project root)
+ assert actual["cwd"] == os.fsdecode(project_path), (
+ f"Expected cwd '{os.fsdecode(project_path)}', got '{actual['cwd']}'"
+ )
+ assert actual["result"] is not None
+ assert test_ids[0] in actual["result"]
+ assert actual["result"][test_ids[0]]["outcome"] == "success"
+
+
+def test_project_root_path_with_different_cwd_and_start_dir(mock_send_run_data) -> None: # noqa: ARG001
+ """Test unittest execution where project_root_path differs from start_dir.
+
+ This simulates the scenario where:
+ - start_dir points to a subfolder where tests are located
+ - project_root_path (PROJECT_ROOT_PATH) points to the project root
+
+ The cwd in the response should be the project root, while execution
+ still runs from the start_dir.
+ """
+ # Use utils_nested_cases as our test case
+ project_path = TEST_DATA_PATH / "utils_nested_cases"
+ start_dir = os.fsdecode(project_path)
+ pattern = "*"
+ test_ids = [
+ "file_one.CaseTwoFileOne.test_one",
+ ]
+
+ os.environ["TEST_RUN_PIPE"] = "fake"
+
+ # Call run_tests with project_root_path set to project root
+ actual = run_tests(
+ start_dir,
+ test_ids,
+ pattern,
+ None,
+ 1,
+ None,
+ project_root_path=os.fsdecode(project_path),
+ )
+
+ assert actual["status"] == "success"
+ # cwd should be the project root (project_root_path)
+ assert actual["cwd"] == os.fsdecode(project_path), (
+ f"Expected cwd '{os.fsdecode(project_path)}', got '{actual['cwd']}'"
+ )
+ assert actual["result"] is not None
+ assert test_ids[0] in actual["result"]
+
+
+@pytest.mark.skipif(
+ sys.platform == "win32",
+ reason="Symlinks require elevated privileges on Windows",
+)
+def test_symlink_with_project_root_path(mock_send_run_data) -> None: # noqa: ARG001
+ """Test unittest execution with both symlink and project_root_path set.
+
+ This tests the combination of:
+ 1. A symlinked test directory
+ 2. project_root_path (PROJECT_ROOT_PATH) set to the symlink path
+
+ This simulates project-based testing where the project root is a symlink,
+ ensuring execution payloads correctly use the symlink path.
+ """
+ with helpers.create_symlink(TEST_DATA_PATH, "unittest_folder", "symlink_unittest_exec") as (
+ _source,
+ destination,
+ ):
+ assert destination.is_symlink()
+
+ # Run execution with:
+ # - start_dir pointing to the symlink destination
+ # - project_root_path set to the symlink destination (simulating PROJECT_ROOT_PATH)
+ start_dir = os.fsdecode(destination)
+ pattern = "test_add*"
+ test_ids = [
+ "test_add.TestAddFunction.test_add_positive_numbers",
+ ]
+
+ os.environ["TEST_RUN_PIPE"] = "fake"
+
+ actual = run_tests(
+ start_dir,
+ test_ids,
+ pattern,
+ None,
+ 1,
+ None,
+ project_root_path=start_dir,
+ )
+
+ assert actual["status"] == "success", (
+ f"Status is not 'success', error is: {actual.get('error')}"
+ )
+ # cwd should be the symlink path (project_root_path)
+ assert actual["cwd"] == os.fsdecode(destination), (
+ f"CWD does not match symlink path: expected {os.fsdecode(destination)}, got {actual['cwd']}"
+ )
diff --git a/pythonFiles/tests/unittestadapter/test_utils.py b/python_files/tests/unittestadapter/test_utils.py
similarity index 76%
rename from pythonFiles/tests/unittestadapter/test_utils.py
rename to python_files/tests/unittestadapter/test_utils.py
index 9fe2af8256cd..dc8a81175e70 100644
--- a/pythonFiles/tests/unittestadapter/test_utils.py
+++ b/python_files/tests/unittestadapter/test_utils.py
@@ -3,6 +3,7 @@
import os
import pathlib
+import sys
import unittest
import pytest
@@ -15,11 +16,16 @@
get_test_case,
)
-from .helpers import TEST_DATA_PATH, is_same_tree
+script_dir = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
+
+from tests.tree_comparison_helper import is_same_tree # noqa: E402
+
+TEST_DATA_PATH = pathlib.Path(__file__).parent / ".data"
@pytest.mark.parametrize(
- "directory, pattern, expected",
+ ("directory", "pattern", "expected"),
[
(
".",
@@ -43,7 +49,6 @@
)
def test_simple_test_cases(directory, pattern, expected) -> None:
"""The get_test_case fuction should return tests from all test suites."""
-
actual = []
# Discover tests in .data/.
@@ -53,15 +58,13 @@ def test_simple_test_cases(directory, pattern, expected) -> None:
suite = loader.discover(start_dir, pattern)
# Iterate on get_test_case and save the test id.
- for test in get_test_case(suite):
- actual.append(test.id())
+ actual = [test.id() for test in get_test_case(suite)]
assert expected == actual
def test_get_existing_child_node() -> None:
"""The get_child_node fuction should return the child node of a test tree if it exists."""
-
tree: TestNode = {
"name": "root",
"path": "foo",
@@ -104,12 +107,11 @@ def test_get_existing_child_node() -> None:
tree_copy = tree.copy()
# Check that the tree didn't get mutated by get_child_node.
- assert is_same_tree(tree, tree_copy)
+ assert is_same_tree(tree, tree_copy, ["id_", "lineno", "name"])
def test_no_existing_child_node() -> None:
"""The get_child_node fuction should add a child node to a test tree and return it if it does not exist."""
-
tree: TestNode = {
"name": "root",
"path": "foo",
@@ -158,7 +160,7 @@ def test_no_existing_child_node() -> None:
tree_after["children"] = tree_after["children"][:-1]
# Check that all pre-existing items in the tree didn't get mutated by get_child_node.
- assert is_same_tree(tree_before, tree_after)
+ assert is_same_tree(tree_before, tree_after, ["id_", "lineno", "name"])
# Check for the added node.
last_child = tree["children"][-1]
@@ -166,10 +168,7 @@ def test_no_existing_child_node() -> None:
def test_build_simple_tree() -> None:
- """The build_test_tree function should build and return a test tree from discovered test suites,
- and an empty list of errors if there are none in the discovered data.
- """
-
+ """The build_test_tree function should build and return a test tree from discovered test suites, and an empty list of errors if there are none in the discovered data."""
# Discovery tests in utils_simple_tree.py.
start_dir = os.fsdecode(TEST_DATA_PATH)
pattern = "utils_simple_tree*"
@@ -220,16 +219,12 @@ def test_build_simple_tree() -> None:
suite = loader.discover(start_dir, pattern)
tests, errors = build_test_tree(suite, start_dir)
- assert is_same_tree(expected, tests)
+ assert is_same_tree(expected, tests, ["id_", "lineno", "name"])
assert not errors
def test_build_decorated_tree() -> None:
- """The build_test_tree function should build and return a test tree from discovered test suites,
- with correct line numbers for decorated test,
- and an empty list of errors if there are none in the discovered data.
- """
-
+ """The build_test_tree function should build and return a test tree from discovered test suites, with correct line numbers for decorated test, and an empty list of errors if there are none in the discovered data."""
# Discovery tests in utils_decorated_tree.py.
start_dir = os.fsdecode(TEST_DATA_PATH)
pattern = "utils_decorated_tree*"
@@ -280,22 +275,65 @@ def test_build_decorated_tree() -> None:
suite = loader.discover(start_dir, pattern)
tests, errors = build_test_tree(suite, start_dir)
- assert is_same_tree(expected, tests)
+ assert is_same_tree(expected, tests, ["id_", "lineno", "name"])
assert not errors
def test_build_empty_tree() -> None:
- """The build_test_tree function should return None if there are no discovered test suites,
- and an empty list of errors if there are none in the discovered data."""
-
+ """The build_test_tree function should return None if there are no discovered test suites, and an empty list of errors if there are none in the discovered data."""
start_dir = os.fsdecode(TEST_DATA_PATH)
pattern = "does_not_exist*"
- expected = None
-
loader = unittest.TestLoader()
suite = loader.discover(start_dir, pattern)
tests, errors = build_test_tree(suite, start_dir)
- assert expected == tests
+ assert tests is not None
+ assert tests.get("children") == []
assert not errors
+
+
+def test_doctest_standard_blocked() -> None:
+ """Standard doctests with short IDs should be skipped with an error message."""
+ start_dir = os.fsdecode(TEST_DATA_PATH)
+ pattern = "test_doctest_standard*"
+
+ loader = unittest.TestLoader()
+ suite = loader.discover(start_dir, pattern)
+ tests, errors = build_test_tree(suite, start_dir)
+
+ # Should return a tree but with no test children (since doctests are skipped)
+ assert tests is not None
+ # Check that we got an error about doctests not being supported
+ assert len(errors) > 0
+ assert "Skipping doctest as it is not supported for the extension" in errors[0]
+
+
+def test_doctest_patched_works() -> None:
+ """Patched doctests with properly formatted IDs should be processed normally."""
+ start_dir = os.fsdecode(TEST_DATA_PATH)
+ pattern = "test_doctest_patched*"
+
+ loader = unittest.TestLoader()
+ suite = loader.discover(start_dir, pattern)
+ tests, errors = build_test_tree(suite, start_dir)
+
+ # Should successfully build a tree with the patched doctest
+ assert tests is not None
+
+ # The patched doctests should have proper IDs and be included
+ # We should find at least one test child (the doctests that were patched)
+ def count_tests(node):
+ """Recursively count test nodes."""
+ if node.get("type_") == "test":
+ return 1
+ count = 0
+ for child in node.get("children", []):
+ count += count_tests(child)
+ return count
+
+ test_count = count_tests(tests)
+ # We expect at least the module doctest and function doctest
+ assert test_count > 0, "Patched doctests should be included in the tree"
+ # Should not have doctest-related errors since they're properly formatted
+ assert not any("doctest" in str(e).lower() for e in errors)
diff --git a/pythonFiles/tests/util.py b/python_files/tests/util.py
similarity index 85%
rename from pythonFiles/tests/util.py
rename to python_files/tests/util.py
index 45c3536145cf..ee240cd95202 100644
--- a/pythonFiles/tests/util.py
+++ b/python_files/tests/util.py
@@ -2,7 +2,7 @@
# Licensed under the MIT License.
-class Stub(object):
+class Stub:
def __init__(self):
self.calls = []
@@ -10,7 +10,7 @@ def add_call(self, name, args=None, kwargs=None):
self.calls.append((name, args, kwargs))
-class StubProxy(object):
+class StubProxy:
def __init__(self, stub=None, name=None):
self.name = name
self.stub = stub if stub is not None else Stub()
@@ -22,5 +22,5 @@ def calls(self):
def add_call(self, funcname, *args, **kwargs):
callname = funcname
if self.name:
- callname = "{}.{}".format(self.name, funcname)
+ callname = f"{self.name}.{funcname}"
return self.stub.add_call(callname, *args, **kwargs)
diff --git a/python_files/unittestadapter/__init__.py b/python_files/unittestadapter/__init__.py
new file mode 100644
index 000000000000..5b7f7a925cc0
--- /dev/null
+++ b/python_files/unittestadapter/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
diff --git a/python_files/unittestadapter/discovery.py b/python_files/unittestadapter/discovery.py
new file mode 100644
index 000000000000..c864ac76916b
--- /dev/null
+++ b/python_files/unittestadapter/discovery.py
@@ -0,0 +1,156 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+import traceback
+import unittest
+from typing import List, Optional
+
+script_dir = pathlib.Path(__file__).parent
+sys.path.append(os.fspath(script_dir))
+
+from django_handler import django_discovery_runner # noqa: E402
+
+# If I use from utils then there will be an import error in test_discovery.py.
+from unittestadapter.pvsc_utils import ( # noqa: E402
+ DiscoveryPayloadDict,
+ VSCodeUnittestError,
+ build_test_tree,
+ parse_unittest_args,
+ send_post_request,
+)
+
+
+def discover_tests(
+ start_dir: str,
+ pattern: str,
+ top_level_dir: Optional[str],
+ project_root_path: Optional[str] = None,
+) -> DiscoveryPayloadDict:
+ """Returns a dictionary containing details of the discovered tests.
+
+ The returned dict has the following keys:
+
+ - cwd: Absolute path to the test start directory (or project_root_path if provided);
+ - status: Test discovery status, can be "success" or "error";
+ - tests: Discoverered tests if any, not present otherwise. Note that the status can be "error" but the payload can still contain tests;
+ - error: Discovery error if any, not present otherwise.
+
+ Payload format for a successful discovery:
+ {
+ "status": "success",
+ "cwd": ,
+ "tests":
+ }
+
+ Payload format for a successful discovery with no tests:
+ {
+ "status": "success",
+ "cwd": ,
+ }
+
+ Payload format when there are errors:
+ {
+ "cwd":
+ "": [list of errors]
+ "status": "error",
+ }
+
+ Args:
+ start_dir: Directory where test discovery starts
+ pattern: Pattern to match test files (e.g., "test*.py")
+ top_level_dir: Top-level directory for the test tree hierarchy
+ project_root_path: Optional project root path for the cwd in the response payload
+ (used for project-based testing to root test tree at project)
+ """
+ cwd = os.path.abspath(project_root_path or start_dir) # noqa: PTH100
+ if "/" in start_dir: # is a subdir
+ parent_dir = os.path.dirname(start_dir) # noqa: PTH120
+ sys.path.insert(0, parent_dir)
+ else:
+ sys.path.insert(0, cwd)
+ payload: DiscoveryPayloadDict = {"cwd": cwd, "status": "success", "tests": None}
+ tests = None
+ error: List[str] = []
+
+ try:
+ loader = unittest.TestLoader()
+ suite = loader.discover(start_dir, pattern, top_level_dir)
+
+ # If the top level directory is not provided, then use the start directory.
+ if top_level_dir is None:
+ top_level_dir = start_dir
+
+ # Get abspath of top level directory for build_test_tree.
+ top_level_dir = os.path.abspath(top_level_dir) # noqa: PTH100
+
+ tests, error = build_test_tree(suite, top_level_dir) # test tree built successfully here.
+
+ except Exception:
+ error.append(traceback.format_exc())
+
+ # Still include the tests in the payload even if there are errors so that the TS
+ # side can determine if it is from run or discovery.
+ payload["tests"] = tests if tests is not None else None
+
+ if len(error):
+ payload["status"] = "error"
+ payload["error"] = error
+
+ return payload
+
+
+if __name__ == "__main__":
+ # Get unittest discovery arguments.
+ argv = sys.argv[1:]
+ index = argv.index("--udiscovery")
+
+ (
+ start_dir,
+ pattern,
+ top_level_dir,
+ _verbosity,
+ _failfast,
+ _locals,
+ ) = parse_unittest_args(argv[index + 1 :])
+
+ test_run_pipe = os.getenv("TEST_RUN_PIPE")
+ if not test_run_pipe:
+ error_msg = (
+ "UNITTEST ERROR: TEST_RUN_PIPE is not set at the time of unittest trying to send data. "
+ "Please confirm this environment variable is not being changed or removed "
+ "as it is required for successful test discovery and execution."
+ f"TEST_RUN_PIPE = {test_run_pipe}\n"
+ )
+ print(error_msg, file=sys.stderr)
+ raise VSCodeUnittestError(error_msg)
+
+ if manage_py_path := os.environ.get("MANAGE_PY_PATH"):
+ # Django configuration requires manage.py path to enable.
+ print(
+ f"MANAGE_PY_PATH is set, running Django discovery with path to manage.py as: ${manage_py_path}"
+ )
+ try:
+ # collect args for Django discovery runner.
+ args = argv[index + 1 :] or []
+ django_discovery_runner(manage_py_path, args)
+ except Exception as e:
+ error_msg = f"Error configuring Django test runner: {e}"
+ print(error_msg, file=sys.stderr)
+ raise VSCodeUnittestError(error_msg) # noqa: B904
+ else:
+ # Check for PROJECT_ROOT_PATH environment variable (project-based testing).
+ # When set, this overrides top_level_dir to root the test tree at the project directory.
+ project_root_path = os.environ.get("PROJECT_ROOT_PATH")
+ if project_root_path:
+ top_level_dir = project_root_path
+
+ # Perform regular unittest test discovery.
+ # Pass project_root_path so the payload's cwd matches the project root.
+ payload = discover_tests(
+ start_dir, pattern, top_level_dir, project_root_path=project_root_path
+ )
+ # Post this discovery payload.
+ send_post_request(payload, test_run_pipe)
diff --git a/python_files/unittestadapter/django_handler.py b/python_files/unittestadapter/django_handler.py
new file mode 100644
index 000000000000..574aee7af7fa
--- /dev/null
+++ b/python_files/unittestadapter/django_handler.py
@@ -0,0 +1,111 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import subprocess
+import sys
+from contextlib import contextmanager, suppress
+from typing import Generator, List
+
+script_dir = pathlib.Path(__file__).parent
+sys.path.append(os.fspath(script_dir))
+sys.path.insert(0, os.fspath(script_dir / "lib" / "python"))
+
+from pvsc_utils import ( # noqa: E402
+ VSCodeUnittestError,
+)
+
+
+@contextmanager
+def override_argv(argv: List[str]) -> Generator:
+ """Context manager to temporarily override sys.argv with the provided arguments."""
+ original_argv = sys.argv
+ sys.argv = argv
+ try:
+ yield
+ finally:
+ sys.argv = original_argv
+
+
+def django_discovery_runner(manage_py_path: str, args: List[str]) -> None:
+ # Attempt a small amount of validation on the manage.py path.
+ if not pathlib.Path(manage_py_path).exists():
+ raise VSCodeUnittestError("Error running Django, manage.py path does not exist.")
+
+ try:
+ # Get path to the custom_test_runner.py parent folder, add to sys.path and new environment used for subprocess.
+ custom_test_runner_dir = pathlib.Path(__file__).parent
+ sys.path.insert(0, os.fspath(custom_test_runner_dir))
+ env = os.environ.copy()
+ if "PYTHONPATH" in env:
+ env["PYTHONPATH"] = os.fspath(custom_test_runner_dir) + os.pathsep + env["PYTHONPATH"]
+ else:
+ env["PYTHONPATH"] = os.fspath(custom_test_runner_dir)
+
+ # Build command to run 'python manage.py test'.
+ command = [
+ sys.executable,
+ manage_py_path,
+ "test",
+ "--testrunner=django_test_runner.CustomDiscoveryTestRunner",
+ ]
+ command.extend(args)
+ print("Running Django tests with command:", command)
+
+ subprocess_discovery = subprocess.run(
+ command,
+ capture_output=True,
+ text=True,
+ env=env,
+ )
+ print(subprocess_discovery.stderr, file=sys.stderr)
+ print(subprocess_discovery.stdout, file=sys.stdout)
+ # Zero return code indicates success, 1 indicates test failures, so both are considered successful.
+ if subprocess_discovery.returncode not in (0, 1):
+ error_msg = "Django test discovery process exited with non-zero error code See stderr above for more details."
+ print(error_msg, file=sys.stderr)
+ except Exception as e:
+ raise VSCodeUnittestError(f"Error during Django discovery: {e}") # noqa: B904
+
+
+def django_execution_runner(manage_py_path: str, test_ids: List[str], args: List[str]) -> None:
+ manage_path: pathlib.Path = pathlib.Path(manage_py_path)
+ # Attempt a small amount of validation on the manage.py path.
+ if not manage_path.exists():
+ raise VSCodeUnittestError("Error running Django, manage.py path does not exist.")
+
+ try:
+ # Get path to the custom_test_runner.py parent folder, add to sys.path.
+ custom_test_runner_dir: pathlib.Path = pathlib.Path(__file__).parent
+ sys.path.insert(0, os.fspath(custom_test_runner_dir))
+ env: dict[str, str] = os.environ.copy()
+ if "PYTHONPATH" in env:
+ env["PYTHONPATH"] = os.fspath(custom_test_runner_dir) + os.pathsep + env["PYTHONPATH"]
+ else:
+ env["PYTHONPATH"] = os.fspath(custom_test_runner_dir)
+
+ django_project_dir: pathlib.Path = manage_path.parent
+ sys.path.insert(0, os.fspath(django_project_dir))
+ print(f"Django project directory: {django_project_dir}")
+
+ manage_argv: List[str] = [
+ str(manage_path),
+ "test",
+ "--testrunner=django_test_runner.CustomExecutionTestRunner",
+ *args,
+ *test_ids,
+ ]
+ print(f"Django manage.py arguments: {manage_argv}")
+
+ try:
+ argv_context = override_argv(manage_argv)
+ suppress_context = suppress(SystemExit)
+ manage_file = manage_path.open()
+ with argv_context, suppress_context, manage_file:
+ manage_code = manage_file.read()
+ exec(manage_code, {"__name__": "__main__", "__file__": manage_path})
+ except OSError as e:
+ raise VSCodeUnittestError("Error running Django, unable to read manage.py") from e
+ except Exception as e:
+ print(f"Error during Django test execution: {e}", file=sys.stderr)
diff --git a/python_files/unittestadapter/django_test_runner.py b/python_files/unittestadapter/django_test_runner.py
new file mode 100644
index 000000000000..c1cca7ac2780
--- /dev/null
+++ b/python_files/unittestadapter/django_test_runner.py
@@ -0,0 +1,95 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import os
+import pathlib
+import sys
+
+script_dir = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
+
+from typing import TYPE_CHECKING # noqa: E402
+
+from execution import UnittestTestResult # noqa: E402
+from pvsc_utils import ( # noqa: E402
+ DiscoveryPayloadDict,
+ VSCodeUnittestError,
+ build_test_tree,
+ send_post_request,
+)
+
+try:
+ from django.test.runner import DiscoverRunner
+except ImportError:
+ raise ImportError( # noqa: B904
+ "Django module not found. Please only use the environment variable MANAGE_PY_PATH if you want to use Django."
+ )
+
+
+if TYPE_CHECKING:
+ import unittest
+
+
+class CustomDiscoveryTestRunner(DiscoverRunner):
+ """Custom test runner for Django to handle test DISCOVERY and building the test tree."""
+
+ def run_tests(self, test_labels, **kwargs):
+ test_run_pipe: str | None = os.getenv("TEST_RUN_PIPE")
+ if not test_run_pipe:
+ error_msg = (
+ "UNITTEST ERROR: TEST_RUN_PIPE is not set at the time of unittest trying to send data. "
+ "Please confirm this environment variable is not being changed or removed "
+ "as it is required for successful test discovery and execution."
+ f"TEST_RUN_PIPE = {test_run_pipe}\n"
+ )
+ print(error_msg, file=sys.stderr)
+ raise VSCodeUnittestError(error_msg)
+ try:
+ top_level_dir: pathlib.Path = pathlib.Path.cwd()
+
+ # Discover tests and build into a tree.
+ suite: unittest.TestSuite = self.build_suite(test_labels, **kwargs)
+ tests, error = build_test_tree(suite, os.fspath(top_level_dir))
+
+ payload: DiscoveryPayloadDict = {
+ "cwd": os.fspath(top_level_dir),
+ "status": "success",
+ "tests": None,
+ }
+ payload["tests"] = tests if tests is not None else None
+ if len(error):
+ payload["status"] = "error"
+ payload["error"] = error
+
+ # Send discovery payload.
+ send_post_request(payload, test_run_pipe)
+ return 0 # Skip actual test execution, return 0 as no tests were run.
+ except Exception as e:
+ error_msg = (
+ "DJANGO ERROR: An error occurred while discovering and building the test suite. "
+ f"Error: {e}\n"
+ )
+ print(error_msg, file=sys.stderr)
+ raise VSCodeUnittestError(error_msg) # noqa: B904
+
+
+class CustomExecutionTestRunner(DiscoverRunner):
+ """Custom test runner for Django to handle test EXECUTION and uses UnittestTestResult to send dynamic run results."""
+
+ def get_test_runner_kwargs(self):
+ """Override to provide custom test runner; resultclass."""
+ test_run_pipe: str | None = os.getenv("TEST_RUN_PIPE")
+ if not test_run_pipe:
+ error_msg = (
+ "UNITTEST ERROR: TEST_RUN_PIPE is not set at the time of Django trying to send data. "
+ "Please confirm this environment variable is not being changed or removed "
+ "as it is required for successful test discovery and execution."
+ f"TEST_RUN_PIPE = {test_run_pipe}\n"
+ )
+ print(error_msg, file=sys.stderr)
+ raise VSCodeUnittestError(error_msg)
+ # Get existing kwargs
+ kwargs = super().get_test_runner_kwargs()
+ # Add custom resultclass, same resultclass as used in unittest.
+ kwargs["resultclass"] = UnittestTestResult
+ return kwargs
diff --git a/python_files/unittestadapter/execution.py b/python_files/unittestadapter/execution.py
new file mode 100644
index 000000000000..422f246d3476
--- /dev/null
+++ b/python_files/unittestadapter/execution.py
@@ -0,0 +1,427 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+import atexit
+import enum
+import os
+import pathlib
+import sys
+import sysconfig
+import traceback
+import unittest
+from types import TracebackType
+from typing import Dict, List, Optional, Set, Tuple, Type, Union
+
+# Adds the scripts directory to the PATH as a workaround for enabling shell for test execution.
+path_var_name = "PATH" if "PATH" in os.environ else "Path"
+os.environ[path_var_name] = (
+ sysconfig.get_paths()["scripts"] + os.pathsep + os.environ[path_var_name]
+)
+
+script_dir = pathlib.Path(__file__).parent
+sys.path.append(os.fspath(script_dir))
+
+from django_handler import django_execution_runner # noqa: E402
+
+from unittestadapter.pvsc_utils import ( # noqa: E402
+ CoveragePayloadDict,
+ ExecutionPayloadDict,
+ FileCoverageInfo,
+ TestExecutionStatus,
+ VSCodeUnittestError,
+ parse_unittest_args,
+ send_post_request,
+)
+
+ErrorType = Union[Tuple[Type[BaseException], BaseException, TracebackType], Tuple[None, None, None]]
+test_run_pipe = ""
+START_DIR = ""
+# PROJECT_ROOT_PATH: Used for project-based testing to override cwd in payload
+# When set, this should be used as the cwd in all execution payloads
+PROJECT_ROOT_PATH = None # type: Optional[str]
+
+
+class TestOutcomeEnum(str, enum.Enum):
+ error = "error"
+ failure = "failure"
+ success = "success"
+ skipped = "skipped"
+ expected_failure = "expected-failure"
+ unexpected_success = "unexpected-success"
+ subtest_success = "subtest-success"
+ subtest_failure = "subtest-failure"
+
+
+class UnittestTestResult(unittest.TextTestResult):
+ def __init__(self, *args, **kwargs):
+ self.formatted: Dict[str, Dict[str, Union[str, None]]] = {}
+ super().__init__(*args, **kwargs)
+
+ def startTest(self, test: unittest.TestCase): # noqa: N802
+ super().startTest(test)
+
+ def stopTestRun(self): # noqa: N802
+ super().stopTestRun()
+
+ def addError( # noqa: N802
+ self,
+ test: unittest.TestCase,
+ err: ErrorType,
+ ):
+ super().addError(test, err)
+ self.formatResult(test, TestOutcomeEnum.error, err)
+
+ def addFailure( # noqa: N802
+ self,
+ test: unittest.TestCase,
+ err: ErrorType,
+ ):
+ super().addFailure(test, err)
+ self.formatResult(test, TestOutcomeEnum.failure, err)
+
+ def addSuccess(self, test: unittest.TestCase): # noqa: N802
+ super().addSuccess(test)
+ self.formatResult(test, TestOutcomeEnum.success)
+
+ def addSkip(self, test: unittest.TestCase, reason: str): # noqa: N802
+ super().addSkip(test, reason)
+ self.formatResult(test, TestOutcomeEnum.skipped)
+
+ def addExpectedFailure(self, test: unittest.TestCase, err: ErrorType): # noqa: N802
+ super().addExpectedFailure(test, err)
+ self.formatResult(test, TestOutcomeEnum.expected_failure, err)
+
+ def addUnexpectedSuccess(self, test: unittest.TestCase): # noqa: N802
+ super().addUnexpectedSuccess(test)
+ self.formatResult(test, TestOutcomeEnum.unexpected_success)
+
+ def addSubTest( # noqa: N802
+ self,
+ test: unittest.TestCase,
+ subtest: unittest.TestCase,
+ err: Union[ErrorType, None],
+ ):
+ super().addSubTest(test, subtest, err)
+ self.formatResult(
+ test,
+ TestOutcomeEnum.subtest_failure if err else TestOutcomeEnum.subtest_success,
+ err,
+ subtest,
+ )
+
+ def formatResult( # noqa: N802
+ self,
+ test: unittest.TestCase,
+ outcome: str,
+ error: Union[ErrorType, None] = None,
+ subtest: Union[unittest.TestCase, None] = None,
+ ):
+ tb = None
+
+ message = ""
+ # error is a tuple of the form returned by sys.exc_info(): (type, value, traceback).
+ if error is not None:
+ try:
+ message = f"{error[0]} {error[1]}"
+ except Exception:
+ message = "Error occurred, unknown type or value"
+ formatted = traceback.format_exception(*error)
+ tb = "".join(formatted)
+ # Remove the 'Traceback (most recent call last)'
+ formatted = formatted[1:]
+ test_id = subtest.id() if subtest else test.id()
+
+ result = {
+ "test": test.id(),
+ "outcome": outcome,
+ "message": message,
+ "traceback": tb,
+ "subtest": subtest.id() if subtest else None,
+ }
+ self.formatted[test_id] = result
+ test_run_pipe = os.getenv("TEST_RUN_PIPE")
+ if not test_run_pipe:
+ print(
+ "UNITTEST ERROR: TEST_RUN_PIPE is not set at the time of unittest trying to send data. "
+ f"TEST_RUN_PIPE = {test_run_pipe}\n",
+ file=sys.stderr,
+ )
+ raise VSCodeUnittestError(
+ "UNITTEST ERROR: TEST_RUN_PIPE is not set at the time of unittest trying to send data. "
+ )
+ send_run_data(result, test_run_pipe)
+
+
+def filter_tests(suite: unittest.TestSuite, test_ids: List[str]) -> unittest.TestSuite:
+ """Filter the tests in the suite to only run the ones with the given ids."""
+ filtered_suite = unittest.TestSuite()
+ for test in suite:
+ if isinstance(test, unittest.TestCase):
+ if test.id() in test_ids:
+ filtered_suite.addTest(test)
+ else:
+ filtered_suite.addTest(filter_tests(test, test_ids))
+ return filtered_suite
+
+
+def get_all_test_ids(suite: unittest.TestSuite) -> List[str]:
+ """Return a list of all test ids in the suite."""
+ test_ids = []
+ for test in suite:
+ if isinstance(test, unittest.TestCase):
+ test_ids.append(test.id())
+ else:
+ test_ids.extend(get_all_test_ids(test))
+ return test_ids
+
+
+def find_missing_tests(test_ids: List[str], suite: unittest.TestSuite) -> List[str]:
+ """Return a list of test ids that are not in the suite."""
+ all_test_ids = get_all_test_ids(suite)
+ return [test_id for test_id in test_ids if test_id not in all_test_ids]
+
+
+# Args: start_path path to a directory or a file, list of ids that may be empty.
+# Edge cases:
+# - if tests got deleted since the VS Code side last ran discovery and the current test run,
+# return these test ids in the "not_found" entry, and the VS Code side can process them as "unknown";
+# - if tests got added since the VS Code side last ran discovery and the current test run, ignore them.
+def run_tests(
+ start_dir: str,
+ test_ids: List[str],
+ pattern: str,
+ top_level_dir: Optional[str],
+ verbosity: int,
+ failfast: Optional[bool], # noqa: FBT001
+ locals_: Optional[bool] = None, # noqa: FBT001
+ project_root_path: Optional[str] = None,
+) -> ExecutionPayloadDict:
+ """Run unittests and return the execution payload.
+
+ Args:
+ start_dir: Directory where test discovery starts
+ test_ids: List of test IDs to run
+ pattern: Pattern to match test files
+ top_level_dir: Top-level directory for test tree hierarchy
+ verbosity: Verbosity level for test output
+ failfast: Stop on first failure
+ locals_: Show local variables in tracebacks
+ project_root_path: Optional project root path for the cwd in the response payload
+ (used for project-based testing to root test tree at project)
+ """
+ cwd = os.path.abspath(project_root_path or start_dir) # noqa: PTH100
+ if "/" in start_dir: # is a subdir
+ parent_dir = os.path.dirname(start_dir) # noqa: PTH120
+ sys.path.insert(0, parent_dir)
+ else:
+ sys.path.insert(0, cwd)
+ status = TestExecutionStatus.error
+ error = None
+ payload: ExecutionPayloadDict = {"cwd": cwd, "status": status, "result": None}
+
+ try:
+ # If it's a file, split path and file name.
+ start_dir = cwd
+ if cwd.endswith(".py"):
+ start_dir = os.path.dirname(cwd) # noqa: PTH120
+ pattern = os.path.basename(cwd) # noqa: PTH119
+
+ if failfast is None:
+ failfast = False
+ if locals_ is None:
+ locals_ = False
+ if verbosity is None:
+ verbosity = 1
+ runner = unittest.TextTestRunner(
+ resultclass=UnittestTestResult,
+ tb_locals=locals_,
+ failfast=failfast,
+ verbosity=verbosity,
+ )
+
+ # Discover tests at path with the file name as a pattern (if any).
+ loader = unittest.TestLoader()
+ suite = loader.discover(start_dir, pattern, top_level_dir)
+
+ # lets try to tailer our own suite so we can figure out running only the ones we want
+ tailor: unittest.TestSuite = filter_tests(suite, test_ids)
+
+ # If any tests are missing, add them to the payload.
+ not_found = find_missing_tests(test_ids, tailor)
+ if not_found:
+ missing_suite = loader.loadTestsFromNames(not_found)
+ tailor.addTests(missing_suite)
+
+ result: UnittestTestResult = runner.run(tailor) # type: ignore
+
+ payload["result"] = result.formatted
+
+ except Exception:
+ status = TestExecutionStatus.error
+ error = traceback.format_exc()
+
+ if error is not None:
+ payload["error"] = error
+ else:
+ status = TestExecutionStatus.success
+
+ payload["status"] = status
+
+ return payload
+
+
+__socket = None
+atexit.register(lambda: __socket.close() if __socket else None)
+
+
+def send_run_data(raw_data, test_run_pipe):
+ status = raw_data["outcome"]
+ # Use PROJECT_ROOT_PATH if set (project-based testing), otherwise use START_DIR
+ cwd = os.path.abspath(PROJECT_ROOT_PATH or START_DIR) # noqa: PTH100
+ test_id = raw_data["subtest"] or raw_data["test"]
+ test_dict = {}
+ test_dict[test_id] = raw_data
+ payload: ExecutionPayloadDict = {"cwd": cwd, "status": status, "result": test_dict}
+ send_post_request(payload, test_run_pipe)
+
+
+if __name__ == "__main__":
+ # Get unittest test execution arguments.
+ argv = sys.argv[1:]
+ index = argv.index("--udiscovery")
+
+ (
+ start_dir,
+ pattern,
+ top_level_dir,
+ verbosity,
+ failfast,
+ locals_,
+ ) = parse_unittest_args(argv[index + 1 :])
+
+ run_test_ids_pipe = os.environ.get("RUN_TEST_IDS_PIPE")
+ test_run_pipe = os.getenv("TEST_RUN_PIPE")
+ if not run_test_ids_pipe:
+ print("Error[vscode-unittest]: RUN_TEST_IDS_PIPE env var is not set.", file=sys.stderr)
+ raise VSCodeUnittestError("Error[vscode-unittest]: RUN_TEST_IDS_PIPE env var is not set.")
+ if not test_run_pipe:
+ print("Error[vscode-unittest]: TEST_RUN_PIPE env var is not set.", file=sys.stderr)
+ raise VSCodeUnittestError("Error[vscode-unittest]: TEST_RUN_PIPE env var is not set.")
+ test_ids = []
+ cwd = pathlib.Path(start_dir).absolute()
+ try:
+ # Read the test ids from the file, attempt to delete file afterwords.
+ ids_path = pathlib.Path(run_test_ids_pipe)
+ test_ids = ids_path.read_text(encoding="utf-8").splitlines()
+ try:
+ ids_path.unlink()
+ except Exception as e:
+ print(f"Error[vscode-unittest]: unable to delete temp file: {e}", file=sys.stderr)
+
+ except Exception as e:
+ # No test ids received from buffer, return error payload
+ status: TestExecutionStatus = TestExecutionStatus.error
+ payload: ExecutionPayloadDict = {
+ "cwd": str(cwd),
+ "status": status,
+ "result": None,
+ "error": "No test ids read from temp file," + str(e),
+ }
+ send_post_request(payload, test_run_pipe)
+
+ workspace_root = os.environ.get("COVERAGE_ENABLED")
+ # For unittest COVERAGE_ENABLED is to the root of the workspace so correct data is collected
+ cov = None
+ is_coverage_run = os.environ.get("COVERAGE_ENABLED") is not None
+ include_branches = False
+ if is_coverage_run:
+ import coverage
+
+ # insert "python_files/lib/python" into the path so packaging can be imported
+ python_files_dir = pathlib.Path(__file__).parent.parent
+ bundled_dir = pathlib.Path(python_files_dir / "lib" / "python")
+ sys.path.append(os.fspath(bundled_dir))
+
+ from packaging.version import Version
+
+ coverage_version = Version(coverage.__version__)
+ # only include branches if coverage version is 7.7.0 or greater (as this was when the api saves)
+ if coverage_version >= Version("7.7.0"):
+ include_branches = True
+
+ source_ar: List[str] = []
+ if workspace_root:
+ source_ar.append(workspace_root)
+ if top_level_dir:
+ source_ar.append(top_level_dir)
+ if start_dir:
+ source_ar.append(os.path.abspath(start_dir)) # noqa: PTH100
+ cov = coverage.Coverage(
+ branch=include_branches, source=source_ar
+ ) # is at least 1 of these required??
+ cov.start()
+
+ # If no error occurred, we will have test ids to run.
+ if manage_py_path := os.environ.get("MANAGE_PY_PATH"):
+ args = argv[index + 1 :] or []
+ django_execution_runner(manage_py_path, test_ids, args)
+ else:
+ # Check for PROJECT_ROOT_PATH environment variable (project-based testing).
+ # When set, this overrides the cwd in the payload to match the project root.
+ project_root_path = os.environ.get("PROJECT_ROOT_PATH")
+ if project_root_path:
+ # Update the module-level variable for send_run_data to use
+ # pylint: disable=global-statement
+ globals()["PROJECT_ROOT_PATH"] = project_root_path
+
+ # Perform regular unittest execution.
+ # Pass project_root_path so the payload's cwd matches the project root.
+ payload = run_tests(
+ start_dir,
+ test_ids,
+ pattern,
+ top_level_dir,
+ verbosity,
+ failfast,
+ locals_,
+ project_root_path=project_root_path,
+ )
+
+ if is_coverage_run:
+ import coverage
+
+ if not cov:
+ raise VSCodeUnittestError("Coverage is enabled but cov is not set")
+ cov.stop()
+ cov.save()
+ cov.load()
+ file_set: Set[str] = cov.get_data().measured_files()
+ file_coverage_map: Dict[str, FileCoverageInfo] = {}
+ for file in file_set:
+ analysis = cov.analysis2(file)
+ taken_file_branches = 0
+ total_file_branches = -1
+
+ if include_branches:
+ branch_stats: dict[int, tuple[int, int]] = cov.branch_stats(file)
+ total_file_branches = sum([total_exits for total_exits, _ in branch_stats.values()])
+ taken_file_branches = sum([taken_exits for _, taken_exits in branch_stats.values()])
+
+ lines_executable = {int(line_no) for line_no in analysis[1]}
+ lines_missed = {int(line_no) for line_no in analysis[3]}
+ lines_covered = lines_executable - lines_missed
+ file_info: FileCoverageInfo = {
+ "lines_covered": list(lines_covered), # list of int
+ "lines_missed": list(lines_missed), # list of int
+ "executed_branches": taken_file_branches,
+ "total_branches": total_file_branches,
+ }
+ file_coverage_map[file] = file_info
+
+ payload_cov: CoveragePayloadDict = CoveragePayloadDict(
+ coverage=True,
+ cwd=os.fspath(cwd),
+ result=file_coverage_map,
+ error=None,
+ )
+ send_post_request(payload_cov, test_run_pipe)
diff --git a/pythonFiles/unittestadapter/pvsc_utils.py b/python_files/unittestadapter/pvsc_utils.py
similarity index 60%
rename from pythonFiles/unittestadapter/pvsc_utils.py
rename to python_files/unittestadapter/pvsc_utils.py
index 5632e69b09c7..d6920592a4d4 100644
--- a/pythonFiles/unittestadapter/pvsc_utils.py
+++ b/python_files/unittestadapter/pvsc_utils.py
@@ -2,19 +2,22 @@
# Licensed under the MIT License.
import argparse
+import atexit
+import doctest
import enum
import inspect
+import json
import os
import pathlib
import sys
import unittest
-from typing import List, Tuple, Union
+from typing import Dict, List, Literal, Optional, Tuple, TypedDict, Union
script_dir = pathlib.Path(__file__).parent.parent
sys.path.append(os.fspath(script_dir))
sys.path.append(os.fspath(script_dir / "lib" / "python"))
-from typing_extensions import TypedDict
+from typing_extensions import NotRequired # noqa: E402
# Types
@@ -41,6 +44,50 @@ class TestItem(TestData):
class TestNode(TestData):
children: "List[TestNode | TestItem]"
+ lineno: NotRequired[str] # Optional field for class nodes
+
+
+class TestExecutionStatus(str, enum.Enum):
+ error = "error"
+ success = "success"
+
+
+class VSCodeUnittestError(Exception):
+ """A custom exception class for unittest errors."""
+
+ def __init__(self, message):
+ super().__init__(message)
+
+
+class DiscoveryPayloadDict(TypedDict):
+ cwd: str
+ status: Literal["success", "error"]
+ tests: Optional[TestNode]
+ error: NotRequired[List[str]]
+
+
+class ExecutionPayloadDict(TypedDict):
+ cwd: str
+ status: TestExecutionStatus
+ result: Optional[Dict[str, Dict[str, Optional[str]]]]
+ not_found: NotRequired[List[str]]
+ error: NotRequired[str]
+
+
+class FileCoverageInfo(TypedDict):
+ lines_covered: List[int]
+ lines_missed: List[int]
+ executed_branches: int
+ total_branches: int
+
+
+class CoveragePayloadDict(Dict):
+ """A dictionary that is used to send a execution post request to the server."""
+
+ coverage: bool
+ cwd: str
+ result: Optional[Dict[str, FileCoverageInfo]]
+ error: Optional[str] # Currently unused need to check
# Helper functions for data retrieval.
@@ -52,8 +99,17 @@ def get_test_case(suite):
if isinstance(test, unittest.TestCase):
yield test
else:
- for test_case in get_test_case(test):
- yield test_case
+ yield from get_test_case(test)
+
+
+def get_class_line(test_case: unittest.TestCase) -> Optional[str]:
+ """Get the line number where a test class is defined."""
+ try:
+ test_class = test_case.__class__
+ _sourcelines, lineno = inspect.getsourcelines(test_class)
+ return str(lineno)
+ except Exception:
+ return None
def get_source_line(obj) -> str:
@@ -91,11 +147,12 @@ def build_test_node(path: str, name: str, type_: TestNodeTypeEnum) -> TestNode:
return {"path": path, "name": name, "type_": type_, "children": [], "id_": id_gen}
-def get_child_node(
- name: str, path: str, type_: TestNodeTypeEnum, root: TestNode
-) -> TestNode:
- """Find a child node in a test tree given its name, type and path. If the node doesn't exist, create it.
- Path is required to distinguish between nodes with the same name and type."""
+def get_child_node(name: str, path: str, type_: TestNodeTypeEnum, root: TestNode) -> TestNode:
+ """Find a child node in a test tree given its name, type and path.
+
+ If the node doesn't exist, create it.
+ Path is required to distinguish between nodes with the same name and type.
+ """
try:
result = next(
node
@@ -154,25 +211,29 @@ def build_test_tree(
"""
error = []
directory_path = pathlib.PurePath(top_level_directory)
- root = build_test_node(
- top_level_directory, directory_path.name, TestNodeTypeEnum.folder
- )
+ root = build_test_node(top_level_directory, directory_path.name, TestNodeTypeEnum.folder)
for test_case in get_test_case(suite):
test_id = test_case.id()
if test_id.startswith("unittest.loader._FailedTest"):
- error.append(str(test_case._exception)) # type: ignore
+ error.append(str(test_case._exception)) # type: ignore # noqa: SLF001
elif test_id.startswith("unittest.loader.ModuleSkipped"):
components = test_id.split(".")
class_name = f"{components[-1]}.py"
# Find/build class node.
- file_path = os.fsdecode(os.path.join(directory_path, class_name))
- current_node = get_child_node(
- class_name, file_path, TestNodeTypeEnum.file, root
- )
+ file_path = os.fsdecode(directory_path / class_name)
+ current_node = get_child_node(class_name, file_path, TestNodeTypeEnum.file, root)
else:
# Get the static test path components: filename, class name and function name.
components = test_id.split(".")
+ # Check if this is a doctest with insufficient components that would cause unpacking to fail
+ if len(components) < 3 and isinstance(test_case, doctest.DocTestCase):
+ print(
+ "Skipping doctest as it is not supported for the extension. Test case: ",
+ test_case,
+ )
+ error = ["Skipping doctest as it is not supported for the extension."]
+ continue
*folders, filename, class_name, function_name = components
py_filename = f"{filename}.py"
@@ -188,7 +249,7 @@ def build_test_tree(
)
# Find/build file node.
- path_components = [top_level_directory] + folders + [py_filename]
+ path_components = [top_level_directory, *folders, py_filename]
file_path = os.fsdecode(pathlib.PurePath("/".join(path_components)))
current_node = get_child_node(
py_filename, file_path, TestNodeTypeEnum.file, current_node
@@ -199,8 +260,14 @@ def build_test_tree(
class_name, file_path, TestNodeTypeEnum.class_, current_node
)
+ # Add line number to class node if not already present.
+ if "lineno" not in current_node:
+ class_lineno = get_class_line(test_case)
+ if class_lineno is not None:
+ current_node["lineno"] = class_lineno
+
# Get test line number.
- test_method = getattr(test_case, test_case._testMethodName)
+ test_method = getattr(test_case, test_case._testMethodName) # noqa: SLF001
lineno = get_source_line(test_method)
# Add test node.
@@ -214,9 +281,6 @@ def build_test_tree(
} # concatenate class name and function test name
current_node["children"].append(test_node)
- if not root["children"]:
- root = None
-
return root, error
@@ -234,7 +298,6 @@ def parse_unittest_args(
- top_level_directory: The top-level directory of the project, defaults to None,
and unittest will use start_directory behind the scenes.
"""
-
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("--start-directory", "-s", default=".")
arg_parser.add_argument("--pattern", "-p", default="test*.py")
@@ -260,3 +323,68 @@ def parse_unittest_args(
parsed_args.failfast,
parsed_args.locals,
)
+
+
+__writer = None
+atexit.register(lambda: __writer.close() if __writer else None)
+
+
+def send_post_request(
+ payload: Union[ExecutionPayloadDict, DiscoveryPayloadDict, CoveragePayloadDict],
+ test_run_pipe: Optional[str],
+):
+ """
+ Sends a post request to the server.
+
+ Keyword arguments:
+ payload -- the payload data to be sent.
+ test_run_pipe -- the name of the pipe to send the data to.
+ """
+ if not test_run_pipe:
+ error_msg = (
+ "UNITTEST ERROR: TEST_RUN_PIPE is not set at the time of unittest trying to send data. "
+ "Please confirm this environment variable is not being changed or removed "
+ "as it is required for successful test discovery and execution."
+ f"TEST_RUN_PIPE = {test_run_pipe}\n"
+ )
+ print(error_msg, file=sys.stderr)
+ raise VSCodeUnittestError(error_msg)
+
+ global __writer
+
+ if __writer is None:
+ try:
+ __writer = open(test_run_pipe, "wb") # noqa: SIM115, PTH123
+ except Exception as error:
+ error_msg = f"Error attempting to connect to extension named pipe {test_run_pipe}[vscode-unittest]: {error}"
+ print(error_msg, file=sys.stderr)
+ __writer = None
+ raise VSCodeUnittestError(error_msg) from error
+
+ rpc = {
+ "jsonrpc": "2.0",
+ "params": payload,
+ }
+ data = json.dumps(rpc)
+ try:
+ if __writer:
+ request = (
+ f"""content-length: {len(data)}\r\ncontent-type: application/json\r\n\r\n{data}"""
+ )
+ size = 4096
+ encoded = request.encode("utf-8")
+ bytes_written = 0
+ while bytes_written < len(encoded):
+ segment = encoded[bytes_written : bytes_written + size]
+ bytes_written += __writer.write(segment)
+ __writer.flush()
+ else:
+ print(
+ f"Connection error[vscode-unittest], writer is None \n[vscode-unittest] data: \n{data} \n",
+ file=sys.stderr,
+ )
+ except Exception as error:
+ print(
+ f"Exception thrown while attempting to send data[vscode-unittest]: {error} \n[vscode-unittest] data: \n{data}\n",
+ file=sys.stderr,
+ )
diff --git a/pythonFiles/visualstudio_py_testlauncher.py b/python_files/visualstudio_py_testlauncher.py
similarity index 76%
rename from pythonFiles/visualstudio_py_testlauncher.py
rename to python_files/visualstudio_py_testlauncher.py
index 0b0ef3242f65..878491083a71 100644
--- a/pythonFiles/visualstudio_py_testlauncher.py
+++ b/python_files/visualstudio_py_testlauncher.py
@@ -17,6 +17,7 @@
__author__ = "Microsoft Corporation "
__version__ = "3.0.0.0"
+import contextlib
import json
import os
import signal
@@ -27,11 +28,11 @@
try:
import thread
-except:
+except ModuleNotFoundError:
import _thread as thread
-class _TestOutput(object):
+class _TestOutput:
"""file like object which redirects output to the repl window."""
errors = "strict"
@@ -39,7 +40,7 @@ class _TestOutput(object):
def __init__(self, old_out, is_stdout):
self.is_stdout = is_stdout
self.old_out = old_out
- if sys.version >= "3." and hasattr(old_out, "buffer"):
+ if sys.version_info[0] >= 3 and hasattr(old_out, "buffer"):
self.buffer = _TestOutputBuffer(old_out.buffer, is_stdout)
def flush(self):
@@ -78,7 +79,7 @@ def __getattr__(self, name):
return getattr(self.old_out, name)
-class _TestOutputBuffer(object):
+class _TestOutputBuffer:
def __init__(self, old_buffer, is_stdout):
self.buffer = old_buffer
self.is_stdout = is_stdout
@@ -100,7 +101,7 @@ def seek(self, pos, whence=0):
return self.buffer.seek(pos, whence)
-class _IpcChannel(object):
+class _IpcChannel:
def __init__(self, socket, callback):
self.socket = socket
self.seq = 0
@@ -108,14 +109,14 @@ def __init__(self, socket, callback):
self.lock = thread.allocate_lock()
self._closed = False
# start the testing reader thread loop
- self.test_thread_id = thread.start_new_thread(self.readSocket, ())
+ self.test_thread_id = thread.start_new_thread(self.read_socket, ())
def close(self):
self._closed = True
- def readSocket(self):
+ def read_socket(self):
try:
- data = self.socket.recv(1024)
+ self.socket.recv(1024)
self.callback()
except OSError:
if not self._closed:
@@ -129,7 +130,7 @@ def send_event(self, name, **args):
body = {"type": "event", "seq": self.seq, "event": name, "body": args}
self.seq += 1
content = json.dumps(body).encode("utf8")
- headers = ("Content-Length: %d\n\n" % (len(content),)).encode("utf8")
+ headers = f"Content-Length: {len(content)}\n\n".encode()
self.socket.send(headers)
self.socket.send(content)
@@ -138,42 +139,40 @@ def send_event(self, name, **args):
class VsTestResult(unittest.TextTestResult):
- def startTest(self, test):
- super(VsTestResult, self).startTest(test)
+ def startTest(self, test): # noqa: N802
+ super().startTest(test)
if _channel is not None:
_channel.send_event(name="start", test=test.id())
- def addError(self, test, err):
- super(VsTestResult, self).addError(test, err)
+ def addError(self, test, err): # noqa: N802
+ super().addError(test, err)
self.sendResult(test, "error", err)
- def addFailure(self, test, err):
- super(VsTestResult, self).addFailure(test, err)
+ def addFailure(self, test, err): # noqa: N802
+ super().addFailure(test, err)
self.sendResult(test, "failed", err)
- def addSuccess(self, test):
- super(VsTestResult, self).addSuccess(test)
+ def addSuccess(self, test): # noqa: N802
+ super().addSuccess(test)
self.sendResult(test, "passed")
- def addSkip(self, test, reason):
- super(VsTestResult, self).addSkip(test, reason)
+ def addSkip(self, test, reason): # noqa: N802
+ super().addSkip(test, reason)
self.sendResult(test, "skipped")
- def addExpectedFailure(self, test, err):
- super(VsTestResult, self).addExpectedFailure(test, err)
+ def addExpectedFailure(self, test, err): # noqa: N802
+ super().addExpectedFailure(test, err)
self.sendResult(test, "failed-expected", err)
- def addUnexpectedSuccess(self, test):
- super(VsTestResult, self).addUnexpectedSuccess(test)
+ def addUnexpectedSuccess(self, test): # noqa: N802
+ super().addUnexpectedSuccess(test)
self.sendResult(test, "passed-unexpected")
- def addSubTest(self, test, subtest, err):
- super(VsTestResult, self).addSubTest(test, subtest, err)
- self.sendResult(
- test, "subtest-passed" if err is None else "subtest-failed", err, subtest
- )
+ def addSubTest(self, test, subtest, err): # noqa: N802
+ super().addSubTest(test, subtest, err)
+ self.sendResult(test, "subtest-passed" if err is None else "subtest-failed", err, subtest)
- def sendResult(self, test, outcome, trace=None, subtest=None):
+ def sendResult(self, test, outcome, trace=None, subtest=None): # noqa: N802
if _channel is not None:
tb = None
message = None
@@ -196,22 +195,19 @@ def sendResult(self, test, outcome, trace=None, subtest=None):
_channel.send_event("result", **result)
-def stopTests():
+def stop_tests():
try:
os.kill(os.getpid(), signal.SIGUSR1)
- except:
- try:
- os.kill(os.getpid(), signal.SIGTERM)
- except:
- pass
+ except Exception:
+ os.kill(os.getpid(), signal.SIGTERM)
-class ExitCommand(Exception):
+class ExitCommand(Exception): # noqa: N818
pass
-def signal_handler(signal, frame):
- raise ExitCommand()
+def signal_handler(signal, frame): # noqa: ARG001
+ raise ExitCommand
def main():
@@ -226,9 +222,7 @@ def main():
prog="visualstudio_py_testlauncher",
usage="Usage: %prog [] ... ",
)
- parser.add_option(
- "--debug", action="store_true", help="Whether debugging the unit tests"
- )
+ parser.add_option("--debug", action="store_true", help="Whether debugging the unit tests")
parser.add_option(
"-x",
"--mixed-mode",
@@ -243,9 +237,7 @@ def main():
action="append",
help="specifies a test to run",
)
- parser.add_option(
- "--testFile", type="str", help="Fully qualitified path to file name"
- )
+ parser.add_option("--testFile", type="str", help="Fully qualitified path to file name")
parser.add_option(
"-c", "--coverage", type="str", help="enable code coverage and specify filename"
)
@@ -256,9 +248,7 @@ def main():
help="connect to port on localhost and send test results",
)
parser.add_option("--us", type="str", help="Directory to start discovery")
- parser.add_option(
- "--up", type="str", help="Pattern to match test files (" "test*.py" " default)"
- )
+ parser.add_option("--up", type="str", help="Pattern to match test files (test*.py default)")
parser.add_option(
"--ut",
type="str",
@@ -271,22 +261,18 @@ def main():
help="Verbose output (0 none, 1 (no -v) simple, 2 (-v) full)",
)
parser.add_option("--uf", "--failfast", type="str", help="Stop on first failure")
- parser.add_option(
- "--uc", "--catch", type="str", help="Catch control-C and display results"
- )
+ parser.add_option("--uc", "--catch", type="str", help="Catch control-C and display results")
(opts, _) = parser.parse_args()
- sys.path[0] = os.getcwd()
+ sys.path[0] = os.getcwd() # noqa: PTH109
if opts.result_port:
try:
signal.signal(signal.SIGUSR1, signal_handler)
- except:
- try:
+ except Exception:
+ with contextlib.suppress(Exception):
signal.signal(signal.SIGTERM, signal_handler)
- except:
- pass
_channel = _IpcChannel(
- socket.create_connection(("127.0.0.1", opts.result_port)), stopTests
+ socket.create_connection(("127.0.0.1", opts.result_port)), stop_tests
)
sys.stdout = _TestOutput(sys.stdout, is_stdout=True)
sys.stderr = _TestOutput(sys.stderr, is_stdout=False)
@@ -303,25 +289,23 @@ def main():
sleep(0.1)
try:
debugger_helper = windll["Microsoft.PythonTools.Debugger.Helper.x86.dll"]
- except WindowsError:
+ except OSError:
debugger_helper = windll["Microsoft.PythonTools.Debugger.Helper.x64.dll"]
- isTracing = c_char.in_dll(debugger_helper, "isTracing")
+ is_tracing = c_char.in_dll(debugger_helper, "isTracing")
while True:
- if isTracing.value != 0:
+ if is_tracing.value != 0:
break
sleep(0.1)
cov = None
try:
if opts.coverage:
- try:
+ with contextlib.suppress(Exception):
import coverage
cov = coverage.coverage(opts.coverage)
cov.load()
cov.start()
- except:
- pass
if opts.tests is None and opts.testFile is None:
if opts.us is None:
opts.us = "."
@@ -334,7 +318,9 @@ def main():
loader = unittest.TestLoader()
# opts.us will be passed in
suites = loader.discover(
- opts.us, pattern=os.path.basename(opts.testFile), top_level_dir=opts.ut
+ opts.us,
+ pattern=os.path.basename(opts.testFile), # noqa: PTH119
+ top_level_dir=opts.ut,
)
suite = None
tests = None
@@ -343,20 +329,18 @@ def main():
tests = suites
else:
# Run a specific test class or test method
- for test_suite in suites._tests:
- for cls in test_suite._tests:
- try:
+ for test_suite in suites._tests: # noqa: SLF001
+ for cls in test_suite._tests: # noqa: SLF001
+ with contextlib.suppress(Exception):
for m in cls._tests:
- testId = m.id()
- if testId.startswith(opts.tests[0]):
+ test_id = m.id()
+ if test_id.startswith(opts.tests[0]):
suite = cls
- if testId in opts.tests:
+ if test_id in opts.tests:
if tests is None:
tests = unittest.TestSuite([m])
else:
tests.addTest(m)
- except Exception as err:
- errorMessage = traceback.format_exc()
if tests is None:
tests = suite
if tests is None and suite is None:
@@ -374,9 +358,7 @@ def main():
verbosity=opts.uvInt, resultclass=VsTestResult, failfast=True
)
else:
- runner = unittest.TextTestRunner(
- verbosity=opts.uvInt, resultclass=VsTestResult
- )
+ runner = unittest.TextTestRunner(verbosity=opts.uvInt, resultclass=VsTestResult)
result = runner.run(tests)
if _channel is not None:
_channel.close()
@@ -390,14 +372,10 @@ def main():
_channel.send_event(name="done")
_channel.socket.close()
# prevent generation of the error 'Error in sys.exitfunc:'
- try:
+ with contextlib.suppress(Exception):
sys.stdout.close()
- except:
- pass
- try:
+ with contextlib.suppress(Exception):
sys.stderr.close()
- except:
- pass
if __name__ == "__main__":
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/__init__.py b/python_files/vscode_datascience_helpers/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/.data/NormCase/tests/__init__.py
rename to python_files/vscode_datascience_helpers/__init__.py
diff --git a/pythonFiles/tests/testing_tools/adapter/.data/complex/tests/__init__.py b/python_files/vscode_datascience_helpers/tests/__init__.py
similarity index 100%
rename from pythonFiles/tests/testing_tools/adapter/.data/complex/tests/__init__.py
rename to python_files/vscode_datascience_helpers/tests/__init__.py
diff --git a/python_files/vscode_datascience_helpers/tests/logParser.py b/python_files/vscode_datascience_helpers/tests/logParser.py
new file mode 100644
index 000000000000..12c090ec581f
--- /dev/null
+++ b/python_files/vscode_datascience_helpers/tests/logParser.py
@@ -0,0 +1,95 @@
+import argparse # noqa: N999
+import os
+import re
+from io import TextIOWrapper
+from pathlib import Path
+
+os.system("color")
+
+
+parser = argparse.ArgumentParser(description="Parse a test log into its parts")
+parser.add_argument("testlog", type=str, nargs=1, help="Log to parse")
+parser.add_argument("--testoutput", action="store_true", help="Show all failures and passes")
+parser.add_argument(
+ "--split",
+ action="store_true",
+ help="Split into per process files. Each file will have the pid appended",
+)
+ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
+pid_regex = re.compile(r"(\d+).*")
+timestamp_regex = re.compile(r"\d{4}-\d{2}-\d{2}T.*\dZ")
+
+
+def strip_timestamp(line: str):
+ match = timestamp_regex.match(line)
+ if match:
+ return line[match.end() :]
+ return line
+
+
+def read_strip_lines(f: TextIOWrapper):
+ return map(strip_timestamp, f.readlines())
+
+
+def print_test_output(testlog):
+ # Find all the lines that don't have a PID in them. These are the test output
+ p = Path(testlog[0])
+ with p.open() as f:
+ for line in read_strip_lines(f):
+ stripped = line.strip()
+ if len(stripped) > 2 and stripped[0] == "\x1b" and stripped[1] == "[":
+ print(line.rstrip()) # Should be a test line as it has color encoding
+
+
+def split_by_pid(testlog):
+ # Split testlog into prefixed logs based on pid
+ p = Path(testlog[0])
+ pids = set()
+ logs = {}
+ pid = None
+ try:
+ with p.open() as f:
+ for line in read_strip_lines(f):
+ stripped = ansi_escape.sub("", line.strip())
+ if len(stripped) > 0:
+ # Pull out the pid
+ match = pid_regex.match(stripped)
+
+ # Pids are at least two digits
+ if match and len(match.group(1)) > 2:
+ # Pid is found
+ pid = int(match.group(1))
+
+ # See if we've created a log for this pid or not
+ if pid not in pids:
+ pids.add(pid)
+ log_file = p.with_name(f"{p.stem}_{pid}.log")
+ print("Writing to new log:", os.fsdecode(log_file))
+ logs[pid] = log_file.open(mode="w")
+
+ # Add this line to the log
+ if pid is not None:
+ logs[pid].write(line)
+ finally:
+ # Close all of the open logs
+ for key in logs:
+ logs[key].close()
+
+
+def do_work(args):
+ if not args.testlog:
+ print("Test log should be passed")
+ elif args.testoutput:
+ print_test_output(args.testlog)
+ elif args.split:
+ split_by_pid(args.testlog)
+ else:
+ parser.print_usage()
+
+
+def main():
+ do_work(parser.parse_args())
+
+
+if __name__ == "__main__":
+ main()
diff --git a/python_files/vscode_pytest/__init__.py b/python_files/vscode_pytest/__init__.py
new file mode 100644
index 000000000000..be4e3daaa843
--- /dev/null
+++ b/python_files/vscode_pytest/__init__.py
@@ -0,0 +1,1197 @@
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+from __future__ import annotations
+
+import atexit
+import contextlib
+import json
+import os
+import pathlib
+import sys
+import traceback
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Dict,
+ Generator,
+ Literal,
+ Protocol,
+ TypedDict,
+ cast,
+)
+
+import pytest
+
+if TYPE_CHECKING:
+ from pluggy import Result
+ from typing_extensions import NotRequired
+
+USES_PYTEST_DESCRIBE = False
+
+with contextlib.suppress(ImportError):
+ from pytest_describe.plugin import DescribeBlock
+
+ USES_PYTEST_DESCRIBE = True
+
+
+class HasPathOrFspath(Protocol):
+ """Protocol defining objects that have either a path or fspath attribute."""
+
+ path: pathlib.Path | None = None
+ fspath: Any | None = None
+
+
+class TestData(TypedDict):
+ """A general class that all test objects inherit from."""
+
+ name: str
+ path: pathlib.Path
+ type_: Literal["class", "function", "file", "folder", "test", "error"]
+ id_: str
+
+
+class TestItem(TestData):
+ """A class defining test items."""
+
+ lineno: str
+ runID: str
+
+
+class TestNode(TestData):
+ """A general class that handles all test data which contains children."""
+
+ children: list[TestNode | TestItem | None]
+ lineno: NotRequired[str] # Optional field for class/function nodes
+
+
+class VSCodePytestError(Exception):
+ """A custom exception class for pytest errors."""
+
+ def __init__(self, message):
+ super().__init__(message)
+
+
+ERRORS = []
+IS_DISCOVERY = False
+map_id_to_path = {}
+collected_tests_so_far = set()
+TEST_RUN_PIPE = os.getenv("TEST_RUN_PIPE")
+PROJECT_ROOT_PATH = os.getenv(
+ "PROJECT_ROOT_PATH"
+) # Path to project root for multi-project workspaces
+SYMLINK_PATH = None
+INCLUDE_BRANCHES = False
+
+# Performance optimization caches for path resolution
+_path_cache: dict[int, pathlib.Path] = {} # Cache node paths by object id
+_path_to_str_cache: dict[pathlib.Path, str] = {} # Cache path-to-string conversions
+_CACHED_CWD: pathlib.Path | None = None
+
+
+def get_test_root_path() -> pathlib.Path:
+ """Get the root path for the test tree.
+
+ For project-based testing, this returns PROJECT_ROOT_PATH (the project root).
+ For legacy mode, this returns the current working directory.
+
+ Returns:
+ pathlib.Path: The root path to use for the test tree.
+ """
+ if PROJECT_ROOT_PATH:
+ return pathlib.Path(PROJECT_ROOT_PATH)
+ return pathlib.Path.cwd()
+
+
+def pytest_load_initial_conftests(early_config, parser, args): # noqa: ARG001
+ has_pytest_cov = early_config.pluginmanager.hasplugin(
+ "pytest_cov"
+ ) or early_config.pluginmanager.hasplugin("pytest_cov.plugin")
+ has_cov_arg = any("--cov" in arg for arg in args)
+ if has_cov_arg and not has_pytest_cov:
+ raise VSCodePytestError(
+ "\n \nERROR: pytest-cov is not installed, please install this before running pytest with coverage as pytest-cov is required. \n"
+ )
+ if "--cov-branch" in args:
+ global INCLUDE_BRANCHES
+ INCLUDE_BRANCHES = True
+
+ global TEST_RUN_PIPE
+ TEST_RUN_PIPE = os.getenv("TEST_RUN_PIPE")
+ error_string = (
+ "PYTEST ERROR: TEST_RUN_PIPE is not set at the time of pytest starting. "
+ "Please confirm this environment variable is not being changed or removed "
+ "as it is required for successful test discovery and execution."
+ f"TEST_RUN_PIPE = {TEST_RUN_PIPE}\n"
+ )
+ if not TEST_RUN_PIPE:
+ print(error_string, file=sys.stderr)
+ if "--collect-only" in args:
+ global IS_DISCOVERY
+ IS_DISCOVERY = True
+
+ # check if --rootdir is in the args
+ for arg in args:
+ if "--rootdir=" in arg:
+ rootdir = pathlib.Path(arg.split("--rootdir=")[1])
+ if not rootdir.exists():
+ raise VSCodePytestError(
+ f"The path set in the argument --rootdir={rootdir} does not exist."
+ )
+
+ # Check if the rootdir is a symlink or a child of a symlink to the current cwd.
+ is_symlink = False
+
+ if rootdir.is_symlink():
+ is_symlink = True
+ print(
+ f"Plugin info[vscode-pytest]: rootdir argument, {rootdir}, is identified as a symlink."
+ )
+ elif rootdir.resolve() != rootdir:
+ print("Plugin info[vscode-pytest]: Checking if rootdir is a child of a symlink.")
+ is_symlink = has_symlink_parent(rootdir)
+ if is_symlink:
+ print(
+ f"Plugin info[vscode-pytest]: rootdir argument, {rootdir}, is identified as a symlink or child of a symlink, adjusting pytest paths accordingly.",
+ )
+ global SYMLINK_PATH
+ SYMLINK_PATH = rootdir
+
+
+def pytest_internalerror(excrepr, excinfo): # noqa: ARG001
+ """A pytest hook that is called when an internal error occurs.
+
+ Keyword arguments:
+ excrepr -- the exception representation.
+ excinfo -- the exception information of type ExceptionInfo.
+ """
+ # call.excinfo.exconly() returns the exception as a string.
+ ERRORS.append(excinfo.exconly() + "\n Check Python Logs for more details.")
+
+
+def pytest_exception_interact(node, call, report):
+ """A pytest hook that is called when an exception is raised which could be handled.
+
+ Keyword arguments:
+ node -- the node that raised the exception.
+ call -- the call object.
+ report -- the report object of either type CollectReport or TestReport.
+ """
+ # call.excinfo is the captured exception of the call, if it raised as type ExceptionInfo.
+ # call.excinfo.exconly() returns the exception as a string.
+ # If it is during discovery, then add the error to error logs.
+ if IS_DISCOVERY:
+ if call.excinfo and call.excinfo.typename != "AssertionError":
+ if report.outcome == "skipped" and "SkipTest" in str(call):
+ return
+ ERRORS.append(call.excinfo.exconly() + "\n Check Python Logs for more details.")
+ else:
+ ERRORS.append(report.longreprtext + "\n Check Python Logs for more details.")
+ else:
+ # If during execution, send this data that the given node failed.
+ report_value = "error"
+ if call.excinfo.typename == "AssertionError":
+ report_value = "failure"
+ node_id = get_absolute_test_id(node.nodeid, get_node_path(node))
+ if node_id not in collected_tests_so_far:
+ collected_tests_so_far.add(node_id)
+ item_result = create_test_outcome(
+ node_id,
+ report_value,
+ "Test failed with exception",
+ report.longreprtext,
+ )
+ collected_test = TestRunResultDict()
+ collected_test[node_id] = item_result
+ cwd = pathlib.Path.cwd()
+ send_execution_message(
+ os.fsdecode(cwd),
+ "success",
+ collected_test or None,
+ )
+
+
+def has_symlink_parent(current_path):
+ """Recursively checks if any parent directories of the given path are symbolic links."""
+ # Convert the current path to an absolute Path object
+ curr_path = pathlib.Path(current_path)
+ print("Checking for symlink parent starting at current path: ", curr_path)
+
+ # Iterate over all parent directories
+ for parent in curr_path.parents:
+ # Check if the parent directory is a symlink
+ if parent.is_symlink():
+ print(f"Symlink found at: {parent}")
+ return True
+ return False
+
+
+def get_absolute_test_id(test_id: str, test_path: pathlib.Path) -> str:
+ """A function that returns the absolute test id.
+
+ This is necessary because testIds are relative to the rootdir.
+ This does not work for our case since testIds when referenced during run time are relative to the instantiation
+ location. Absolute paths for testIds are necessary for the test tree ensures configurations that change the rootdir
+ of pytest are handled correctly.
+
+ Keyword arguments:
+ test_id -- the pytest id of the test which is relative to the rootdir.
+ testPath -- the path to the file the test is located in, as a pathlib.Path object.
+ """
+ split_id = test_id.split("::")[1:]
+ return "::".join([str(test_path), *split_id])
+
+
+def pytest_keyboard_interrupt(excinfo):
+ """A pytest hook that is called when a keyboard interrupt is raised.
+
+ Keyword arguments:
+ excinfo -- the exception information of type ExceptionInfo.
+ """
+ # The function execonly() returns the exception as a string.
+ ERRORS.append(excinfo.exconly() + "\n Check Python Logs for more details.")
+
+
+class TestOutcome(Dict):
+ """A class that handles outcome for a single test.
+
+ for pytest the outcome for a test is only 'passed', 'skipped' or 'failed'
+ """
+
+ test: str
+ outcome: Literal["success", "failure", "skipped", "error"]
+ message: str | None
+ traceback: str | None
+ subtest: str | None
+
+
+def create_test_outcome(
+ testid: str,
+ outcome: str,
+ message: str | None,
+ traceback: str | None,
+ subtype: str | None = None, # noqa: ARG001
+) -> TestOutcome:
+ """A function that creates a TestOutcome object."""
+ return TestOutcome(
+ test=testid,
+ outcome=outcome,
+ message=message,
+ traceback=traceback, # TODO: traceback
+ subtest=None,
+ )
+
+
+class TestRunResultDict(Dict[str, Dict[str, TestOutcome]]):
+ """A class that stores all test run results."""
+
+ outcome: str
+ tests: dict[str, TestOutcome]
+
+
+@pytest.hookimpl(hookwrapper=True, trylast=True)
+def pytest_report_teststatus(report, config): # noqa: ARG001
+ """A pytest hook that is called when a test is called.
+
+ It is called 3 times per test, during setup, call, and teardown.
+
+ Keyword arguments:
+ report -- the report on the test setup, call, and teardown.
+ config -- configuration object.
+ """
+ cwd = pathlib.Path.cwd()
+ if SYMLINK_PATH:
+ cwd = SYMLINK_PATH
+
+ if report.when == "call" or (report.when == "setup" and report.skipped):
+ traceback = None
+ message = None
+ report_value = "skipped"
+ if report.passed:
+ report_value = "success"
+ elif report.failed:
+ report_value = "failure"
+ message = report.longreprtext
+ try:
+ node_path = map_id_to_path[report.nodeid]
+ except KeyError:
+ node_path = cwd
+ # Calculate the absolute test id and use this as the ID moving forward.
+ absolute_node_id = get_absolute_test_id(report.nodeid, node_path)
+ if absolute_node_id not in collected_tests_so_far:
+ collected_tests_so_far.add(absolute_node_id)
+ item_result = create_test_outcome(
+ absolute_node_id,
+ report_value,
+ message,
+ traceback,
+ )
+ collected_test = TestRunResultDict()
+ collected_test[absolute_node_id] = item_result
+ send_execution_message(
+ os.fsdecode(cwd),
+ "success",
+ collected_test or None,
+ )
+ yield
+
+
+ERROR_MESSAGE_CONST = {
+ 2: "Pytest was unable to start or run any tests due to issues with test discovery or test collection.",
+ 3: "Pytest was interrupted by the user, for example by pressing Ctrl+C during test execution.",
+ 4: "Pytest encountered an internal error or exception during test execution.",
+ 5: "Pytest was unable to find any tests to run.",
+}
+
+
+@pytest.hookimpl(hookwrapper=True, trylast=True)
+def pytest_runtest_protocol(item, nextitem): # noqa: ARG001
+ map_id_to_path[item.nodeid] = get_node_path(item)
+ skipped = check_skipped_wrapper(item)
+ if skipped:
+ absolute_node_id = get_absolute_test_id(item.nodeid, get_node_path(item))
+ report_value = "skipped"
+ cwd = pathlib.Path.cwd()
+ if absolute_node_id not in collected_tests_so_far:
+ collected_tests_so_far.add(absolute_node_id)
+ item_result = create_test_outcome(
+ absolute_node_id,
+ report_value,
+ None,
+ None,
+ )
+ collected_test = TestRunResultDict()
+ collected_test[absolute_node_id] = item_result
+ send_execution_message(
+ os.fsdecode(cwd),
+ "success",
+ collected_test or None,
+ )
+ yield
+
+
+def check_skipped_wrapper(item):
+ """A function that checks if a test is skipped or not by check its markers and its parent markers.
+
+ Returns True if the test is marked as skipped at any level, False otherwise.
+
+ Keyword arguments:
+ item -- the pytest item object.
+ """
+ if item.own_markers and check_skipped_condition(item):
+ return True
+ parent = item.parent
+ while isinstance(parent, pytest.Class):
+ if parent.own_markers and check_skipped_condition(parent):
+ return True
+ parent = parent.parent
+ return False
+
+
+def check_skipped_condition(item):
+ """A helper function that checks if a item has a skip or a true skip condition.
+
+ Keyword arguments:
+ item -- the pytest item object.
+ """
+ for marker in item.own_markers:
+ # If the test is marked with skip then it will not hit the pytest_report_teststatus hook,
+ # therefore we need to handle it as skipped here.
+ skip_condition = False
+ if marker.name == "skipif":
+ skip_condition = any(marker.args)
+ if marker.name == "skip" or skip_condition:
+ return True
+ return False
+
+
+class FileCoverageInfo(TypedDict):
+ lines_covered: list[int]
+ lines_missed: list[int]
+ executed_branches: int
+ total_branches: int
+
+
+def pytest_sessionfinish(session, exitstatus):
+ """A pytest hook that is called after pytest has fulled finished.
+
+ Keyword arguments:
+ session -- the pytest session object.
+ exitstatus -- the status code of the session.
+
+ Exit code 0: All tests were collected and passed successfully
+ Exit code 1: Tests were collected and run but some of the tests failed
+ Exit code 2: Test execution was interrupted by the user
+ Exit code 3: Internal error happened while executing tests
+ Exit code 4: pytest command line usage error
+ Exit code 5: No tests were collected
+ """
+ # Get the root path for the test tree structure (not the CWD for test execution)
+ # This is PROJECT_ROOT_PATH in project-based mode, or cwd in legacy mode
+ test_root_path = get_test_root_path()
+ if SYMLINK_PATH:
+ print("Plugin warning[vscode-pytest]: SYMLINK set, adjusting test root path.")
+ test_root_path = pathlib.Path(SYMLINK_PATH)
+
+ if IS_DISCOVERY:
+ if not (exitstatus == 0 or exitstatus == 1 or exitstatus == 5):
+ error_node: TestNode = {
+ "name": "",
+ "path": test_root_path,
+ "type_": "error",
+ "children": [],
+ "id_": "",
+ }
+ send_discovery_message(os.fsdecode(test_root_path), error_node)
+ try:
+ session_node: TestNode | None = build_test_tree(session)
+ if not session_node:
+ raise VSCodePytestError(
+ "Something went wrong following pytest finish, \
+ no session node was created"
+ )
+ send_discovery_message(os.fsdecode(test_root_path), session_node)
+ except Exception as e:
+ ERRORS.append(
+ f"Error Occurred, traceback: {(traceback.format_exc() if e.__traceback__ else '')}"
+ )
+ error_node: TestNode = {
+ "name": "",
+ "path": test_root_path,
+ "type_": "error",
+ "children": [],
+ "id_": "",
+ }
+ send_discovery_message(os.fsdecode(test_root_path), error_node)
+ else:
+ if exitstatus == 0 or exitstatus == 1:
+ exitstatus_bool = "success"
+ else:
+ ERRORS.append(
+ f"Pytest exited with error status: {exitstatus}, {ERROR_MESSAGE_CONST[exitstatus]}"
+ )
+ exitstatus_bool = "error"
+
+ send_execution_message(
+ os.fsdecode(test_root_path),
+ exitstatus_bool,
+ None,
+ )
+ # send end of transmission token
+
+ # send coverage if enabled
+ is_coverage_run = os.environ.get("COVERAGE_ENABLED")
+ if is_coverage_run == "True":
+ # load the report and build the json result to return
+ import coverage
+
+ # insert "python_files/lib/python" into the path so packaging can be imported
+ python_files_dir = pathlib.Path(__file__).parent.parent
+ bundled_dir = pathlib.Path(python_files_dir / "lib" / "python")
+ sys.path.append(os.fspath(bundled_dir))
+
+ from packaging.version import Version
+
+ coverage_version = Version(coverage.__version__)
+ global INCLUDE_BRANCHES
+ # only include branches if coverage version is 7.7.0 or greater (as this was when the api saves)
+ if coverage_version < Version("7.7.0") and INCLUDE_BRANCHES:
+ print(
+ "Plugin warning[vscode-pytest]: Branch coverage not supported in this coverage versions < 7.7.0. Please upgrade coverage package if you would like to see branch coverage."
+ )
+ INCLUDE_BRANCHES = False
+
+ try:
+ from coverage.exceptions import NoSource
+ except ImportError:
+ from coverage.misc import NoSource
+
+ cov = coverage.Coverage()
+ cov.load()
+
+ file_set: set[str] = cov.get_data().measured_files()
+ file_coverage_map: dict[str, FileCoverageInfo] = {}
+
+ # remove files omitted per coverage report config if any
+ omit_files: list[str] | None = cov.config.report_omit
+ if omit_files is not None:
+ for pattern in omit_files:
+ for file in list(file_set):
+ if pathlib.Path(file).match(pattern):
+ file_set.remove(file)
+
+ for file in file_set:
+ try:
+ analysis = cov.analysis2(file)
+ taken_file_branches = 0
+ total_file_branches = -1
+
+ if INCLUDE_BRANCHES:
+ branch_stats: dict[int, tuple[int, int]] = cov.branch_stats(file)
+ total_file_branches = sum(
+ [total_exits for total_exits, _ in branch_stats.values()]
+ )
+ taken_file_branches = sum(
+ [taken_exits for _, taken_exits in branch_stats.values()]
+ )
+
+ except NoSource:
+ # as per issue 24308 this best way to handle this edge case
+ continue
+ except Exception as e:
+ print(
+ f"Plugin error[vscode-pytest]: Skipping analysis of file: {file} due to error: {e}"
+ )
+ continue
+ lines_executable = {int(line_no) for line_no in analysis[1]}
+ lines_missed = {int(line_no) for line_no in analysis[3]}
+ lines_covered = lines_executable - lines_missed
+ file_info: FileCoverageInfo = {
+ "lines_covered": list(lines_covered), # list of int
+ "lines_missed": list(lines_missed), # list of int
+ "executed_branches": taken_file_branches,
+ "total_branches": total_file_branches,
+ }
+ # convert relative path to absolute path
+ if not pathlib.Path(file).is_absolute():
+ file = str(pathlib.Path(file).resolve())
+ file_coverage_map[file] = file_info
+
+ payload: CoveragePayloadDict = CoveragePayloadDict(
+ coverage=True,
+ cwd=os.fspath(test_root_path),
+ result=file_coverage_map,
+ error=None,
+ )
+ send_message(payload)
+
+
+def construct_nested_folders(
+ file_nodes_dict: dict[str, TestNode],
+ session_node: TestNode,
+ session_children_dict: dict[str, TestNode],
+) -> dict[str, TestNode]:
+ """Iterate through all files and construct them into nested folders.
+
+ Keyword arguments:
+ file_nodes_dict -- Dictionary of all file nodes
+ session_node -- The session node that will be parent to the folder structure
+ session_children_dict -- Dictionary of session's children nodes indexed by ID
+
+ Returns:
+ dict[str, TestNode] -- Updated session_children_dict with folder nodes added
+ """
+ created_files_folders_dict: dict[str, TestNode] = {}
+ for file_node in file_nodes_dict.values():
+ # Iterate through all the files that exist and construct them into nested folders.
+ root_folder_node: TestNode
+ try:
+ root_folder_node: TestNode = build_nested_folders(
+ file_node, created_files_folders_dict, session_node
+ )
+ except ValueError:
+ # This exception is raised when the session node is not a parent of the file node.
+ print(
+ "[vscode-pytest]: Session path not a parent of test paths, adjusting session node to common parent."
+ )
+ file_path_str: str = str(file_node["path"])
+ session_path_str: str = str(session_node["path"])
+ common_parent = os.path.commonpath([file_path_str, session_path_str])
+ common_parent_path = pathlib.Path(common_parent)
+ print("[vscode-pytest]: Session node now set to: ", common_parent)
+ session_node["path"] = common_parent_path # pathlib.Path
+ session_node["id_"] = common_parent # str
+ session_node["name"] = common_parent_path.name # str
+ root_folder_node = build_nested_folders(
+ file_node, created_files_folders_dict, session_node
+ )
+ # The final folder we get to is the highest folder in the path
+ # and therefore we add this as a child to the session.
+ root_id = root_folder_node.get("id_")
+ if root_id and root_id not in session_children_dict:
+ session_children_dict[root_id] = root_folder_node
+
+ return session_children_dict
+
+
+def process_parameterized_test(
+ test_case: pytest.Item,
+ test_node: TestItem,
+ function_nodes_dict: dict[str, TestNode],
+ file_nodes_dict: dict[str, TestNode],
+) -> TestNode:
+ """Process a parameterized test case and create appropriate function nodes.
+
+ Keyword arguments:
+ test_case -- the parameterized pytest test case; must have callspec attribute
+ test_node -- the test node created from the test case
+ function_nodes_dict -- dictionary of function nodes indexed by ID
+ file_nodes_dict -- dictionary of file nodes indexed by path
+
+ Returns:
+ TestNode -- the node to use for further processing (function node or original test node)
+ """
+ function_name: str = ""
+ # parameterized test cases cut the repetitive part of the name off.
+ parent_part, parameterized_section = test_node["name"].split("[", 1)
+ test_node["name"] = "[" + parameterized_section
+
+ first_split = test_case.nodeid.rsplit(
+ "::", 1
+ ) # splits the parameterized test name from the rest of the nodeid
+ second_split = first_split[0].rsplit(
+ ".py", 1
+ ) # splits the file path from the rest of the nodeid
+
+ class_and_method = second_split[1] + "::" # This has "::" separator at both ends
+ # construct the parent id, so it is absolute path :: any class and method :: parent_part
+ parent_id = cached_fsdecode(get_node_path(test_case)) + class_and_method + parent_part
+
+ try:
+ function_name = test_case.originalname # type: ignore
+ except AttributeError: # actual error has occurred
+ ERRORS.append(
+ f"unable to find original name for {test_case.name} with parameterization detected."
+ )
+ raise VSCodePytestError(
+ "Unable to find original name for parameterized test case"
+ ) from None
+
+ function_test_node = function_nodes_dict.get(parent_id)
+ if function_test_node is None:
+ function_test_node = create_parameterized_function_node(
+ function_name, get_node_path(test_case), parent_id
+ )
+ function_nodes_dict[parent_id] = function_test_node
+
+ if test_node not in function_test_node["children"]:
+ function_test_node["children"].append(test_node)
+
+ # Check if the parent node of the function is file, if so create/add to this file node.
+ if isinstance(test_case.parent, pytest.File):
+ # calculate the parent path of the test case
+ parent_path = get_node_path(test_case.parent)
+ parent_path_key = cached_fsdecode(parent_path)
+ parent_test_case = file_nodes_dict.get(parent_path_key)
+ if parent_test_case is None:
+ parent_test_case = create_file_node(parent_path)
+ file_nodes_dict[parent_path_key] = parent_test_case
+ if function_test_node not in parent_test_case["children"]:
+ parent_test_case["children"].append(function_test_node)
+
+ # Return the function node as the test node to handle subsequent nesting
+ return function_test_node
+
+
+def build_test_tree(session: pytest.Session) -> TestNode:
+ """Builds a tree made up of testing nodes from the pytest session.
+
+ Keyword arguments:
+ session -- the pytest session object that contains test items.
+
+ Returns:
+ TestNode -- The root node of the constructed test tree.
+ """
+ session_node = create_session_node(session)
+ session_children_dict: dict[str, TestNode] = {}
+ file_nodes_dict: dict[str, TestNode] = {}
+ class_nodes_dict: dict[str, TestNode] = {}
+ function_nodes_dict: dict[str, TestNode] = {}
+
+ # Check to see if the global variable for symlink path is set
+ if SYMLINK_PATH:
+ session_node["path"] = SYMLINK_PATH
+ session_node["id_"] = os.fspath(SYMLINK_PATH)
+
+ for test_case in session.items:
+ test_node = create_test_node(test_case)
+ if hasattr(test_case, "callspec"): # This means it is a parameterized test.
+ # Process parameterized test and get the function node to use for further processing
+ test_node = process_parameterized_test(
+ test_case, test_node, function_nodes_dict, file_nodes_dict
+ )
+ if isinstance(test_case.parent, pytest.Class) or (
+ USES_PYTEST_DESCRIBE and isinstance(test_case.parent, DescribeBlock)
+ ):
+ case_iter = test_case.parent
+ node_child_iter = test_node
+ test_class_node: TestNode | None = None
+ while isinstance(case_iter, pytest.Class) or (
+ USES_PYTEST_DESCRIBE and isinstance(case_iter, DescribeBlock)
+ ):
+ # While the given node is a class, create a class and nest the previous node as a child.
+ test_class_node = class_nodes_dict.get(case_iter.nodeid)
+ if test_class_node is None:
+ test_class_node = create_class_node(case_iter)
+ class_nodes_dict[case_iter.nodeid] = test_class_node
+ # Check if the class already has the child node. This will occur if the test is parameterized.
+ if node_child_iter not in test_class_node["children"]:
+ test_class_node["children"].append(node_child_iter)
+ # Iterate up.
+ node_child_iter = test_class_node
+ case_iter = case_iter.parent
+ # Now the parent node is not a class node, it is a file node.
+ if case_iter:
+ parent_module = case_iter
+ else:
+ ERRORS.append(f"Test class {case_iter} has no parent")
+ break
+ parent_path = get_node_path(parent_module)
+ # Create a file node that has the last class as a child.
+ parent_path_key = cached_fsdecode(parent_path)
+ test_file_node = file_nodes_dict.get(parent_path_key)
+ if test_file_node is None:
+ test_file_node = create_file_node(parent_path)
+ file_nodes_dict[parent_path_key] = test_file_node
+ # Check if the class is already a child of the file node.
+ if test_class_node is not None and test_class_node not in test_file_node["children"]:
+ test_file_node["children"].append(test_class_node)
+ elif not hasattr(test_case, "callspec"):
+ # This includes test cases that are pytest functions or a doctests.
+ if test_case.parent is None:
+ ERRORS.append(f"Test case {test_case.name} has no parent")
+ continue
+ parent_path = get_node_path(
+ cast(
+ "pytest.Session | pytest.Item | pytest.File | pytest.Class | pytest.Module | HasPathOrFspath",
+ test_case.parent,
+ )
+ )
+ parent_path_key = cached_fsdecode(parent_path)
+ parent_test_case = file_nodes_dict.get(parent_path_key)
+ if parent_test_case is None:
+ parent_test_case = create_file_node(parent_path)
+ file_nodes_dict[parent_path_key] = parent_test_case
+ parent_test_case["children"].append(test_node)
+ # Process all files and construct them into nested folders
+ session_children_dict = construct_nested_folders(
+ file_nodes_dict, session_node, session_children_dict
+ )
+ session_node["children"] = list(session_children_dict.values())
+ return session_node
+
+
+def build_nested_folders(
+ file_node: TestNode,
+ created_files_folders_dict: dict[str, TestNode],
+ session_node: TestNode,
+) -> TestNode:
+ """Takes a file or folder and builds the nested folder structure for it.
+
+ Keyword arguments:
+ file_module -- the created module for the file we are nesting.
+ file_node -- the file node that we are building the nested folders for.
+ created_files_folders_dict -- Dictionary of all the folders and files that have been created where the key is the path.
+ session -- the pytest session object.
+ """
+ # check if session node is a parent of the file node, throw error if not.
+ session_node_path = session_node["path"]
+ is_relative = False
+ try:
+ is_relative = file_node["path"].is_relative_to(session_node_path)
+ except AttributeError:
+ is_relative = file_node["path"].relative_to(session_node_path)
+ if not is_relative:
+ # If the session node is not a parent of the file node, we need to find their common parent.
+ raise ValueError("session and file not relative to each other, fixing now....")
+
+ # Begin the iterator_path one level above the current file.
+ prev_folder_node = file_node
+ iterator_path = file_node["path"].parent
+ counter = 0
+ max_iter = 100
+ while iterator_path != session_node_path:
+ curr_folder_name = iterator_path.name
+ iterator_path_key = cached_fsdecode(iterator_path)
+ curr_folder_node = created_files_folders_dict.get(iterator_path_key)
+ if curr_folder_node is None:
+ curr_folder_node = create_folder_node(curr_folder_name, iterator_path)
+ created_files_folders_dict[iterator_path_key] = curr_folder_node
+ if prev_folder_node not in curr_folder_node["children"]:
+ curr_folder_node["children"].append(prev_folder_node)
+ iterator_path = iterator_path.parent
+ prev_folder_node = curr_folder_node
+ # Handles error where infinite loop occurs.
+ counter += 1
+ if counter > max_iter:
+ raise ValueError(
+ "[vscode-pytest]: Infinite loop occurred in build_nested_folders. iterator_path: ",
+ iterator_path,
+ "session_node_path: ",
+ session_node_path,
+ )
+ return prev_folder_node
+
+
+def create_test_node(
+ test_case: pytest.Item,
+) -> TestItem:
+ """Creates a test node from a pytest test case.
+
+ Keyword arguments:
+ test_case -- the pytest test case.
+ """
+ test_case_loc: str = (
+ str(test_case.location[1] + 1) if (test_case.location[1] is not None) else ""
+ )
+ absolute_test_id = get_absolute_test_id(test_case.nodeid, get_node_path(test_case))
+ return {
+ "name": test_case.name,
+ "path": get_node_path(test_case),
+ "lineno": test_case_loc,
+ "type_": "test",
+ "id_": absolute_test_id,
+ "runID": absolute_test_id,
+ }
+
+
+def create_session_node(session: pytest.Session) -> TestNode:
+ """Creates a session node from a pytest session.
+
+ Keyword arguments:
+ session -- the pytest session.
+ """
+ # Use PROJECT_ROOT_PATH if set (project-based testing), otherwise use session path (legacy)
+ node_path = pathlib.Path(PROJECT_ROOT_PATH) if PROJECT_ROOT_PATH else get_node_path(session)
+ return {
+ "name": node_path.name,
+ "path": node_path,
+ "type_": "folder",
+ "children": [],
+ "id_": os.fspath(node_path),
+ }
+
+
+def create_class_node(class_module: pytest.Class | DescribeBlock) -> TestNode:
+ """Creates a class node from a pytest class object.
+
+ Keyword arguments:
+ class_module -- the pytest object representing a class module.
+ """
+ # Get line number for the class definition
+ class_line = ""
+ try:
+ if hasattr(class_module, "obj"):
+ import inspect
+
+ _, lineno = inspect.getsourcelines(class_module.obj)
+ class_line = str(lineno)
+ except (OSError, TypeError):
+ # If we can't get the source lines, leave lineno empty
+ pass
+
+ return {
+ "name": class_module.name,
+ "path": get_node_path(class_module),
+ "type_": "class",
+ "children": [],
+ "id_": get_absolute_test_id(class_module.nodeid, get_node_path(class_module)),
+ "lineno": class_line,
+ }
+
+
+def create_parameterized_function_node(
+ function_name: str, test_path: pathlib.Path, function_id: str
+) -> TestNode:
+ """Creates a function node to be the parent for the parameterized test nodes.
+
+ Keyword arguments:
+ function_name -- the name of the function.
+ test_path -- the path to the test file.
+ function_id -- the previously constructed function id that fits the pattern- absolute path :: any class and method :: parent_part
+ must be edited to get a unique id for the function node.
+ """
+ return {
+ "name": function_name,
+ "path": test_path,
+ "type_": "function",
+ "children": [],
+ "id_": function_id,
+ }
+
+
+def create_file_node(calculated_node_path: pathlib.Path) -> TestNode:
+ """Creates a file node from a path which has already been calculated using the get_node_path function.
+
+ Keyword arguments:
+ calculated_node_path -- the pytest file path.
+ """
+ return {
+ "name": calculated_node_path.name,
+ "path": calculated_node_path,
+ "type_": "file",
+ "id_": os.fspath(calculated_node_path),
+ "children": [],
+ }
+
+
+def create_folder_node(folder_name: str, path_iterator: pathlib.Path) -> TestNode:
+ """Creates a folder node from a pytest folder name and its path.
+
+ Keyword arguments:
+ folderName -- the name of the folder.
+ path_iterator -- the path of the folder.
+ """
+ return {
+ "name": folder_name,
+ "path": path_iterator,
+ "type_": "folder",
+ "id_": os.fspath(path_iterator),
+ "children": [],
+ }
+
+
+class DiscoveryPayloadDict(TypedDict):
+ """A dictionary that is used to send a post request to the server."""
+
+ cwd: str
+ status: Literal["success", "error"]
+ tests: TestNode | None
+ error: list[str] | None
+
+
+class ExecutionPayloadDict(Dict):
+ """A dictionary that is used to send a execution post request to the server."""
+
+ cwd: str
+ status: Literal["success", "error"]
+ result: TestRunResultDict | None
+ not_found: list[str] | None # Currently unused need to check
+ error: str | None # Currently unused need to check
+
+
+class CoveragePayloadDict(Dict):
+ """A dictionary that is used to send a execution post request to the server."""
+
+ coverage: bool
+ cwd: str
+ result: dict[str, FileCoverageInfo] | None
+ error: str | None # Currently unused need to check
+
+
+def cached_fsdecode(path: pathlib.Path) -> str:
+ """Convert path to string with caching for performance.
+
+ This function caches path-to-string conversions to avoid redundant
+ os.fsdecode() calls during test tree building.
+
+ Parameters:
+ path: The pathlib.Path object to convert to string.
+
+ Returns:
+ str: The string representation of the path.
+ """
+ if path not in _path_to_str_cache:
+ _path_to_str_cache[path] = os.fspath(path)
+ return _path_to_str_cache[path]
+
+
+def get_node_path(
+ node: pytest.Session
+ | pytest.Item
+ | pytest.File
+ | pytest.Class
+ | pytest.Module
+ | HasPathOrFspath,
+) -> pathlib.Path:
+ """A function that returns the path of a node given the switch to pathlib.Path.
+
+ It also evaluates if the node is a symlink and returns the equivalent path.
+
+ Parameters:
+ node: A pytest object or any object that has a path or fspath attribute.
+ Do NOT pass a pathlib.Path object directly; use it directly instead.
+
+ Returns:
+ pathlib.Path: The resolved path for the node.
+ """
+ cache_key = id(node)
+ if cache_key in _path_cache:
+ return _path_cache[cache_key]
+
+ node_path = getattr(node, "path", None)
+ if node_path is None:
+ fspath = getattr(node, "fspath", None)
+ node_path = pathlib.Path(fspath) if fspath is not None else None
+
+ if not node_path:
+ raise VSCodePytestError(
+ f"Unable to find path for node: {node}, node.path: {node.path}, node.fspath: {node.fspath}"
+ )
+
+ # Check for the session node since it has the symlink already.
+ if SYMLINK_PATH and not isinstance(node, pytest.Session):
+ # Get relative between the cwd (resolved path) and the node path.
+ try:
+ # Check to see if the node path contains the symlink root already
+ # Convert Path objects to strings for os.path.commonpath
+ symlink_str: str = str(SYMLINK_PATH)
+ node_path_str: str = str(node_path)
+ common_path = os.path.commonpath([symlink_str, node_path_str])
+ if common_path == os.fsdecode(SYMLINK_PATH):
+ # The node path is already relative to the SYMLINK_PATH root therefore return
+ result = node_path
+ else:
+ # If the node path is not a symlink, then we need to calculate the equivalent symlink path
+ # get the relative path between the cwd and the node path (as the node path is not a symlink).
+ # Use cached cwd to avoid repeated system calls
+ global _CACHED_CWD
+ if _CACHED_CWD is None:
+ _CACHED_CWD = pathlib.Path.cwd()
+ rel_path = node_path.relative_to(_CACHED_CWD)
+ # combine the difference between the cwd and the node path with the symlink path
+ result = pathlib.Path(SYMLINK_PATH, rel_path)
+ except Exception as e:
+ raise VSCodePytestError(
+ f"Error occurred while calculating symlink equivalent from node path: {e}"
+ f"\n SYMLINK_PATH: {SYMLINK_PATH}, \n node path: {node_path}, \n cwd: {_CACHED_CWD or pathlib.Path.cwd()}"
+ ) from e
+ else:
+ result = node_path
+
+ # Cache before returning
+ _path_cache[cache_key] = result
+ return result
+
+
+__writer = None
+atexit.register(lambda: __writer.close() if __writer else None)
+
+
+def send_execution_message(
+ cwd: str, status: Literal["success", "error"], tests: TestRunResultDict | None
+):
+ """Sends message execution payload details.
+
+ Args:
+ cwd (str): Current working directory.
+ status (Literal["success", "error"]): Execution status indicating success or error.
+ tests (Union[testRunResultDict, None]): Test run results, if available.
+ """
+ payload: ExecutionPayloadDict = ExecutionPayloadDict(
+ cwd=cwd, status=status, result=tests, not_found=None, error=None
+ )
+ if ERRORS:
+ payload["error"] = ERRORS
+ send_message(payload)
+
+
+def send_discovery_message(cwd: str, session_node: TestNode) -> None:
+ """
+ Sends a POST request with test session details in payload.
+
+ Args:
+ cwd (str): Current working directory.
+ session_node (TestNode): Node information of the test session.
+ """
+ payload: DiscoveryPayloadDict = {
+ "cwd": cwd,
+ "status": "success" if not ERRORS else "error",
+ "tests": session_node,
+ "error": [],
+ }
+ if ERRORS is not None:
+ payload["error"] = ERRORS
+ send_message(payload, cls_encoder=PathEncoder)
+
+
+class PathEncoder(json.JSONEncoder):
+ """A custom JSON encoder that encodes pathlib.Path objects as strings."""
+
+ def default(self, o):
+ if isinstance(o, pathlib.Path):
+ return os.fspath(o)
+ return super().default(o)
+
+
+def send_message(
+ payload: ExecutionPayloadDict | DiscoveryPayloadDict | CoveragePayloadDict,
+ cls_encoder=None,
+):
+ """
+ Sends a post request to the server.
+
+ Keyword arguments:
+ payload -- the payload data to be sent.
+ cls_encoder -- a custom encoder if needed.
+ """
+ if not TEST_RUN_PIPE:
+ error_msg = (
+ "PYTEST ERROR: TEST_RUN_PIPE is not set at the time of pytest starting. "
+ "Please confirm this environment variable is not being changed or removed "
+ "as it is required for successful test discovery and execution."
+ f"TEST_RUN_PIPE = {TEST_RUN_PIPE}\n"
+ )
+ print(error_msg, file=sys.stderr)
+ raise VSCodePytestError(error_msg)
+
+ global __writer
+
+ if __writer is None:
+ try:
+ __writer = open(TEST_RUN_PIPE, "wb") # noqa: SIM115, PTH123
+ except Exception as error:
+ error_msg = f"Error attempting to connect to extension named pipe {TEST_RUN_PIPE}[vscode-pytest]: {error}"
+ print(error_msg, file=sys.stderr)
+ print(
+ "If you are on a Windows machine, this error may be occurring if any of your tests clear environment variables"
+ " as they are required to communicate with the extension. Please reference https://docs.pytest.org/en/stable/how-to/monkeypatch.html#monkeypatching-environment-variables"
+ "for the correct way to clear environment variables during testing.\n",
+ file=sys.stderr,
+ )
+ __writer = None
+ raise VSCodePytestError(error_msg) from error
+
+ rpc = {
+ "jsonrpc": "2.0",
+ "params": payload,
+ }
+ data = json.dumps(rpc, cls=cls_encoder)
+ try:
+ if __writer:
+ request = (
+ f"""content-length: {len(data)}\r\ncontent-type: application/json\r\n\r\n{data}"""
+ )
+ size = 4096
+ encoded = request.encode("utf-8")
+ bytes_written = 0
+ while bytes_written < len(encoded):
+ segment = encoded[bytes_written : bytes_written + size]
+ bytes_written += __writer.write(segment)
+ __writer.flush()
+ else:
+ print(
+ f"Plugin error connection error[vscode-pytest], writer is None \n[vscode-pytest] data: \n{data} \n",
+ file=sys.stderr,
+ )
+ except Exception as error:
+ print(
+ f"Plugin error, exception thrown while attempting to send data[vscode-pytest]: {error} \n[vscode-pytest] data: \n{data}\n",
+ file=sys.stderr,
+ )
+
+
+class DeferPlugin:
+ @pytest.hookimpl(hookwrapper=True)
+ def pytest_xdist_auto_num_workers(
+ self, config: pytest.Config
+ ) -> Generator[None, Result[int], None]:
+ """Determine how many workers to use based on how many tests were selected in the test explorer."""
+ outcome = yield
+ result = min(outcome.get_result(), len(config.option.file_or_dir))
+ if result == 1:
+ result = 0
+ outcome.force_result(result)
+
+
+def pytest_plugin_registered(plugin: object, manager: pytest.PytestPluginManager):
+ plugin_name = "vscode_xdist"
+ if (
+ # only register the plugin if xdist is enabled:
+ manager.hasplugin("xdist")
+ # prevent infinite recursion:
+ and not isinstance(plugin, DeferPlugin)
+ # prevent this plugin from being registered multiple times:
+ and not manager.hasplugin(plugin_name)
+ ):
+ manager.register(DeferPlugin(), name=plugin_name)
diff --git a/python_files/vscode_pytest/_common.py b/python_files/vscode_pytest/_common.py
new file mode 100644
index 000000000000..9f835f555b6e
--- /dev/null
+++ b/python_files/vscode_pytest/_common.py
@@ -0,0 +1,2 @@
+# def send_post_request():
+# return
diff --git a/python_files/vscode_pytest/run_pytest_script.py b/python_files/vscode_pytest/run_pytest_script.py
new file mode 100644
index 000000000000..50ab12a35423
--- /dev/null
+++ b/python_files/vscode_pytest/run_pytest_script.py
@@ -0,0 +1,73 @@
+# Copyright (c) Microsoft Corporation.
+# Licensed under the MIT License.
+import os
+import pathlib
+import sys
+import sysconfig
+
+import pytest
+
+# Adds the scripts directory to the PATH as a workaround for enabling shell for test execution.
+path_var_name = "PATH" if "PATH" in os.environ else "Path"
+os.environ[path_var_name] = (
+ sysconfig.get_paths()["scripts"] + os.pathsep + os.environ[path_var_name]
+)
+
+script_dir = pathlib.Path(__file__).parent.parent
+sys.path.append(os.fspath(script_dir))
+sys.path.append(os.fspath(script_dir / "lib" / "python"))
+
+
+def run_pytest(args):
+ arg_array = ["-p", "vscode_pytest", *args]
+ pytest.main(arg_array)
+
+
+# This script handles running pytest via pytest.main(). It is called via run in the
+# pytest execution adapter and gets the test_ids to run via stdin and the rest of the
+# args through sys.argv. It then runs pytest.main() with the args and test_ids.
+
+if __name__ == "__main__":
+ # Add the root directory to the path so that we can import the plugin.
+ directory_path = pathlib.Path(__file__).parent.parent
+ sys.path.append(os.fspath(directory_path))
+ sys.path.insert(0, os.getcwd()) # noqa: PTH109
+ # Get the rest of the args to run with pytest.
+ args = sys.argv[1:]
+
+ # Check if coverage is enabled and adjust the args accordingly.
+ is_coverage_run = os.environ.get("COVERAGE_ENABLED")
+ coverage_enabled = False
+ if is_coverage_run == "True":
+ # If coverage is enabled, check if the coverage plugin is already in the args, if so keep user args.
+ for arg in args:
+ # if '--cov' is an arg or if '--cov=' is in an arg (check to see if this arg is set to not override user intent)
+ if arg == "--cov" or "--cov=" in arg:
+ print("coverage already enabled with specific args")
+ coverage_enabled = True
+ break
+ if not coverage_enabled:
+ args = [*args, "--cov=.", "--cov-branch"]
+
+ run_test_ids_pipe = os.environ.get("RUN_TEST_IDS_PIPE")
+ if run_test_ids_pipe:
+ ids_path = pathlib.Path(run_test_ids_pipe)
+ try:
+ # Read the test ids from the file and run pytest.
+ ids = ids_path.read_text(encoding="utf-8").splitlines()
+ except Exception as e:
+ print("Error[vscode-pytest]: unable to read testIds from temp file" + str(e))
+ run_pytest(args)
+ else:
+ arg_array = ["-p", "vscode_pytest", *args, *ids]
+ print("Running pytest with args: " + str(arg_array))
+ pytest.main(arg_array)
+ finally:
+ # Delete the test ids temp file.
+ try:
+ ids_path.unlink()
+ except Exception as e:
+ print("Error[vscode-pytest]: unable to delete temp file" + str(e))
+ else:
+ print("Error[vscode-pytest]: RUN_TEST_IDS_PIPE env var is not set.")
+ run_pytest(args)
diff --git a/requirements.in b/requirements.in
index 16a49eec1d88..8bbc9a0f3728 100644
--- a/requirements.in
+++ b/requirements.in
@@ -1,10 +1,10 @@
# This file is used to generate requirements.txt.
# To update requirements.txt, run the following commands.
-# 1) pip install pip-tools
-# 2) pip-compile --generate-hashes requirements.in
+# 1) Install `uv` https://docs.astral.sh/uv/getting-started/installation/
+# 2) uv pip compile --generate-hashes --upgrade requirements.in -o requirements.txt
# Unittest test adapter
-typing-extensions==4.9.0
+typing-extensions==4.15.0
# Fallback env creator for debian
microvenv
diff --git a/requirements.txt b/requirements.txt
index 838ab51d7e58..540590ed2ae7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,30 +1,71 @@
-#
-# This file is autogenerated by pip-compile with Python 3.8
-# by the following command:
-#
-# pip-compile --generate-hashes requirements.in
-#
-importlib-metadata==7.0.1 \
- --hash=sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e \
- --hash=sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc
+# This file was autogenerated by uv via the following command:
+# uv pip compile --generate-hashes requirements.in -o requirements.txt
+importlib-metadata==9.0.0 \
+ --hash=sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7 \
+ --hash=sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc
# via -r requirements.in
-microvenv==2023.5.post1 \
- --hash=sha256:32c46afea874e300f69f1add0806eb0795fd02b5fb251092fba0b73c059a7d1f \
- --hash=sha256:fd79b3dfea7860e2e84c87dd0aa8a135075f7fa2284174842b7bdeb077a0d8ac
+microvenv==2025.0 \
+ --hash=sha256:568155ec18af01c89f270d35d123ab803b09672b480c3702d15fd69e9cc5bd1e \
+ --hash=sha256:8a2568a8390a4ffb5af2f05e7642454e03b887e582d192b6316326974eab5d0f
# via -r requirements.in
-packaging==23.2 \
- --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \
- --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7
+packaging==26.2 \
+ --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \
+ --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661
# via -r requirements.in
-tomli==2.0.1 \
- --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
- --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
+tomli==2.4.1 \
+ --hash=sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853 \
+ --hash=sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe \
+ --hash=sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5 \
+ --hash=sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d \
+ --hash=sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd \
+ --hash=sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26 \
+ --hash=sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54 \
+ --hash=sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6 \
+ --hash=sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c \
+ --hash=sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a \
+ --hash=sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd \
+ --hash=sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f \
+ --hash=sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5 \
+ --hash=sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9 \
+ --hash=sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662 \
+ --hash=sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9 \
+ --hash=sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1 \
+ --hash=sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585 \
+ --hash=sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e \
+ --hash=sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c \
+ --hash=sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41 \
+ --hash=sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f \
+ --hash=sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085 \
+ --hash=sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15 \
+ --hash=sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7 \
+ --hash=sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c \
+ --hash=sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36 \
+ --hash=sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076 \
+ --hash=sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac \
+ --hash=sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8 \
+ --hash=sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232 \
+ --hash=sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece \
+ --hash=sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a \
+ --hash=sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897 \
+ --hash=sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d \
+ --hash=sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4 \
+ --hash=sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917 \
+ --hash=sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396 \
+ --hash=sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a \
+ --hash=sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc \
+ --hash=sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba \
+ --hash=sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f \
+ --hash=sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257 \
+ --hash=sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30 \
+ --hash=sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf \
+ --hash=sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9 \
+ --hash=sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049
# via -r requirements.in
-typing-extensions==4.9.0 \
- --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
- --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
+typing-extensions==4.15.0 \
+ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \
+ --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548
# via -r requirements.in
-zipp==3.15.0 \
- --hash=sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b \
- --hash=sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556
+zipp==3.21.0 \
+ --hash=sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4 \
+ --hash=sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931
# via importlib-metadata
diff --git a/resources/report_issue_template.md b/resources/report_issue_template.md
index a0892ecba53b..a95af90ff7fe 100644
--- a/resources/report_issue_template.md
+++ b/resources/report_issue_template.md
@@ -1,6 +1,5 @@
# Behaviour
-## Expected vs. Actual
XXX
@@ -12,13 +11,9 @@ XXX
**After** creating the issue on GitHub, you can add screenshots and GIFs of what is happening. Consider tools like https://www.cockos.com/licecap/, https://github.com/phw/peek or https://www.screentogif.com/ for GIF creation.
-->
-
+
# Diagnostic data
-- Python version (& distribution if applicable, e.g. Anaconda): {0}
-- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): {1}
-- Value of the `python.languageServer` setting: {2}
-
Output for Python in the Output panel (ViewβOutput, change the drop-down the upper-right of the Output panel to Python)
@@ -32,16 +27,3 @@ XXX
-
-
-
-User Settings
-
-
-
-```
-{3}{4}
-```
-
-
-
diff --git a/resources/report_issue_user_data_template.md b/resources/report_issue_user_data_template.md
new file mode 100644
index 000000000000..037b844511d3
--- /dev/null
+++ b/resources/report_issue_user_data_template.md
@@ -0,0 +1,21 @@
+- Python version (& distribution if applicable, e.g. Anaconda): {0}
+- Type of virtual environment used (e.g. conda, venv, virtualenv, etc.): {1}
+- Value of the `python.languageServer` setting: {2}
+
+
+User Settings
+
+
+```
+{3}{4}
+```
+
+
+
+
+Installed Extensions
+
+|Extension Name|Extension Id|Version|
+|---|---|---|
+{5}
+
diff --git a/resources/report_issue_user_settings.json b/resources/report_issue_user_settings.json
index eea4ca007da6..7e034651c46d 100644
--- a/resources/report_issue_user_settings.json
+++ b/resources/report_issue_user_settings.json
@@ -11,6 +11,7 @@
"condaPath": "placeholder",
"pipenvPath": "placeholder",
"poetryPath": "placeholder",
+ "pixiToolPath": "placeholder",
"devOptions": false,
"globalModuleInstallation": false,
"languageServer": true,
@@ -78,7 +79,8 @@
"pytestPath": "placeholder",
"unittestArgs": "placeholder",
"unittestEnabled": true,
- "autoTestDiscoverOnSaveEnabled": true
+ "autoTestDiscoverOnSaveEnabled": true,
+ "autoTestDiscoverOnSavePattern": "placeholder"
},
"terminal": {
"activateEnvironment": true,
diff --git a/schemas/conda-environment.json b/schemas/conda-environment.json
index 458676942a44..fb1e821778c3 100644
--- a/schemas/conda-environment.json
+++ b/schemas/conda-environment.json
@@ -1,6 +1,6 @@
{
"title": "conda environment file",
- "description": "Support for conda's enviroment.yml files (e.g. `conda env export > environment.yml`)",
+ "description": "Support for conda's environment.yml files (e.g. `conda env export > environment.yml`)",
"id": "https://raw.githubusercontent.com/Microsoft/vscode-python/main/schemas/conda-environment.json",
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
diff --git a/schemas/condarc.json b/schemas/condarc.json
index 396236238c1a..a881315d3137 100644
--- a/schemas/condarc.json
+++ b/schemas/condarc.json
@@ -59,7 +59,14 @@
}
},
"ssl_verify": {
- "type": "boolean"
+ "oneOf": [
+ {
+ "type": "boolean"
+ },
+ {
+ "type": "string"
+ }
+ ]
},
"offline": {
"type": "boolean"
diff --git a/scripts/cleanup-eslintignore.js b/scripts/cleanup-eslintignore.js
new file mode 100644
index 000000000000..848f5a9c4910
--- /dev/null
+++ b/scripts/cleanup-eslintignore.js
@@ -0,0 +1,44 @@
+const fs = require('fs');
+const path = require('path');
+
+const baseDir = process.cwd();
+const eslintignorePath = path.join(baseDir, '.eslintignore');
+
+fs.readFile(eslintignorePath, 'utf8', (err, data) => {
+ if (err) {
+ console.error('Error reading .eslintignore file:', err);
+ return;
+ }
+
+ const lines = data.split('\n');
+ const files = lines.map((line) => line.trim()).filter((line) => line && !line.startsWith('#'));
+ const nonExistentFiles = [];
+
+ files.forEach((file) => {
+ const filePath = path.join(baseDir, file);
+ if (!fs.existsSync(filePath) && file !== 'pythonExtensionApi/out/') {
+ nonExistentFiles.push(file);
+ }
+ });
+
+ if (nonExistentFiles.length > 0) {
+ console.log('The following files listed in .eslintignore do not exist:');
+ nonExistentFiles.forEach((file) => console.log(file));
+
+ const updatedLines = lines.filter((line) => {
+ const trimmedLine = line.trim();
+ return !nonExistentFiles.includes(trimmedLine) || trimmedLine === 'pythonExtensionApi/out/';
+ });
+ const updatedData = `${updatedLines.join('\n')}\n`;
+
+ fs.writeFile(eslintignorePath, updatedData, 'utf8', (err) => {
+ if (err) {
+ console.error('Error writing to .eslintignore file:', err);
+ return;
+ }
+ console.log('Non-existent files have been removed from .eslintignore.');
+ });
+ } else {
+ console.log('All files listed in .eslintignore exist.');
+ }
+});
diff --git a/scripts/issue_velocity_summary_script.py b/scripts/issue_velocity_summary_script.py
new file mode 100644
index 000000000000..94929d1798a9
--- /dev/null
+++ b/scripts/issue_velocity_summary_script.py
@@ -0,0 +1,110 @@
+"""
+This script fetches open issues from the microsoft/vscode-python repository,
+calculates the thumbs-up per day for each issue, and generates a markdown
+summary of the issues sorted by highest thumbs-up per day. Issues with zero
+thumbs-up are excluded from the summary.
+"""
+
+import requests
+import os
+from datetime import datetime, timezone
+
+
+GITHUB_API_URL = "https://api.github.com"
+REPO = "microsoft/vscode-python"
+TOKEN = os.getenv("GITHUB_TOKEN")
+
+
+def fetch_issues():
+ """
+ Fetches all open issues from the specified GitHub repository.
+
+ Returns:
+ list: A list of dictionaries representing the issues.
+ """
+ headers = {"Authorization": f"token {TOKEN}"}
+ issues = []
+ page = 1
+ while True:
+ query = (
+ f"{GITHUB_API_URL}/repos/{REPO}/issues?state=open&per_page=25&page={page}"
+ )
+ response = requests.get(query, headers=headers)
+ if response.status_code == 403:
+ raise Exception(
+ "Access forbidden: Check your GitHub token and permissions."
+ )
+ response.raise_for_status()
+ page_issues = response.json()
+ if not page_issues:
+ break
+ issues.extend(page_issues)
+ page += 1
+ return issues
+
+
+def calculate_thumbs_up_per_day(issue):
+ """
+ Calculates the thumbs-up per day for a given issue.
+
+ Args:
+ issue (dict): A dictionary representing the issue.
+
+ Returns:
+ float: The thumbs-up per day for the issue.
+ """
+ created_at = datetime.strptime(issue["created_at"], "%Y-%m-%dT%H:%M:%SZ").replace(
+ tzinfo=timezone.utc
+ )
+ now = datetime.now(timezone.utc)
+ days_open = (now - created_at).days or 1
+ thumbs_up = issue["reactions"].get("+1", 0)
+ return thumbs_up / days_open
+
+
+def generate_markdown_summary(issues):
+ """
+ Generates a markdown summary of the issues.
+
+ Args:
+ issues (list): A list of dictionaries representing the issues.
+
+ Returns:
+ str: A markdown-formatted string summarizing the issues.
+ """
+ summary = "| URL | Title | π | Days Open | π/day |\n| --- | ----- | --- | --------- | ------ |\n"
+ issues_with_thumbs_up = []
+ for issue in issues:
+ created_at = datetime.strptime(
+ issue["created_at"], "%Y-%m-%dT%H:%M:%SZ"
+ ).replace(tzinfo=timezone.utc)
+ now = datetime.now(timezone.utc)
+ days_open = (now - created_at).days or 1
+ thumbs_up = issue["reactions"].get("+1", 0)
+ if thumbs_up > 0:
+ thumbs_up_per_day = thumbs_up / days_open
+ issues_with_thumbs_up.append(
+ (issue, thumbs_up, days_open, thumbs_up_per_day)
+ )
+
+ # Sort issues by thumbs_up_per_day in descending order
+ issues_with_thumbs_up.sort(key=lambda x: x[3], reverse=True)
+
+ for issue, thumbs_up, days_open, thumbs_up_per_day in issues_with_thumbs_up:
+ summary += f"| {issue['html_url']} | {issue['title']} | {thumbs_up} | {days_open} | {thumbs_up_per_day:.2f} |\n"
+
+ return summary
+
+
+def main():
+ """
+ Main function to fetch issues, generate the markdown summary, and write it to a file.
+ """
+ issues = fetch_issues()
+ summary = generate_markdown_summary(issues)
+ with open("endorsement_velocity_summary.md", "w") as f:
+ f.write(summary)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/onCreateCommand.sh b/scripts/onCreateCommand.sh
index 05ffe64a8c0b..3d473d1ee172 100644
--- a/scripts/onCreateCommand.sh
+++ b/scripts/onCreateCommand.sh
@@ -12,7 +12,7 @@ command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
source ~/.bashrc
# Install Python via pyenv .
-pyenv install 3.8:latest 3.9:latest 3.10:latest 3.11:latest
+pyenv install 3.8.18 3.9:latest 3.10:latest 3.11:latest
# Set default Python version to 3.8 .
pyenv global 3.8.18
@@ -20,7 +20,7 @@ pyenv global 3.8.18
npm ci
# Create Virutal environment.
-pyenv exec python3.8 -m venv .venv
+pyenv exec python -m venv .venv
# Activate Virtual environment.
source /workspaces/vscode-python/.venv/bin/activate
diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts
index 763ce1ae8819..9e97c5c48857 100644
--- a/src/client/activation/activationManager.ts
+++ b/src/client/activation/activationManager.ts
@@ -11,6 +11,7 @@ import { PYTHON_LANGUAGE } from '../common/constants';
import { IFileSystem } from '../common/platform/types';
import { IDisposable, IInterpreterPathService, Resource } from '../common/types';
import { Deferred } from '../common/utils/async';
+import { StopWatch } from '../common/utils/stopWatch';
import { IInterpreterAutoSelectionService } from '../interpreter/autoSelection/types';
import { traceDecoratorError } from '../logging';
import { sendActivationTelemetry } from '../telemetry/envFileTelemetry';
@@ -69,7 +70,7 @@ export class ExtensionActivationManager implements IExtensionActivationManager {
}
}
- public async activate(): Promise {
+ public async activate(startupStopWatch: StopWatch): Promise {
this.filterServices();
await this.initialize();
@@ -77,12 +78,12 @@ export class ExtensionActivationManager implements IExtensionActivationManager {
await Promise.all([
...this.singleActivationServices.map((item) => item.activate()),
- this.activateWorkspace(this.activeResourceService.getActiveResource()),
+ this.activateWorkspace(this.activeResourceService.getActiveResource(), startupStopWatch),
]);
}
@traceDecoratorError('Failed to activate a workspace')
- public async activateWorkspace(resource: Resource): Promise {
+ public async activateWorkspace(resource: Resource, startupStopWatch?: StopWatch): Promise {
const folder = this.workspaceService.getWorkspaceFolder(resource);
resource = folder ? folder.uri : undefined;
const key = this.getWorkspaceKey(resource);
@@ -97,7 +98,7 @@ export class ExtensionActivationManager implements IExtensionActivationManager {
await this.interpreterPathService.copyOldInterpreterStorageValuesToNew(resource);
}
await sendActivationTelemetry(this.fileSystem, this.workspaceService, resource);
- await Promise.all(this.activationServices.map((item) => item.activate(resource)));
+ await Promise.all(this.activationServices.map((item) => item.activate(resource, startupStopWatch)));
await this.appDiagnostics.performPreStartupHealthCheck(resource);
}
diff --git a/src/client/activation/extensionSurvey.ts b/src/client/activation/extensionSurvey.ts
index 11b581a27252..d32ba7180c0f 100644
--- a/src/client/activation/extensionSurvey.ts
+++ b/src/client/activation/extensionSurvey.ts
@@ -3,10 +3,10 @@
'use strict';
-import { inject, injectable, optional } from 'inversify';
+import { inject, injectable } from 'inversify';
import * as querystring from 'querystring';
import { env, UIKind } from 'vscode';
-import { IApplicationEnvironment, IApplicationShell } from '../common/application/types';
+import { IApplicationEnvironment, IApplicationShell, IWorkspaceService } from '../common/application/types';
import { ShowExtensionSurveyPrompt } from '../common/experiments/groups';
import '../common/extensions';
import { IPlatformService } from '../common/platform/types';
@@ -37,8 +37,9 @@ export class ExtensionSurveyPrompt implements IExtensionSingleActivationService
@inject(IExperimentService) private experiments: IExperimentService,
@inject(IApplicationEnvironment) private appEnvironment: IApplicationEnvironment,
@inject(IPlatformService) private platformService: IPlatformService,
- @optional() private sampleSizePerOneHundredUsers: number = 10,
- @optional() private waitTimeToShowSurvey: number = WAIT_TIME_TO_SHOW_SURVEY,
+ @inject(IWorkspaceService) private readonly workspace: IWorkspaceService,
+ private sampleSizePerOneHundredUsers: number = 10,
+ private waitTimeToShowSurvey: number = WAIT_TIME_TO_SHOW_SURVEY,
) {}
public async activate(): Promise {
@@ -57,6 +58,18 @@ export class ExtensionSurveyPrompt implements IExtensionSingleActivationService
if (env.uiKind === UIKind?.Web) {
return false;
}
+
+ let feedbackEnabled = true;
+
+ const telemetryConfig = this.workspace.getConfiguration('telemetry');
+ if (telemetryConfig) {
+ feedbackEnabled = telemetryConfig.get('feedback.enabled', true);
+ }
+
+ if (!feedbackEnabled) {
+ return false;
+ }
+
const doNotShowSurveyAgain = this.persistentState.createGlobalPersistentState(
extensionSurveyStateKeys.doNotShowAgain,
false,
diff --git a/src/client/activation/jedi/analysisOptions.ts b/src/client/activation/jedi/analysisOptions.ts
index 3b1897b91088..007008dc9b13 100644
--- a/src/client/activation/jedi/analysisOptions.ts
+++ b/src/client/activation/jedi/analysisOptions.ts
@@ -85,6 +85,9 @@ export class JediLanguageServerAnalysisOptions extends LanguageServerAnalysisOpt
maxSymbols: 0,
},
},
+ semantic_tokens: {
+ enable: true,
+ },
};
}
}
diff --git a/src/client/activation/jedi/languageClientFactory.ts b/src/client/activation/jedi/languageClientFactory.ts
index c3ef8d9623f3..70bd65da8d0d 100644
--- a/src/client/activation/jedi/languageClientFactory.ts
+++ b/src/client/activation/jedi/languageClientFactory.ts
@@ -21,7 +21,7 @@ export class JediLanguageClientFactory implements ILanguageClientFactory {
clientOptions: LanguageClientOptions,
): Promise {
// Just run the language server using a module
- const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'run-jedi-language-server.py');
+ const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'python_files', 'run-jedi-language-server.py');
const interpreter = await this.interpreterService.getActiveInterpreter(resource);
const serverOptions: ServerOptions = {
command: interpreter ? interpreter.path : 'python',
diff --git a/src/client/activation/jedi/languageClientMiddleware.ts b/src/client/activation/jedi/languageClientMiddleware.ts
index 656c47309bb9..c8bb99629946 100644
--- a/src/client/activation/jedi/languageClientMiddleware.ts
+++ b/src/client/activation/jedi/languageClientMiddleware.ts
@@ -8,6 +8,5 @@ import { LanguageServerType } from '../types';
export class JediLanguageClientMiddleware extends LanguageClientMiddleware {
public constructor(serviceContainer: IServiceContainer, serverVersion?: string) {
super(serviceContainer, LanguageServerType.Jedi, serverVersion);
- this.setupHidingMiddleware(serviceContainer);
}
}
diff --git a/src/client/activation/jedi/manager.ts b/src/client/activation/jedi/manager.ts
index 672e9a1b33fd..bafdcc735a12 100644
--- a/src/client/activation/jedi/manager.ts
+++ b/src/client/activation/jedi/manager.ts
@@ -68,7 +68,7 @@ export class JediLanguageServerManager implements ILanguageServerManager {
try {
// Version is actually hardcoded in our requirements.txt.
const requirementsTxt = await fs.readFile(
- path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'jedilsp_requirements', 'requirements.txt'),
+ path.join(EXTENSION_ROOT_DIR, 'python_files', 'jedilsp_requirements', 'requirements.txt'),
'utf-8',
);
diff --git a/src/client/activation/languageClientMiddleware.ts b/src/client/activation/languageClientMiddleware.ts
index 110d7461c615..d3d1e0c3c171 100644
--- a/src/client/activation/languageClientMiddleware.ts
+++ b/src/client/activation/languageClientMiddleware.ts
@@ -1,58 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import { IJupyterExtensionDependencyManager } from '../common/application/types';
-import { IDisposableRegistry, IExtensions } from '../common/types';
import { IServiceContainer } from '../ioc/types';
import { sendTelemetryEvent } from '../telemetry';
import { LanguageClientMiddlewareBase } from './languageClientMiddlewareBase';
import { LanguageServerType } from './types';
-import { createHidingMiddleware } from '@vscode/jupyter-lsp-middleware';
-
export class LanguageClientMiddleware extends LanguageClientMiddlewareBase {
public constructor(serviceContainer: IServiceContainer, serverType: LanguageServerType, serverVersion?: string) {
super(serviceContainer, serverType, sendTelemetryEvent, serverVersion);
}
-
- /**
- * Creates the HidingMiddleware if needed and sets up code to do so if needed after
- * Jupyter is installed.
- *
- * This method should be called from the constructor of derived classes. It is separated
- * from the constructor to allow derived classes to initialize before it is called.
- */
- protected setupHidingMiddleware(serviceContainer: IServiceContainer) {
- const jupyterDependencyManager = serviceContainer.get(
- IJupyterExtensionDependencyManager,
- );
- const disposables = serviceContainer.get(IDisposableRegistry) || [];
- const extensions = serviceContainer.get(IExtensions);
-
- // Enable notebook support if jupyter support is installed
- if (this.shouldCreateHidingMiddleware(jupyterDependencyManager)) {
- this.notebookAddon = createHidingMiddleware();
- }
-
- disposables.push(
- extensions?.onDidChange(async () => {
- await this.onExtensionChange(jupyterDependencyManager);
- }),
- );
- }
-
- protected shouldCreateHidingMiddleware(jupyterDependencyManager: IJupyterExtensionDependencyManager): boolean {
- return jupyterDependencyManager && jupyterDependencyManager.isJupyterExtensionInstalled;
- }
-
- protected async onExtensionChange(jupyterDependencyManager: IJupyterExtensionDependencyManager): Promise {
- if (jupyterDependencyManager) {
- if (this.notebookAddon && !this.shouldCreateHidingMiddleware(jupyterDependencyManager)) {
- this.notebookAddon = undefined;
- } else if (!this.notebookAddon && this.shouldCreateHidingMiddleware(jupyterDependencyManager)) {
- this.notebookAddon = createHidingMiddleware();
- }
- }
- }
}
diff --git a/src/client/activation/languageClientMiddlewareBase.ts b/src/client/activation/languageClientMiddlewareBase.ts
index 5f7b6fa72656..f1e102a4081d 100644
--- a/src/client/activation/languageClientMiddlewareBase.ts
+++ b/src/client/activation/languageClientMiddlewareBase.ts
@@ -87,10 +87,7 @@ export class LanguageClientMiddlewareBase implements Middleware {
const settingDict: LSPObject & { pythonPath: string; _envPYTHONPATH: string } = settings[
i
] as LSPObject & { pythonPath: string; _envPYTHONPATH: string };
- settingDict.pythonPath =
- (await this.getPythonPathOverride(uri)) ??
- (await interpreterService.getActiveInterpreter(uri))?.path ??
- 'python';
+ settingDict.pythonPath = (await interpreterService.getActiveInterpreter(uri))?.path ?? 'python';
const env = await envService.getEnvironmentVariables(uri);
const envPYTHONPATH = env.PYTHONPATH;
@@ -106,11 +103,6 @@ export class LanguageClientMiddlewareBase implements Middleware {
},
};
- // eslint-disable-next-line class-methods-use-this
- protected async getPythonPathOverride(_uri: Uri | undefined): Promise {
- return undefined;
- }
-
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function
protected configurationHook(_item: ConfigurationItem, _settings: LSPObject): void {}
diff --git a/src/client/activation/node/languageClientMiddleware.ts b/src/client/activation/node/languageClientMiddleware.ts
index fbc534f17e1c..dfd65f1bb418 100644
--- a/src/client/activation/node/languageClientMiddleware.ts
+++ b/src/client/activation/node/languageClientMiddleware.ts
@@ -1,104 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import { Uri } from 'vscode';
-import { ConfigurationItem, LanguageClient, LSPObject } from 'vscode-languageclient/node';
-import { IJupyterExtensionDependencyManager, IWorkspaceService } from '../../common/application/types';
import { IServiceContainer } from '../../ioc/types';
-import { JupyterExtensionIntegration } from '../../jupyter/jupyterIntegration';
-import { traceLog } from '../../logging';
import { LanguageClientMiddleware } from '../languageClientMiddleware';
-import { LspInteractiveWindowMiddlewareAddon } from './lspInteractiveWindowMiddlewareAddon';
import { LanguageServerType } from '../types';
-import { LspNotebooksExperiment } from './lspNotebooksExperiment';
-
export class NodeLanguageClientMiddleware extends LanguageClientMiddleware {
- private readonly lspNotebooksExperiment: LspNotebooksExperiment;
-
- private readonly jupyterExtensionIntegration: JupyterExtensionIntegration;
-
- private readonly workspaceService: IWorkspaceService;
-
- public constructor(
- serviceContainer: IServiceContainer,
- private getClient: () => LanguageClient | undefined,
- serverVersion?: string,
- ) {
+ public constructor(serviceContainer: IServiceContainer, serverVersion?: string) {
super(serviceContainer, LanguageServerType.Node, serverVersion);
-
- this.workspaceService = serviceContainer.get(IWorkspaceService);
-
- this.lspNotebooksExperiment = serviceContainer.get(LspNotebooksExperiment);
- this.setupHidingMiddleware(serviceContainer);
-
- this.jupyterExtensionIntegration = serviceContainer.get(
- JupyterExtensionIntegration,
- );
- if (!this.notebookAddon) {
- this.notebookAddon = new LspInteractiveWindowMiddlewareAddon(
- this.getClient,
- this.jupyterExtensionIntegration,
- );
- }
- }
-
- // eslint-disable-next-line class-methods-use-this
- protected shouldCreateHidingMiddleware(_: IJupyterExtensionDependencyManager): boolean {
- return false;
- }
-
- protected async onExtensionChange(jupyterDependencyManager: IJupyterExtensionDependencyManager): Promise {
- if (jupyterDependencyManager && jupyterDependencyManager.isJupyterExtensionInstalled) {
- await this.lspNotebooksExperiment.onJupyterInstalled();
- }
-
- if (!this.notebookAddon) {
- this.notebookAddon = new LspInteractiveWindowMiddlewareAddon(
- this.getClient,
- this.jupyterExtensionIntegration,
- );
- }
- }
-
- protected async getPythonPathOverride(uri: Uri | undefined): Promise {
- if (!uri) {
- return undefined;
- }
-
- const jupyterPythonPathFunction = this.jupyterExtensionIntegration.getJupyterPythonPathFunction();
- if (!jupyterPythonPathFunction) {
- return undefined;
- }
-
- const result = await jupyterPythonPathFunction(uri);
-
- if (result) {
- traceLog(`Jupyter provided interpreter path override: ${result}`);
- }
-
- return result;
- }
-
- // eslint-disable-next-line class-methods-use-this
- protected configurationHook(item: ConfigurationItem, settings: LSPObject): void {
- if (item.section === 'editor') {
- if (this.workspaceService) {
- // Get editor.formatOnType using Python language id so [python] setting
- // will be honored if present.
- const editorConfig = this.workspaceService.getConfiguration(
- item.section,
- undefined,
- /* languageSpecific */ true,
- );
-
- const settingDict: LSPObject & { formatOnType?: boolean } = settings as LSPObject & {
- formatOnType: boolean;
- };
-
- settingDict.formatOnType = editorConfig.get('formatOnType');
- }
- }
}
}
diff --git a/src/client/activation/node/lspInteractiveWindowMiddlewareAddon.ts b/src/client/activation/node/lspInteractiveWindowMiddlewareAddon.ts
deleted file mode 100644
index 0a40915d98eb..000000000000
--- a/src/client/activation/node/lspInteractiveWindowMiddlewareAddon.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { Disposable, NotebookCell, NotebookDocument, TextDocument, TextDocumentChangeEvent, Uri } from 'vscode';
-import { Converter } from 'vscode-languageclient/lib/common/codeConverter';
-import {
- DidChangeNotebookDocumentNotification,
- LanguageClient,
- Middleware,
- NotebookCellKind,
- NotebookDocumentChangeEvent,
-} from 'vscode-languageclient/node';
-import * as proto from 'vscode-languageserver-protocol';
-import { JupyterExtensionIntegration } from '../../jupyter/jupyterIntegration';
-
-type TextContent = Required['cells']>['textContent']>[0];
-
-/**
- * Detects the input box text documents of Interactive Windows and makes them appear to be
- * the last cell of their corresponding notebooks.
- */
-export class LspInteractiveWindowMiddlewareAddon implements Middleware, Disposable {
- constructor(
- private readonly getClient: () => LanguageClient | undefined,
- private readonly jupyterExtensionIntegration: JupyterExtensionIntegration,
- ) {
- // Make sure a bunch of functions are bound to this. VS code can call them without a this context
- this.didOpen = this.didOpen.bind(this);
- this.didChange = this.didChange.bind(this);
- this.didClose = this.didClose.bind(this);
- }
-
- public dispose(): void {
- // Nothing to dispose at the moment
- }
-
- // Map of document URIs to NotebookDocuments for all known notebooks.
- private notebookDocumentMap: Map = new Map();
-
- // Map of document URIs to TextDocuments that should be linked to a notebook
- // whose didOpen we're expecting to see in the future.
- private unlinkedTextDocumentMap: Map = new Map();
-
- public async didOpen(document: TextDocument, next: (ev: TextDocument) => Promise): Promise {
- const notebookUri = this.getNotebookUriForTextDocumentUri(document.uri);
- if (!notebookUri) {
- await next(document);
- return;
- }
-
- const notebookDocument = this.notebookDocumentMap.get(notebookUri.toString());
- if (!notebookDocument) {
- this.unlinkedTextDocumentMap.set(notebookUri.toString(), document);
- return;
- }
-
- try {
- const result: NotebookDocumentChangeEvent = {
- cells: {
- structure: {
- array: {
- start: notebookDocument.cellCount,
- deleteCount: 0,
- cells: [{ kind: NotebookCellKind.Code, document: document.uri.toString() }],
- },
- didOpen: [
- {
- uri: document.uri.toString(),
- languageId: document.languageId,
- version: document.version,
- text: document.getText(),
- },
- ],
- didClose: undefined,
- },
- },
- };
-
- await this.getClient()?.sendNotification(DidChangeNotebookDocumentNotification.type, {
- notebookDocument: { version: notebookDocument.version, uri: notebookUri.toString() },
- change: result,
- });
- } catch (error) {
- this.getClient()?.error('Sending DidChangeNotebookDocumentNotification failed', error);
- throw error;
- }
- }
-
- public async didChange(
- event: TextDocumentChangeEvent,
- next: (ev: TextDocumentChangeEvent) => Promise,
- ): Promise {
- const notebookUri = this.getNotebookUriForTextDocumentUri(event.document.uri);
- if (!notebookUri) {
- await next(event);
- return;
- }
-
- const notebookDocument = this.notebookDocumentMap.get(notebookUri.toString());
- if (notebookDocument) {
- const client = this.getClient();
- if (client) {
- client.sendNotification(proto.DidChangeNotebookDocumentNotification.type, {
- notebookDocument: { uri: notebookUri.toString(), version: notebookDocument.version },
- change: {
- cells: {
- textContent: [
- LspInteractiveWindowMiddlewareAddon._asTextContentChange(
- event,
- client.code2ProtocolConverter,
- ),
- ],
- },
- },
- });
- }
- }
- }
-
- private static _asTextContentChange(event: TextDocumentChangeEvent, c2pConverter: Converter): TextContent {
- const params = c2pConverter.asChangeTextDocumentParams(event, event.document.uri, event.document.version);
- return { document: params.textDocument, changes: params.contentChanges };
- }
-
- public async didClose(document: TextDocument, next: (ev: TextDocument) => Promise): Promise {
- const notebookUri = this.getNotebookUriForTextDocumentUri(document.uri);
- if (!notebookUri) {
- await next(document);
- return;
- }
-
- this.unlinkedTextDocumentMap.delete(notebookUri.toString());
- }
-
- public async didOpenNotebook(
- notebookDocument: NotebookDocument,
- cells: NotebookCell[],
- next: (notebookDocument: NotebookDocument, cells: NotebookCell[]) => Promise,
- ): Promise {
- this.notebookDocumentMap.set(notebookDocument.uri.toString(), notebookDocument);
-
- const relatedTextDocument = this.unlinkedTextDocumentMap.get(notebookDocument.uri.toString());
- if (relatedTextDocument) {
- const newCells = [
- ...cells,
- {
- index: notebookDocument.cellCount,
- notebook: notebookDocument,
- kind: NotebookCellKind.Code,
- document: relatedTextDocument,
- metadata: {},
- outputs: [],
- executionSummary: undefined,
- },
- ];
-
- this.unlinkedTextDocumentMap.delete(notebookDocument.uri.toString());
-
- await next(notebookDocument, newCells);
- } else {
- await next(notebookDocument, cells);
- }
- }
-
- public async didCloseNotebook(
- notebookDocument: NotebookDocument,
- cells: NotebookCell[],
- next: (notebookDocument: NotebookDocument, cells: NotebookCell[]) => Promise,
- ): Promise {
- this.notebookDocumentMap.delete(notebookDocument.uri.toString());
-
- await next(notebookDocument, cells);
- }
-
- notebooks = {
- didOpen: this.didOpenNotebook.bind(this),
- didClose: this.didCloseNotebook.bind(this),
- };
-
- private getNotebookUriForTextDocumentUri(textDocumentUri: Uri): Uri | undefined {
- const getNotebookUriFunction = this.jupyterExtensionIntegration.getGetNotebookUriForTextDocumentUriFunction();
- if (!getNotebookUriFunction) {
- return undefined;
- }
-
- return getNotebookUriFunction(textDocumentUri);
- }
-}
diff --git a/src/client/activation/node/lspNotebooksExperiment.ts b/src/client/activation/node/lspNotebooksExperiment.ts
deleted file mode 100644
index de0acde0600e..000000000000
--- a/src/client/activation/node/lspNotebooksExperiment.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { inject, injectable } from 'inversify';
-import { IExtensionSingleActivationService } from '../types';
-import { traceVerbose } from '../../logging';
-import { IJupyterExtensionDependencyManager } from '../../common/application/types';
-import { IServiceContainer } from '../../ioc/types';
-import { sleep } from '../../common/utils/async';
-import { JupyterExtensionIntegration } from '../../jupyter/jupyterIntegration';
-
-@injectable()
-export class LspNotebooksExperiment implements IExtensionSingleActivationService {
- public readonly supportedWorkspaceTypes = { untrustedWorkspace: true, virtualWorkspace: true };
-
- private isJupyterInstalled = false;
-
- constructor(
- @inject(IServiceContainer) private readonly serviceContainer: IServiceContainer,
- @inject(IJupyterExtensionDependencyManager) jupyterDependencyManager: IJupyterExtensionDependencyManager,
- ) {
- this.isJupyterInstalled = jupyterDependencyManager.isJupyterExtensionInstalled;
- }
-
- // eslint-disable-next-line class-methods-use-this
- public activate(): Promise {
- return Promise.resolve();
- }
-
- public async onJupyterInstalled(): Promise {
- if (this.isJupyterInstalled) {
- return;
- }
-
- await this.waitForJupyterToRegisterPythonPathFunction();
-
- this.isJupyterInstalled = true;
- }
-
- private async waitForJupyterToRegisterPythonPathFunction(): Promise {
- const jupyterExtensionIntegration = this.serviceContainer.get(
- JupyterExtensionIntegration,
- );
-
- let success = false;
- for (let tryCount = 0; tryCount < 20; tryCount += 1) {
- const jupyterPythonPathFunction = jupyterExtensionIntegration.getJupyterPythonPathFunction();
- if (jupyterPythonPathFunction) {
- traceVerbose(`Jupyter called registerJupyterPythonPathFunction`);
- success = true;
- break;
- }
-
- await sleep(500);
- }
-
- if (!success) {
- traceVerbose(`Timed out waiting for Jupyter to call registerJupyterPythonPathFunction`);
- }
- }
-}
diff --git a/src/client/activation/node/manager.ts b/src/client/activation/node/manager.ts
index b85d8fe6ed14..5a66e4abecd0 100644
--- a/src/client/activation/node/manager.ts
+++ b/src/client/activation/node/manager.ts
@@ -116,11 +116,7 @@ export class NodeLanguageServerManager implements ILanguageServerManager {
@traceDecoratorVerbose('Starting language server')
protected async startLanguageServer(): Promise {
const options = await this.analysisOptions.getAnalysisOptions();
- this.middleware = new NodeLanguageClientMiddleware(
- this.serviceContainer,
- () => this.languageServerProxy.languageClient,
- this.lsVersion,
- );
+ this.middleware = new NodeLanguageClientMiddleware(this.serviceContainer, this.lsVersion);
options.middleware = this.middleware;
// Make sure the middleware is connected if we restart and we we're already connected.
diff --git a/src/client/activation/node/pylanceApi.ts b/src/client/activation/node/pylanceApi.ts
index 72f20db140e4..4b3d21d7527e 100644
--- a/src/client/activation/node/pylanceApi.ts
+++ b/src/client/activation/node/pylanceApi.ts
@@ -18,7 +18,6 @@ export interface PylanceApi {
};
notebook?: {
registerJupyterPythonPathFunction(func: (uri: Uri) => Promise): void;
- registerGetNotebookUriForTextDocumentUriFunction(func: (textDocumentUri: Uri) => Uri | undefined): void;
getCompletionItems(
document: TextDocument,
position: Position,
diff --git a/src/client/activation/requirementsTxtLinkActivator.ts b/src/client/activation/requirementsTxtLinkActivator.ts
new file mode 100644
index 000000000000..fcb6b72e545e
--- /dev/null
+++ b/src/client/activation/requirementsTxtLinkActivator.ts
@@ -0,0 +1,26 @@
+import { injectable } from 'inversify';
+import { Hover, languages, TextDocument, Position } from 'vscode';
+import { IExtensionSingleActivationService } from './types';
+
+const PYPI_PROJECT_URL = 'https://pypi.org/project';
+
+export function generatePyPiLink(name: string): string | null {
+ // Regex to allow to find every possible pypi package (base regex from https://peps.python.org/pep-0508/#names)
+ const projectName = name.match(/^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*)($|=| |;|\[)/i);
+ return projectName ? `${PYPI_PROJECT_URL}/${projectName[1]}/` : null;
+}
+
+@injectable()
+export class RequirementsTxtLinkActivator implements IExtensionSingleActivationService {
+ public readonly supportedWorkspaceTypes = { untrustedWorkspace: true, virtualWorkspace: true };
+
+ // eslint-disable-next-line class-methods-use-this
+ public async activate(): Promise {
+ languages.registerHoverProvider([{ pattern: '**/*requirement*.txt' }, { pattern: '**/requirements/*.txt' }], {
+ provideHover(document: TextDocument, position: Position) {
+ const link = generatePyPiLink(document.lineAt(position.line).text);
+ return link ? new Hover(link) : null;
+ },
+ });
+ }
+}
diff --git a/src/client/activation/serviceRegistry.ts b/src/client/activation/serviceRegistry.ts
index aed2d2e346e4..875afa12f0b4 100644
--- a/src/client/activation/serviceRegistry.ts
+++ b/src/client/activation/serviceRegistry.ts
@@ -15,7 +15,7 @@ import { LoadLanguageServerExtension } from './common/loadLanguageServerExtensio
import { PartialModeStatusItem } from './partialModeStatus';
import { ILanguageServerWatcher } from '../languageServer/types';
import { LanguageServerWatcher } from '../languageServer/watcher';
-import { LspNotebooksExperiment } from './node/lspNotebooksExperiment';
+import { RequirementsTxtLinkActivator } from './requirementsTxtLinkActivator';
export function registerTypes(serviceManager: IServiceManager): void {
serviceManager.addSingleton(IExtensionActivationService, PartialModeStatusItem);
@@ -35,6 +35,9 @@ export function registerTypes(serviceManager: IServiceManager): void {
serviceManager.addSingleton(ILanguageServerWatcher, LanguageServerWatcher);
serviceManager.addBinding(ILanguageServerWatcher, IExtensionActivationService);
- serviceManager.addSingleton(LspNotebooksExperiment, LspNotebooksExperiment);
- serviceManager.addBinding(LspNotebooksExperiment, IExtensionSingleActivationService);
+
+ serviceManager.addSingleton(
+ IExtensionSingleActivationService,
+ RequirementsTxtLinkActivator,
+ );
}
diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts
index 2a177bb570b8..e3b9b818691a 100644
--- a/src/client/activation/types.ts
+++ b/src/client/activation/types.ts
@@ -6,32 +6,20 @@
import { Event } from 'vscode';
import { LanguageClient, LanguageClientOptions } from 'vscode-languageclient/node';
import type { IDisposable, ILogOutputChannel, Resource } from '../common/types';
+import { StopWatch } from '../common/utils/stopWatch';
import { PythonEnvironment } from '../pythonEnvironments/info';
export const IExtensionActivationManager = Symbol('IExtensionActivationManager');
/**
* Responsible for activation of extension.
- *
- * @export
- * @interface IExtensionActivationManager
- * @extends {IDisposable}
*/
export interface IExtensionActivationManager extends IDisposable {
- /**
- * Method invoked when extension activates (invoked once).
- *
- * @returns {Promise}
- * @memberof IExtensionActivationManager
- */
- activate(): Promise;
+ // Method invoked when extension activates (invoked once).
+ activate(startupStopWatch: StopWatch): Promise;
/**
* Method invoked when a workspace is loaded.
* This is where we place initialization scripts for each workspace.
* (e.g. if we need to run code for each workspace, then this is where that happens).
- *
- * @param {Resource} resource
- * @returns {Promise}
- * @memberof IExtensionActivationManager
*/
activateWorkspace(resource: Resource): Promise;
}
@@ -42,12 +30,10 @@ export const IExtensionActivationService = Symbol('IExtensionActivationService')
* invoked for every workspace folder (in multi-root workspace folders) during the activation of the extension.
* This is a great hook for extension activation code, i.e. you don't need to modify
* the `extension.ts` file to invoke some code when extension gets activated.
- * @export
- * @interface IExtensionActivationService
*/
export interface IExtensionActivationService {
supportedWorkspaceTypes: { untrustedWorkspace: boolean; virtualWorkspace: boolean };
- activate(resource: Resource): Promise;
+ activate(resource: Resource, startupStopWatch?: StopWatch): Promise;
}
export enum LanguageServerType {
@@ -99,8 +85,6 @@ export interface ILanguageServerProxy extends IDisposable {
* Sends a request to LS so as to load other extensions.
* This is used as a plugin loader mechanism.
* Anyone (such as intellicode) wanting to interact with LS, needs to send this request to LS.
- * @param {{}} [args]
- * @memberof ILanguageServerProxy
*/
loadExtension(args?: unknown): void;
}
@@ -109,9 +93,6 @@ export const ILanguageServerOutputChannel = Symbol('ILanguageServerOutputChannel
export interface ILanguageServerOutputChannel {
/**
* Creates output channel if necessary and returns it
- *
- * @type {ILogOutputChannel}
- * @memberof ILanguageServerOutputChannel
*/
readonly channel: ILogOutputChannel;
}
@@ -122,8 +103,6 @@ export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivat
* invoked during the activation of the extension.
* This is a great hook for extension activation code, i.e. you don't need to modify
* the `extension.ts` file to invoke some code when extension gets activated.
- * @export
- * @interface IExtensionSingleActivationService
*/
export interface IExtensionSingleActivationService {
supportedWorkspaceTypes: { untrustedWorkspace: boolean; virtualWorkspace: boolean };
diff --git a/src/client/api.ts b/src/client/api.ts
index 81a5f676cc22..908da4be7103 100644
--- a/src/client/api.ts
+++ b/src/client/api.ts
@@ -12,16 +12,21 @@ import { ILanguageServerOutputChannel } from './activation/types';
import { PythonExtension } from './api/types';
import { isTestExecution, PYTHON_LANGUAGE } from './common/constants';
import { IConfigurationService, Resource } from './common/types';
-import { getDebugpyLauncherArgs, getDebugpyPackagePath } from './debugger/extension/adapter/remoteLaunchers';
+import { getDebugpyLauncherArgs } from './debugger/extension/adapter/remoteLaunchers';
import { IInterpreterService } from './interpreter/contracts';
import { IServiceContainer, IServiceManager } from './ioc/types';
-import { JupyterExtensionIntegration } from './jupyter/jupyterIntegration';
+import {
+ JupyterExtensionIntegration,
+ JupyterExtensionPythonEnvironments,
+ JupyterPythonEnvironmentApi,
+} from './jupyter/jupyterIntegration';
import { traceError } from './logging';
import { IDiscoveryAPI } from './pythonEnvironments/base/locator';
import { buildEnvironmentApi } from './environmentApi';
import { ApiForPylance } from './pylanceApi';
import { getTelemetryReporter } from './telemetry';
import { TensorboardExtensionIntegration } from './tensorBoard/tensorboardIntegration';
+import { getDebugpyPath } from './debugger/pythonDebugger';
export function buildApi(
ready: Promise,
@@ -32,11 +37,18 @@ export function buildApi(
const configurationService = serviceContainer.get(IConfigurationService);
const interpreterService = serviceContainer.get(IInterpreterService);
serviceManager.addSingleton(JupyterExtensionIntegration, JupyterExtensionIntegration);
+ serviceManager.addSingleton(
+ JupyterExtensionPythonEnvironments,
+ JupyterExtensionPythonEnvironments,
+ );
serviceManager.addSingleton(
TensorboardExtensionIntegration,
TensorboardExtensionIntegration,
);
+ const jupyterPythonEnvApi = serviceContainer.get(JupyterExtensionPythonEnvironments);
+ const environments = buildEnvironmentApi(discoveryApi, serviceContainer, jupyterPythonEnvApi);
const jupyterIntegration = serviceContainer.get(JupyterExtensionIntegration);
+ jupyterIntegration.registerEnvApi(environments);
const tensorboardIntegration = serviceContainer.get(
TensorboardExtensionIntegration,
);
@@ -79,7 +91,6 @@ export function buildApi(
* @param {Resource} [resource] A resource for which the setting is asked for.
* * When no resource is provided, the setting scoped to the first workspace folder is returned.
* * If no folder is present, it returns the global setting.
- * @returns {({ execCommand: string[] | undefined })}
*/
getExecutionDetails(
resource?: Resource,
@@ -122,7 +133,7 @@ export function buildApi(
});
},
async getDebuggerPackagePath(): Promise {
- return getDebugpyPackagePath();
+ return getDebugpyPath();
},
},
settings: {
@@ -146,7 +157,7 @@ export function buildApi(
stop: (client: BaseLanguageClient): Promise => client.stop(),
getTelemetryReporter: () => getTelemetryReporter(),
},
- environments: buildEnvironmentApi(discoveryApi, serviceContainer),
+ environments,
};
// In test environment return the DI Container.
diff --git a/src/client/api/types.ts b/src/client/api/types.ts
index 4de554bf5a24..95556aacbd90 100644
--- a/src/client/api/types.ts
+++ b/src/client/api/types.ts
@@ -16,7 +16,7 @@ export interface PythonExtension {
/**
* Generate an array of strings for commands to pass to the Python executable to launch the debugger for remote debugging.
* Users can append another array of strings of what they want to execute along with relevant arguments to Python.
- * E.g `['/Users/..../pythonVSCode/pythonFiles/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
+ * E.g `['/Users/..../pythonVSCode/python_files/lib/python/debugpy', '--listen', 'localhost:57039', '--wait-for-client']`
* @param host
* @param port
* @param waitUntilDebuggerAttaches Defaults to `true`.
@@ -25,7 +25,6 @@ export interface PythonExtension {
/**
* Gets the path to the debugger package used by the extension.
- * @returns {Promise}
*/
getDebuggerPackagePath(): Promise;
};
@@ -228,9 +227,9 @@ export type EnvironmentsChangeEvent = {
export type ActiveEnvironmentPathChangeEvent = EnvironmentPath & {
/**
- * Workspace folder the environment changed for.
+ * Resource the environment changed for.
*/
- readonly resource: WorkspaceFolder | undefined;
+ readonly resource: Resource | undefined;
};
/**
@@ -268,6 +267,7 @@ export type KnownEnvironmentTools =
| 'Venv'
| 'VirtualEnvWrapper'
| 'Pyenv'
+ | 'Hatch'
| 'Unknown';
/**
diff --git a/src/client/application/diagnostics/applicationDiagnostics.ts b/src/client/application/diagnostics/applicationDiagnostics.ts
index 493c6cfece53..90d2ced8d0ae 100644
--- a/src/client/application/diagnostics/applicationDiagnostics.ts
+++ b/src/client/application/diagnostics/applicationDiagnostics.ts
@@ -9,7 +9,7 @@ import { Resource } from '../../common/types';
import { IServiceContainer } from '../../ioc/types';
import { traceLog, traceVerbose } from '../../logging';
import { IApplicationDiagnostics } from '../types';
-import { IDiagnostic, IDiagnosticsService, ISourceMapSupportService } from './types';
+import { IDiagnostic, IDiagnosticsService } from './types';
function log(diagnostics: IDiagnostic[]): void {
diagnostics.forEach((item) => {
@@ -43,9 +43,7 @@ async function runDiagnostics(diagnosticServices: IDiagnosticsService[], resourc
export class ApplicationDiagnostics implements IApplicationDiagnostics {
constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) {}
- public register() {
- this.serviceContainer.get(ISourceMapSupportService).register();
- }
+ public register() {}
public async performPreStartupHealthCheck(resource: Resource): Promise {
// When testing, do not perform health checks, as modal dialogs can be displayed.
diff --git a/src/client/application/diagnostics/base.ts b/src/client/application/diagnostics/base.ts
index 17bb7559ee77..8ce1c3b83184 100644
--- a/src/client/application/diagnostics/base.ts
+++ b/src/client/application/diagnostics/base.ts
@@ -73,11 +73,6 @@ export abstract class BaseDiagnosticsService implements IDiagnosticsService, IDi
/**
* Returns a key used to keep track of whether a diagnostic was handled or not.
* So as to prevent handling/displaying messages multiple times for the same diagnostic.
- *
- * @protected
- * @param {IDiagnostic} diagnostic
- * @returns {string}
- * @memberof BaseDiagnosticsService
*/
protected getDiagnosticsKey(diagnostic: IDiagnostic): string {
if (diagnostic.scope === DiagnosticScope.Global) {
diff --git a/src/client/application/diagnostics/checks/macPythonInterpreter.ts b/src/client/application/diagnostics/checks/macPythonInterpreter.ts
index 19ccc2f8beb9..21d6b34fb7c5 100644
--- a/src/client/application/diagnostics/checks/macPythonInterpreter.ts
+++ b/src/client/application/diagnostics/checks/macPythonInterpreter.ts
@@ -40,7 +40,7 @@ export const InvalidMacPythonInterpreterServiceId = 'InvalidMacPythonInterpreter
export class InvalidMacPythonInterpreterService extends BaseDiagnosticsService {
protected changeThrottleTimeout = 1000;
- private timeOut?: NodeJS.Timer | number;
+ private timeOut?: NodeJS.Timeout | number;
constructor(
@inject(IServiceContainer) serviceContainer: IServiceContainer,
diff --git a/src/client/application/diagnostics/checks/pythonInterpreter.ts b/src/client/application/diagnostics/checks/pythonInterpreter.ts
index 31da53e75357..9167e232a417 100644
--- a/src/client/application/diagnostics/checks/pythonInterpreter.ts
+++ b/src/client/application/diagnostics/checks/pythonInterpreter.ts
@@ -20,7 +20,7 @@ import {
IDiagnosticHandlerService,
IDiagnosticMessageOnCloseHandler,
} from '../types';
-import { Common } from '../../../common/utils/localize';
+import { Common, Interpreters } from '../../../common/utils/localize';
import { Commands } from '../../../common/constants';
import { ICommandManager, IWorkspaceService } from '../../../common/application/types';
import { sendTelemetryEvent } from '../../../telemetry';
@@ -30,11 +30,12 @@ import { cache } from '../../../common/utils/decorators';
import { noop } from '../../../common/utils/misc';
import { getEnvironmentVariable, getOSType, OSType } from '../../../common/utils/platform';
import { IFileSystem } from '../../../common/platform/types';
-import { traceError } from '../../../logging';
+import { traceError, traceWarn } from '../../../logging';
import { getExecutable } from '../../../common/process/internal/python';
import { getSearchPathEnvVarNames } from '../../../common/utils/exec';
import { IProcessServiceFactory } from '../../../common/process/types';
import { normCasePath } from '../../../common/platform/fs-paths';
+import { useEnvExtension } from '../../../envExt/api.internal';
const messages = {
[DiagnosticCodes.NoPythonInterpretersDiagnostic]: l10n.t(
@@ -144,6 +145,9 @@ export class InvalidPythonInterpreterService extends BaseDiagnosticsService
const isInterpreterSetToDefault = interpreterPathService.get(resource) === 'python';
if (!hasInterpreters && isInterpreterSetToDefault) {
+ if (useEnvExtension()) {
+ traceWarn(Interpreters.envExtDiscoveryNoEnvironments);
+ }
return [
new InvalidPythonInterpreterDiagnostic(
DiagnosticCodes.NoPythonInterpretersDiagnostic,
@@ -156,6 +160,9 @@ export class InvalidPythonInterpreterService extends BaseDiagnosticsService
const currentInterpreter = await interpreterService.getActiveInterpreter(resource);
if (!currentInterpreter) {
+ if (useEnvExtension()) {
+ traceWarn(Interpreters.envExtNoActiveEnvironment);
+ }
return [
new InvalidPythonInterpreterDiagnostic(
DiagnosticCodes.InvalidPythonInterpreterDiagnostic,
diff --git a/src/client/application/diagnostics/surceMapSupportService.ts b/src/client/application/diagnostics/surceMapSupportService.ts
deleted file mode 100644
index 8ff491e4cb06..000000000000
--- a/src/client/application/diagnostics/surceMapSupportService.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-'use strict';
-
-import { inject, injectable } from 'inversify';
-import { ConfigurationTarget } from 'vscode';
-import { IApplicationShell, ICommandManager } from '../../common/application/types';
-import { Commands } from '../../common/constants';
-import { IConfigurationService, IDisposableRegistry } from '../../common/types';
-import { Diagnostics } from '../../common/utils/localize';
-import { ISourceMapSupportService } from './types';
-
-@injectable()
-export class SourceMapSupportService implements ISourceMapSupportService {
- constructor(
- @inject(ICommandManager) private readonly commandManager: ICommandManager,
- @inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry,
- @inject(IConfigurationService) private readonly configurationService: IConfigurationService,
- @inject(IApplicationShell) private readonly shell: IApplicationShell,
- ) {}
- public register(): void {
- this.disposables.push(
- this.commandManager.registerCommand(Commands.Enable_SourceMap_Support, this.onEnable, this),
- );
- }
- public async enable(): Promise {
- await this.configurationService.updateSetting(
- 'diagnostics.sourceMapsEnabled',
- true,
- undefined,
- ConfigurationTarget.Global,
- );
- await this.commandManager.executeCommand('workbench.action.reloadWindow');
- }
- protected async onEnable(): Promise {
- const enableSourceMapsAndReloadVSC = Diagnostics.enableSourceMapsAndReloadVSC;
- const selection = await this.shell.showWarningMessage(
- Diagnostics.warnBeforeEnablingSourceMaps,
- enableSourceMapsAndReloadVSC,
- );
- if (selection === enableSourceMapsAndReloadVSC) {
- await this.enable();
- }
- }
-}
diff --git a/src/client/application/diagnostics/types.ts b/src/client/application/diagnostics/types.ts
index ced9930c81ab..1dc9a3c689df 100644
--- a/src/client/application/diagnostics/types.ts
+++ b/src/client/application/diagnostics/types.ts
@@ -64,8 +64,3 @@ export const IInvalidPythonPathInDebuggerService = Symbol('IInvalidPythonPathInD
export interface IInvalidPythonPathInDebuggerService extends IDiagnosticsService {
validatePythonPath(pythonPath?: string, pythonPathSource?: PythonPathSource, resource?: Uri): Promise;
}
-export const ISourceMapSupportService = Symbol('ISourceMapSupportService');
-export interface ISourceMapSupportService {
- register(): void;
- enable(): Promise;
-}
diff --git a/src/client/application/serviceRegistry.ts b/src/client/application/serviceRegistry.ts
index 38773bd20198..ff5376d70b24 100644
--- a/src/client/application/serviceRegistry.ts
+++ b/src/client/application/serviceRegistry.ts
@@ -5,10 +5,7 @@
import { IServiceManager } from '../ioc/types';
import { registerTypes as diagnosticsRegisterTypes } from './diagnostics/serviceRegistry';
-import { SourceMapSupportService } from './diagnostics/surceMapSupportService';
-import { ISourceMapSupportService } from './diagnostics/types';
export function registerTypes(serviceManager: IServiceManager) {
- serviceManager.addSingleton(ISourceMapSupportService, SourceMapSupportService);
diagnosticsRegisterTypes(serviceManager);
}
diff --git a/src/client/application/types.ts b/src/client/application/types.ts
index 460ac39807c8..cfd41f7b9746 100644
--- a/src/client/application/types.ts
+++ b/src/client/application/types.ts
@@ -11,8 +11,6 @@ export interface IApplicationDiagnostics {
/**
* Perform pre-extension activation health checks.
* E.g. validate user environment, etc.
- * @returns {Promise}
- * @memberof IApplicationDiagnostics
*/
performPreStartupHealthCheck(resource: Resource): Promise;
register(): void;
diff --git a/src/client/browser/extension.ts b/src/client/browser/extension.ts
index 28e1912f67e4..132618430551 100644
--- a/src/client/browser/extension.ts
+++ b/src/client/browser/extension.ts
@@ -108,7 +108,7 @@ async function runPylance(
middleware,
};
- const client = new LanguageClient('python', 'Python Language Server', clientOptions, worker);
+ const client = new LanguageClient('python', 'Python Language Server', worker, clientOptions);
languageClient = client;
context.subscriptions.push(
@@ -139,7 +139,7 @@ async function runPylance(
await client.start();
} catch (e) {
- console.log(e);
+ console.log(e); // necessary to use console.log for browser
}
}
@@ -200,7 +200,7 @@ function sendTelemetryEventBrowser(
break;
}
} catch (exception) {
- console.error(`Failed to serialize ${prop} for ${eventName}`, exception);
+ console.error(`Failed to serialize ${prop} for ${eventName}`, exception); // necessary to use console.log for browser
}
});
}
diff --git a/src/client/chat/baseTool.ts b/src/client/chat/baseTool.ts
new file mode 100644
index 000000000000..d8e2e1d60d42
--- /dev/null
+++ b/src/client/chat/baseTool.ts
@@ -0,0 +1,80 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationToken,
+ LanguageModelTextPart,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+ workspace,
+} from 'vscode';
+import { IResourceReference, isCancellationError, resolveFilePath } from './utils';
+import { ErrorWithTelemetrySafeReason } from '../common/errors/errorUtils';
+import { sendTelemetryEvent } from '../telemetry';
+import { EventName } from '../telemetry/constants';
+import { StopWatch } from '../common/utils/stopWatch';
+
+export abstract class BaseTool implements LanguageModelTool {
+ protected extraTelemetryProperties: Record = {};
+ constructor(private readonly toolName: string) {}
+
+ async invoke(
+ options: LanguageModelToolInvocationOptions,
+ token: CancellationToken,
+ ): Promise {
+ if (!workspace.isTrusted) {
+ return new LanguageModelToolResult([
+ new LanguageModelTextPart('Cannot use this tool in an untrusted workspace.'),
+ ]);
+ }
+ this.extraTelemetryProperties = {};
+ let error: Error | undefined;
+ const resource = resolveFilePath(options.input.resourcePath);
+ const stopWatch = new StopWatch();
+ try {
+ return await this.invokeImpl(options, resource, token);
+ } catch (ex) {
+ error = ex as any;
+ throw ex;
+ } finally {
+ const isCancelled = token.isCancellationRequested || (error ? isCancellationError(error) : false);
+ const failed = !!error || isCancelled;
+ const failureCategory = isCancelled
+ ? 'cancelled'
+ : error
+ ? error instanceof ErrorWithTelemetrySafeReason
+ ? error.telemetrySafeReason
+ : 'error'
+ : undefined;
+ sendTelemetryEvent(EventName.INVOKE_TOOL, stopWatch.elapsedTime, {
+ toolName: this.toolName,
+ failed,
+ failureCategory,
+ ...this.extraTelemetryProperties,
+ });
+ }
+ }
+ protected abstract invokeImpl(
+ options: LanguageModelToolInvocationOptions,
+ resource: Uri | undefined,
+ token: CancellationToken,
+ ): Promise;
+
+ async prepareInvocation(
+ options: LanguageModelToolInvocationPrepareOptions,
+ token: CancellationToken,
+ ): Promise {
+ const resource = resolveFilePath(options.input.resourcePath);
+ return this.prepareInvocationImpl(options, resource, token);
+ }
+
+ protected abstract prepareInvocationImpl(
+ options: LanguageModelToolInvocationPrepareOptions,
+ resource: Uri | undefined,
+ token: CancellationToken,
+ ): Promise;
+}
diff --git a/src/client/chat/configurePythonEnvTool.ts b/src/client/chat/configurePythonEnvTool.ts
new file mode 100644
index 000000000000..914a92f81c52
--- /dev/null
+++ b/src/client/chat/configurePythonEnvTool.ts
@@ -0,0 +1,131 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationToken,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+ workspace,
+ lm,
+} from 'vscode';
+import { PythonExtension } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import { ICodeExecutionService } from '../terminals/types';
+import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
+import {
+ getEnvDetailsForResponse,
+ getEnvTypeForTelemetry,
+ getToolResponseIfNotebook,
+ IResourceReference,
+ isCancellationError,
+ raceCancellationError,
+} from './utils';
+import { ITerminalHelper } from '../common/terminal/types';
+import { IRecommendedEnvironmentService } from '../interpreter/configuration/types';
+import { CreateVirtualEnvTool } from './createVirtualEnvTool';
+import { ISelectPythonEnvToolArguments, SelectPythonEnvTool } from './selectEnvTool';
+import { BaseTool } from './baseTool';
+
+export class ConfigurePythonEnvTool extends BaseTool
+ implements LanguageModelTool {
+ private readonly terminalExecutionService: TerminalCodeExecutionProvider;
+ private readonly terminalHelper: ITerminalHelper;
+ private readonly recommendedEnvService: IRecommendedEnvironmentService;
+ public static readonly toolName = 'configure_python_environment';
+ constructor(
+ private readonly api: PythonExtension['environments'],
+ private readonly serviceContainer: IServiceContainer,
+ private readonly createEnvTool: CreateVirtualEnvTool,
+ ) {
+ super(ConfigurePythonEnvTool.toolName);
+ this.terminalExecutionService = this.serviceContainer.get(
+ ICodeExecutionService,
+ 'standard',
+ );
+ this.terminalHelper = this.serviceContainer.get(ITerminalHelper);
+ this.recommendedEnvService = this.serviceContainer.get(
+ IRecommendedEnvironmentService,
+ );
+ }
+
+ async invokeImpl(
+ options: LanguageModelToolInvocationOptions,
+ resource: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ const notebookResponse = getToolResponseIfNotebook(resource);
+ if (notebookResponse) {
+ this.extraTelemetryProperties.resolveOutcome = 'notebook';
+ return notebookResponse;
+ }
+
+ const workspaceSpecificEnv = await raceCancellationError(
+ this.hasAlreadyGotAWorkspaceSpecificEnvironment(resource),
+ token,
+ );
+
+ if (workspaceSpecificEnv) {
+ this.extraTelemetryProperties.resolveOutcome = 'existingWorkspaceEnv';
+ this.extraTelemetryProperties.envType = getEnvTypeForTelemetry(workspaceSpecificEnv);
+ return getEnvDetailsForResponse(
+ workspaceSpecificEnv,
+ this.api,
+ this.terminalExecutionService,
+ this.terminalHelper,
+ resource,
+ token,
+ );
+ }
+
+ if (await this.createEnvTool.shouldCreateNewVirtualEnv(resource, token)) {
+ try {
+ const result = await lm.invokeTool(CreateVirtualEnvTool.toolName, options, token);
+ this.extraTelemetryProperties.resolveOutcome = 'createdVirtualEnv';
+ return result;
+ } catch (ex) {
+ if (isCancellationError(ex)) {
+ const input: ISelectPythonEnvToolArguments = {
+ ...options.input,
+ reason: 'cancelled',
+ };
+ // If the user cancelled the tool, then we should invoke the select env tool.
+ this.extraTelemetryProperties.resolveOutcome = 'selectedEnvAfterCancelledCreate';
+ return lm.invokeTool(SelectPythonEnvTool.toolName, { ...options, input }, token);
+ }
+ throw ex;
+ }
+ } else {
+ const input: ISelectPythonEnvToolArguments = {
+ ...options.input,
+ };
+ this.extraTelemetryProperties.resolveOutcome = 'selectedEnv';
+ return lm.invokeTool(SelectPythonEnvTool.toolName, { ...options, input }, token);
+ }
+ }
+
+ async prepareInvocationImpl(
+ _options: LanguageModelToolInvocationPrepareOptions,
+ _resource: Uri | undefined,
+ _token: CancellationToken,
+ ): Promise {
+ return {
+ invocationMessage: 'Configuring a Python Environment',
+ };
+ }
+
+ async hasAlreadyGotAWorkspaceSpecificEnvironment(resource: Uri | undefined) {
+ const recommededEnv = await this.recommendedEnvService.getRecommededEnvironment(resource);
+ // Already selected workspace env, hence nothing to do.
+ if (recommededEnv?.reason === 'workspaceUserSelected' && workspace.workspaceFolders?.length) {
+ return recommededEnv.environment;
+ }
+ // No workspace folders, and the user selected a global environment.
+ if (recommededEnv?.reason === 'globalUserSelected' && !workspace.workspaceFolders?.length) {
+ return recommededEnv.environment;
+ }
+ }
+}
diff --git a/src/client/chat/createVirtualEnvTool.ts b/src/client/chat/createVirtualEnvTool.ts
new file mode 100644
index 000000000000..56760d2b4bef
--- /dev/null
+++ b/src/client/chat/createVirtualEnvTool.ts
@@ -0,0 +1,246 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationError,
+ CancellationToken,
+ commands,
+ l10n,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+ workspace,
+} from 'vscode';
+import { PythonExtension, ResolvedEnvironment } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import { ICodeExecutionService } from '../terminals/types';
+import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
+import {
+ doesWorkspaceHaveVenvOrCondaEnv,
+ getDisplayVersion,
+ getEnvDetailsForResponse,
+ IResourceReference,
+ isCancellationError,
+ raceCancellationError,
+} from './utils';
+import { ITerminalHelper } from '../common/terminal/types';
+import { raceTimeout, sleep } from '../common/utils/async';
+import { IInterpreterPathService } from '../common/types';
+import { DisposableStore } from '../common/utils/resourceLifecycle';
+import { IRecommendedEnvironmentService } from '../interpreter/configuration/types';
+import { EnvironmentType } from '../pythonEnvironments/info';
+import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
+import { convertEnvInfoToPythonEnvironment } from '../pythonEnvironments/legacyIOC';
+import { sortInterpreters } from '../interpreter/helpers';
+import { isStableVersion } from '../pythonEnvironments/info/pythonVersion';
+import { createVirtualEnvironment } from '../pythonEnvironments/creation/createEnvApi';
+import { traceError, traceVerbose, traceWarn } from '../logging';
+import { StopWatch } from '../common/utils/stopWatch';
+import { useEnvExtension } from '../envExt/api.internal';
+import { PythonEnvironment } from '../envExt/types';
+import { hideEnvCreation } from '../pythonEnvironments/creation/provider/hideEnvCreation';
+import { BaseTool } from './baseTool';
+
+interface ICreateVirtualEnvToolParams extends IResourceReference {
+ packageList?: string[]; // Added only becausewe have ability to create a virtual env with list of packages same tool within the in Python Env extension.
+}
+
+export class CreateVirtualEnvTool extends BaseTool
+ implements LanguageModelTool {
+ private readonly terminalExecutionService: TerminalCodeExecutionProvider;
+ private readonly terminalHelper: ITerminalHelper;
+ private readonly recommendedEnvService: IRecommendedEnvironmentService;
+
+ public static readonly toolName = 'create_virtual_environment';
+ constructor(
+ private readonly discoveryApi: IDiscoveryAPI,
+ private readonly api: PythonExtension['environments'],
+ private readonly serviceContainer: IServiceContainer,
+ ) {
+ super(CreateVirtualEnvTool.toolName);
+ this.terminalExecutionService = this.serviceContainer.get(
+ ICodeExecutionService,
+ 'standard',
+ );
+ this.terminalHelper = this.serviceContainer.get(ITerminalHelper);
+ this.recommendedEnvService = this.serviceContainer.get(
+ IRecommendedEnvironmentService,
+ );
+ }
+
+ async invokeImpl(
+ options: LanguageModelToolInvocationOptions,
+ resource: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ let info = await this.getPreferredEnvForCreation(resource);
+ if (!info) {
+ traceWarn(`Called ${CreateVirtualEnvTool.toolName} tool not invoked, no preferred environment found.`);
+ throw new CancellationError();
+ }
+ const { workspaceFolder, preferredGlobalPythonEnv } = info;
+ const interpreterPathService = this.serviceContainer.get(IInterpreterPathService);
+ const disposables = new DisposableStore();
+ try {
+ disposables.add(hideEnvCreation());
+ const interpreterChanged = new Promise((resolve) => {
+ disposables.add(interpreterPathService.onDidChange(() => resolve()));
+ });
+
+ let createdEnvPath: string | undefined = undefined;
+ if (useEnvExtension()) {
+ const result: PythonEnvironment | undefined = await commands.executeCommand('python-envs.createAny', {
+ quickCreate: true,
+ additionalPackages: options.input.packageList || [],
+ uri: workspaceFolder.uri,
+ selectEnvironment: true,
+ });
+ createdEnvPath = result?.environmentPath.fsPath;
+ } else {
+ const created = await raceCancellationError(
+ createVirtualEnvironment({
+ interpreter: preferredGlobalPythonEnv.id,
+ workspaceFolder,
+ }),
+ token,
+ );
+ createdEnvPath = created?.path;
+ }
+ if (!createdEnvPath) {
+ traceWarn(`${CreateVirtualEnvTool.toolName} tool not invoked, virtual env not created.`);
+ throw new CancellationError();
+ }
+
+ // Wait a few secs to ensure the env is selected as the active environment..
+ // If this doesn't work, then something went wrong.
+ await raceTimeout(5_000, interpreterChanged);
+
+ const stopWatch = new StopWatch();
+ let env: ResolvedEnvironment | undefined;
+ while (stopWatch.elapsedTime < 5_000 || !env) {
+ env = await this.api.resolveEnvironment(createdEnvPath);
+ if (env) {
+ break;
+ } else {
+ traceVerbose(
+ `${CreateVirtualEnvTool.toolName} tool invoked, env created but not yet resolved, waiting...`,
+ );
+ await sleep(200);
+ }
+ }
+ if (!env) {
+ traceError(`${CreateVirtualEnvTool.toolName} tool invoked, env created but unable to resolve details.`);
+ throw new CancellationError();
+ }
+ return await getEnvDetailsForResponse(
+ env,
+ this.api,
+ this.terminalExecutionService,
+ this.terminalHelper,
+ resource,
+ token,
+ );
+ } catch (ex) {
+ if (!isCancellationError(ex)) {
+ traceError(
+ `${
+ CreateVirtualEnvTool.toolName
+ } tool failed to create virtual environment for resource ${resource?.toString()}`,
+ ex,
+ );
+ }
+ throw ex;
+ } finally {
+ disposables.dispose();
+ }
+ }
+
+ public async shouldCreateNewVirtualEnv(resource: Uri | undefined, token: CancellationToken): Promise {
+ if (doesWorkspaceHaveVenvOrCondaEnv(resource, this.api)) {
+ // If we already have a .venv or .conda in this workspace, then do not prompt to create a virtual environment.
+ return false;
+ }
+
+ const info = await raceCancellationError(this.getPreferredEnvForCreation(resource), token);
+ return info ? true : false;
+ }
+
+ async prepareInvocationImpl(
+ _options: LanguageModelToolInvocationPrepareOptions,
+ resource: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ const info = await raceCancellationError(this.getPreferredEnvForCreation(resource), token);
+ if (!info) {
+ return {};
+ }
+ const { preferredGlobalPythonEnv } = info;
+ const version = getDisplayVersion(preferredGlobalPythonEnv.version);
+ return {
+ confirmationMessages: {
+ title: l10n.t('Create a Virtual Environment{0}?', version ? ` (${version})` : ''),
+ message: l10n.t(`Virtual Environments provide the benefit of package isolation and more.`),
+ },
+ invocationMessage: l10n.t('Creating a Virtual Environment'),
+ };
+ }
+ async hasAlreadyGotAWorkspaceSpecificEnvironment(resource: Uri | undefined) {
+ const recommededEnv = await this.recommendedEnvService.getRecommededEnvironment(resource);
+ // Already selected workspace env, hence nothing to do.
+ if (recommededEnv?.reason === 'workspaceUserSelected' && workspace.workspaceFolders?.length) {
+ return recommededEnv.environment;
+ }
+ // No workspace folders, and the user selected a global environment.
+ if (recommededEnv?.reason === 'globalUserSelected' && !workspace.workspaceFolders?.length) {
+ return recommededEnv.environment;
+ }
+ }
+
+ private async getPreferredEnvForCreation(resource: Uri | undefined) {
+ if (await this.hasAlreadyGotAWorkspaceSpecificEnvironment(resource)) {
+ return undefined;
+ }
+
+ // If we have a resource or have only one workspace folder && there is no .venv and no workspace specific environment.
+ // Then lets recommend creating a virtual environment.
+ const workspaceFolder =
+ resource && workspace.workspaceFolders?.length
+ ? workspace.getWorkspaceFolder(resource)
+ : workspace.workspaceFolders?.length === 1
+ ? workspace.workspaceFolders[0]
+ : undefined;
+ if (!workspaceFolder) {
+ // No workspace folder, hence no need to create a virtual environment.
+ return undefined;
+ }
+
+ // Find the latest stable version of Python from the list of know envs.
+ let globalPythonEnvs = this.discoveryApi
+ .getEnvs()
+ .map((env) => convertEnvInfoToPythonEnvironment(env))
+ .filter((env) =>
+ [
+ EnvironmentType.System,
+ EnvironmentType.MicrosoftStore,
+ EnvironmentType.Global,
+ EnvironmentType.Pyenv,
+ ].includes(env.envType),
+ )
+ .filter((env) => env.version && isStableVersion(env.version));
+
+ globalPythonEnvs = sortInterpreters(globalPythonEnvs);
+ const preferredGlobalPythonEnv = globalPythonEnvs.length
+ ? this.api.known.find((e) => e.id === globalPythonEnvs[globalPythonEnvs.length - 1].id)
+ : undefined;
+
+ return workspaceFolder && preferredGlobalPythonEnv
+ ? {
+ workspaceFolder,
+ preferredGlobalPythonEnv,
+ }
+ : undefined;
+ }
+}
diff --git a/src/client/chat/getExecutableTool.ts b/src/client/chat/getExecutableTool.ts
new file mode 100644
index 000000000000..38dabce644a7
--- /dev/null
+++ b/src/client/chat/getExecutableTool.ts
@@ -0,0 +1,90 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationToken,
+ l10n,
+ LanguageModelTextPart,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+} from 'vscode';
+import { PythonExtension } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import { ICodeExecutionService } from '../terminals/types';
+import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
+import {
+ getEnvDisplayName,
+ getEnvironmentDetails,
+ getEnvTypeForTelemetry,
+ getToolResponseIfNotebook,
+ IResourceReference,
+ raceCancellationError,
+} from './utils';
+import { ITerminalHelper } from '../common/terminal/types';
+import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
+import { BaseTool } from './baseTool';
+
+export class GetExecutableTool extends BaseTool implements LanguageModelTool {
+ private readonly terminalExecutionService: TerminalCodeExecutionProvider;
+ private readonly terminalHelper: ITerminalHelper;
+ public static readonly toolName = 'get_python_executable_details';
+ constructor(
+ private readonly api: PythonExtension['environments'],
+ private readonly serviceContainer: IServiceContainer,
+ private readonly discovery: IDiscoveryAPI,
+ ) {
+ super(GetExecutableTool.toolName);
+ this.terminalExecutionService = this.serviceContainer.get(
+ ICodeExecutionService,
+ 'standard',
+ );
+ this.terminalHelper = this.serviceContainer.get(ITerminalHelper);
+ }
+ async invokeImpl(
+ _options: LanguageModelToolInvocationOptions,
+ resourcePath: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ const notebookResponse = getToolResponseIfNotebook(resourcePath);
+ if (notebookResponse) {
+ return notebookResponse;
+ }
+
+ const envPath = this.api.getActiveEnvironmentPath(resourcePath);
+ const environment = await raceCancellationError(this.api.resolveEnvironment(envPath), token);
+ if (environment) {
+ this.extraTelemetryProperties.envType = getEnvTypeForTelemetry(environment);
+ }
+
+ const message = await getEnvironmentDetails(
+ resourcePath,
+ this.api,
+ this.terminalExecutionService,
+ this.terminalHelper,
+ undefined,
+ token,
+ );
+ return new LanguageModelToolResult([new LanguageModelTextPart(message)]);
+ }
+
+ async prepareInvocationImpl(
+ _options: LanguageModelToolInvocationPrepareOptions,
+ resourcePath: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ if (getToolResponseIfNotebook(resourcePath)) {
+ return {};
+ }
+
+ const envName = await raceCancellationError(getEnvDisplayName(this.discovery, resourcePath, this.api), token);
+ return {
+ invocationMessage: envName
+ ? l10n.t('Fetching Python executable information for {0}', envName)
+ : l10n.t('Fetching Python executable information'),
+ };
+ }
+}
diff --git a/src/client/chat/getPythonEnvTool.ts b/src/client/chat/getPythonEnvTool.ts
new file mode 100644
index 000000000000..d25d72baeba8
--- /dev/null
+++ b/src/client/chat/getPythonEnvTool.ts
@@ -0,0 +1,131 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationToken,
+ l10n,
+ LanguageModelTextPart,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+} from 'vscode';
+import { PythonExtension } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import { ICodeExecutionService } from '../terminals/types';
+import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
+import { IProcessServiceFactory, IPythonExecutionFactory } from '../common/process/types';
+import {
+ getEnvironmentDetails,
+ getEnvTypeForTelemetry,
+ getToolResponseIfNotebook,
+ IResourceReference,
+ raceCancellationError,
+} from './utils';
+import { getPythonPackagesResponse } from './listPackagesTool';
+import { ITerminalHelper } from '../common/terminal/types';
+import { getEnvExtApi, useEnvExtension } from '../envExt/api.internal';
+import { ErrorWithTelemetrySafeReason } from '../common/errors/errorUtils';
+import { BaseTool } from './baseTool';
+
+export class GetEnvironmentInfoTool extends BaseTool
+ implements LanguageModelTool {
+ private readonly terminalExecutionService: TerminalCodeExecutionProvider;
+ private readonly pythonExecFactory: IPythonExecutionFactory;
+ private readonly processServiceFactory: IProcessServiceFactory;
+ private readonly terminalHelper: ITerminalHelper;
+ public static readonly toolName = 'get_python_environment_details';
+ constructor(
+ private readonly api: PythonExtension['environments'],
+ private readonly serviceContainer: IServiceContainer,
+ ) {
+ super(GetEnvironmentInfoTool.toolName);
+ this.terminalExecutionService = this.serviceContainer.get(
+ ICodeExecutionService,
+ 'standard',
+ );
+ this.pythonExecFactory = this.serviceContainer.get(IPythonExecutionFactory);
+ this.processServiceFactory = this.serviceContainer.get(IProcessServiceFactory);
+ this.terminalHelper = this.serviceContainer.get(ITerminalHelper);
+ }
+
+ async invokeImpl(
+ _options: LanguageModelToolInvocationOptions,
+ resourcePath: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ const notebookResponse = getToolResponseIfNotebook(resourcePath);
+ if (notebookResponse) {
+ return notebookResponse;
+ }
+
+ // environment
+ const envPath = this.api.getActiveEnvironmentPath(resourcePath);
+ const environment = await raceCancellationError(this.api.resolveEnvironment(envPath), token);
+ if (!environment || !environment.version) {
+ throw new ErrorWithTelemetrySafeReason(
+ 'No environment found for the provided resource path: ' + resourcePath?.fsPath,
+ 'noEnvFound',
+ );
+ }
+ this.extraTelemetryProperties.envType = getEnvTypeForTelemetry(environment);
+
+ let packages = '';
+ let responsePackageCount = 0;
+ if (useEnvExtension()) {
+ const api = await getEnvExtApi();
+ const env = await api.getEnvironment(resourcePath);
+ const pkgs = env ? await api.getPackages(env) : [];
+ if (pkgs && pkgs.length > 0) {
+ responsePackageCount = pkgs.length;
+ // Installed Python packages, each in the format or (). The version may be omitted if unknown. Returns an empty array if no packages are installed.
+ const response = [
+ 'Below is a list of the Python packages, each in the format or (). The version may be omitted if unknown: ',
+ ];
+ pkgs.forEach((pkg) => {
+ const version = pkg.version;
+ response.push(version ? `- ${pkg.name} (${version})` : `- ${pkg.name}`);
+ });
+ packages = response.join('\n');
+ }
+ }
+ if (!packages) {
+ packages = await getPythonPackagesResponse(
+ environment,
+ this.pythonExecFactory,
+ this.processServiceFactory,
+ resourcePath,
+ token,
+ );
+ // Count lines starting with '- ' to get the number of packages
+ responsePackageCount = (packages.match(/^- /gm) || []).length;
+ }
+ this.extraTelemetryProperties.responsePackageCount = String(responsePackageCount);
+ const message = await getEnvironmentDetails(
+ resourcePath,
+ this.api,
+ this.terminalExecutionService,
+ this.terminalHelper,
+ packages,
+ token,
+ );
+
+ return new LanguageModelToolResult([new LanguageModelTextPart(message)]);
+ }
+
+ async prepareInvocationImpl(
+ _options: LanguageModelToolInvocationPrepareOptions,
+ resourcePath: Uri | undefined,
+ _token: CancellationToken,
+ ): Promise {
+ if (getToolResponseIfNotebook(resourcePath)) {
+ return {};
+ }
+
+ return {
+ invocationMessage: l10n.t('Fetching Python environment information'),
+ };
+ }
+}
diff --git a/src/client/chat/index.ts b/src/client/chat/index.ts
new file mode 100644
index 000000000000..b548860eaae3
--- /dev/null
+++ b/src/client/chat/index.ts
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { lm } from 'vscode';
+import { PythonExtension } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import { InstallPackagesTool } from './installPackagesTool';
+import { IExtensionContext } from '../common/types';
+import { DisposableStore } from '../common/utils/resourceLifecycle';
+import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
+import { GetExecutableTool } from './getExecutableTool';
+import { GetEnvironmentInfoTool } from './getPythonEnvTool';
+import { ConfigurePythonEnvTool } from './configurePythonEnvTool';
+import { SelectPythonEnvTool } from './selectEnvTool';
+import { CreateVirtualEnvTool } from './createVirtualEnvTool';
+
+export function registerTools(
+ context: IExtensionContext,
+ discoverApi: IDiscoveryAPI,
+ environmentsApi: PythonExtension['environments'],
+ serviceContainer: IServiceContainer,
+) {
+ const ourTools = new DisposableStore();
+ context.subscriptions.push(ourTools);
+
+ ourTools.add(
+ lm.registerTool(GetEnvironmentInfoTool.toolName, new GetEnvironmentInfoTool(environmentsApi, serviceContainer)),
+ );
+ ourTools.add(
+ lm.registerTool(
+ GetExecutableTool.toolName,
+ new GetExecutableTool(environmentsApi, serviceContainer, discoverApi),
+ ),
+ );
+ ourTools.add(
+ lm.registerTool(
+ InstallPackagesTool.toolName,
+ new InstallPackagesTool(environmentsApi, serviceContainer, discoverApi),
+ ),
+ );
+ const createVirtualEnvTool = new CreateVirtualEnvTool(discoverApi, environmentsApi, serviceContainer);
+ ourTools.add(lm.registerTool(CreateVirtualEnvTool.toolName, createVirtualEnvTool));
+ ourTools.add(
+ lm.registerTool(SelectPythonEnvTool.toolName, new SelectPythonEnvTool(environmentsApi, serviceContainer)),
+ );
+ ourTools.add(
+ lm.registerTool(
+ ConfigurePythonEnvTool.toolName,
+ new ConfigurePythonEnvTool(environmentsApi, serviceContainer, createVirtualEnvTool),
+ ),
+ );
+}
diff --git a/src/client/chat/installPackagesTool.ts b/src/client/chat/installPackagesTool.ts
new file mode 100644
index 000000000000..5d3d456361f9
--- /dev/null
+++ b/src/client/chat/installPackagesTool.ts
@@ -0,0 +1,167 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationToken,
+ l10n,
+ LanguageModelTextPart,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+} from 'vscode';
+import { PythonExtension } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import {
+ getEnvDisplayName,
+ getEnvTypeForTelemetry,
+ getToolResponseIfNotebook,
+ IResourceReference,
+ isCancellationError,
+ isCondaEnv,
+ raceCancellationError,
+} from './utils';
+import { IModuleInstaller } from '../common/installer/types';
+import { ModuleInstallerType } from '../pythonEnvironments/info';
+import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
+import { getEnvExtApi, useEnvExtension } from '../envExt/api.internal';
+import { ErrorWithTelemetrySafeReason } from '../common/errors/errorUtils';
+import { BaseTool } from './baseTool';
+
+export interface IInstallPackageArgs extends IResourceReference {
+ packageList: string[];
+}
+
+export class InstallPackagesTool extends BaseTool
+ implements LanguageModelTool {
+ public static readonly toolName = 'install_python_packages';
+ constructor(
+ private readonly api: PythonExtension['environments'],
+ private readonly serviceContainer: IServiceContainer,
+ private readonly discovery: IDiscoveryAPI,
+ ) {
+ super(InstallPackagesTool.toolName);
+ }
+
+ async invokeImpl(
+ options: LanguageModelToolInvocationOptions,
+ resourcePath: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ const packageCount = options.input.packageList.length;
+ const packagePlurality = packageCount === 1 ? 'package' : 'packages';
+ this.extraTelemetryProperties.packageCount = String(packageCount);
+ const notebookResponse = getToolResponseIfNotebook(resourcePath);
+ if (notebookResponse) {
+ return notebookResponse;
+ }
+
+ if (useEnvExtension()) {
+ const api = await getEnvExtApi();
+ const env = await api.getEnvironment(resourcePath);
+ if (env) {
+ await raceCancellationError(api.managePackages(env, { install: options.input.packageList }), token);
+ const resultMessage = `Successfully installed ${packagePlurality}: ${options.input.packageList.join(
+ ', ',
+ )}`;
+ return new LanguageModelToolResult([new LanguageModelTextPart(resultMessage)]);
+ } else {
+ return new LanguageModelToolResult([
+ new LanguageModelTextPart(
+ `Packages not installed. No environment found for: ${resourcePath?.fsPath}`,
+ ),
+ ]);
+ }
+ }
+
+ try {
+ // environment
+ const envPath = this.api.getActiveEnvironmentPath(resourcePath);
+ const environment = await raceCancellationError(this.api.resolveEnvironment(envPath), token);
+ if (!environment || !environment.version) {
+ throw new ErrorWithTelemetrySafeReason(
+ 'No environment found for the provided resource path: ' + resourcePath?.fsPath,
+ 'noEnvFound',
+ );
+ }
+ this.extraTelemetryProperties.envType = getEnvTypeForTelemetry(environment);
+ const isConda = isCondaEnv(environment);
+ const installers = this.serviceContainer.getAll(IModuleInstaller);
+ const installerType = isConda ? ModuleInstallerType.Conda : ModuleInstallerType.Pip;
+ this.extraTelemetryProperties.installerType = isConda ? 'conda' : 'pip';
+ const installer = installers.find((i) => i.type === installerType);
+ if (!installer) {
+ throw new ErrorWithTelemetrySafeReason(
+ `No installer found for the environment type: ${installerType}`,
+ 'noInstallerFound',
+ );
+ }
+ if (!installer.isSupported(resourcePath)) {
+ throw new ErrorWithTelemetrySafeReason(
+ `Installer ${installerType} not supported for the environment type: ${installerType}`,
+ 'installerNotSupported',
+ );
+ }
+ for (const packageName of options.input.packageList) {
+ await installer.installModule(packageName, resourcePath, token, undefined, {
+ installAsProcess: true,
+ hideProgress: true,
+ });
+ }
+ // format and return
+ const resultMessage = `Successfully installed ${packagePlurality}: ${options.input.packageList.join(', ')}`;
+ return new LanguageModelToolResult([new LanguageModelTextPart(resultMessage)]);
+ } catch (error) {
+ if (isCancellationError(error)) {
+ throw error;
+ }
+ const errorMessage = `An error occurred while installing ${packagePlurality}: ${error}`;
+ return new LanguageModelToolResult([new LanguageModelTextPart(errorMessage)]);
+ }
+ }
+
+ async prepareInvocationImpl(
+ options: LanguageModelToolInvocationPrepareOptions,
+ resourcePath: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ const packageCount = options.input.packageList.length;
+ if (getToolResponseIfNotebook(resourcePath)) {
+ return {};
+ }
+
+ const envName = await raceCancellationError(getEnvDisplayName(this.discovery, resourcePath, this.api), token);
+ let title = '';
+ let invocationMessage = '';
+ const message =
+ packageCount === 1
+ ? ''
+ : l10n.t(`The following packages will be installed: {0}`, options.input.packageList.sort().join(', '));
+ if (envName) {
+ title =
+ packageCount === 1
+ ? l10n.t(`Install {0} in {1}?`, options.input.packageList[0], envName)
+ : l10n.t(`Install packages in {0}?`, envName);
+ invocationMessage =
+ packageCount === 1
+ ? l10n.t(`Installing {0} in {1}`, options.input.packageList[0], envName)
+ : l10n.t(`Installing packages {0} in {1}`, options.input.packageList.sort().join(', '), envName);
+ } else {
+ title =
+ options.input.packageList.length === 1
+ ? l10n.t(`Install Python package '{0}'?`, options.input.packageList[0])
+ : l10n.t(`Install Python packages?`);
+ invocationMessage =
+ packageCount === 1
+ ? l10n.t(`Installing Python package '{0}'`, options.input.packageList[0])
+ : l10n.t(`Installing Python packages: {0}`, options.input.packageList.sort().join(', '));
+ }
+
+ return {
+ confirmationMessages: { title, message },
+ invocationMessage,
+ };
+ }
+}
diff --git a/src/client/chat/listPackagesTool.ts b/src/client/chat/listPackagesTool.ts
new file mode 100644
index 000000000000..fcae831cfe2f
--- /dev/null
+++ b/src/client/chat/listPackagesTool.ts
@@ -0,0 +1,95 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { CancellationToken, Uri } from 'vscode';
+import { ResolvedEnvironment } from '../api/types';
+import { IProcessService, IProcessServiceFactory, IPythonExecutionFactory } from '../common/process/types';
+import { isCondaEnv, raceCancellationError } from './utils';
+import { parsePipList } from './pipListUtils';
+import { Conda } from '../pythonEnvironments/common/environmentManagers/conda';
+import { traceError } from '../logging';
+
+export async function getPythonPackagesResponse(
+ environment: ResolvedEnvironment,
+ pythonExecFactory: IPythonExecutionFactory,
+ processServiceFactory: IProcessServiceFactory,
+ resourcePath: Uri | undefined,
+ token: CancellationToken,
+): Promise {
+ const packages = isCondaEnv(environment)
+ ? await raceCancellationError(
+ listCondaPackages(
+ pythonExecFactory,
+ environment,
+ resourcePath,
+ await raceCancellationError(processServiceFactory.create(resourcePath), token),
+ ),
+ token,
+ )
+ : await raceCancellationError(listPipPackages(pythonExecFactory, resourcePath), token);
+
+ if (!packages.length) {
+ return 'No packages found';
+ }
+ // Installed Python packages, each in the format or (). The version may be omitted if unknown. Returns an empty array if no packages are installed.
+ const response = [
+ 'Below is a list of the Python packages, each in the format or (). The version may be omitted if unknown: ',
+ ];
+ packages.forEach((pkg) => {
+ const [name, version] = pkg;
+ response.push(version ? `- ${name} (${version})` : `- ${name}`);
+ });
+ return response.join('\n');
+}
+
+async function listPipPackages(
+ execFactory: IPythonExecutionFactory,
+ resource: Uri | undefined,
+): Promise<[string, string][]> {
+ // Add option --format to subcommand list of pip cache, with abspath choice to output the full path of a wheel file. (#8355)
+ // Added in 2020. Thats almost 5 years ago. When Python 3.8 was released.
+ const exec = await execFactory.createActivatedEnvironment({ allowEnvironmentFetchExceptions: true, resource });
+ const output = await exec.execModule('pip', ['list'], { throwOnStdErr: false, encoding: 'utf8' });
+ return parsePipList(output.stdout).map((pkg) => [pkg.name, pkg.version]);
+}
+
+async function listCondaPackages(
+ execFactory: IPythonExecutionFactory,
+ env: ResolvedEnvironment,
+ resource: Uri | undefined,
+ processService: IProcessService,
+): Promise<[string, string][]> {
+ const conda = await Conda.getConda();
+ if (!conda) {
+ traceError('Conda is not installed, falling back to pip packages');
+ return listPipPackages(execFactory, resource);
+ }
+ if (!env.executable.uri) {
+ traceError('Conda environment executable not found, falling back to pip packages');
+ return listPipPackages(execFactory, resource);
+ }
+ const condaEnv = await conda.getCondaEnvironment(env.executable.uri.fsPath);
+ if (!condaEnv) {
+ traceError('Conda environment not found, falling back to pip packages');
+ return listPipPackages(execFactory, resource);
+ }
+ const cmd = await conda.getListPythonPackagesArgs(condaEnv, true);
+ if (!cmd) {
+ traceError('Conda list command not found, falling back to pip packages');
+ return listPipPackages(execFactory, resource);
+ }
+ const output = await processService.exec(cmd[0], cmd.slice(1), { shell: true });
+ if (!output.stdout) {
+ traceError('Unable to get conda packages, falling back to pip packages');
+ return listPipPackages(execFactory, resource);
+ }
+ const content = output.stdout.split(/\r?\n/).filter((l) => !l.startsWith('#'));
+ const packages: [string, string][] = [];
+ content.forEach((l) => {
+ const parts = l.split(' ').filter((p) => p.length > 0);
+ if (parts.length >= 3) {
+ packages.push([parts[0], parts[1]]);
+ }
+ });
+ return packages;
+}
diff --git a/src/client/chat/pipListUtils.ts b/src/client/chat/pipListUtils.ts
new file mode 100644
index 000000000000..0112d88c53ab
--- /dev/null
+++ b/src/client/chat/pipListUtils.ts
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+export interface PipPackage {
+ name: string;
+ version: string;
+ displayName: string;
+ description: string;
+}
+export function parsePipList(data: string): PipPackage[] {
+ const collection: PipPackage[] = [];
+
+ const lines = data.split('\n').splice(2);
+ for (let line of lines) {
+ if (line.trim() === '' || line.startsWith('Package') || line.startsWith('----') || line.startsWith('[')) {
+ continue;
+ }
+ const parts = line.split(' ').filter((e) => e);
+ if (parts.length > 1) {
+ const name = parts[0].trim();
+ const version = parts[1].trim();
+ const pkg = {
+ name,
+ version,
+ displayName: name,
+ description: version,
+ };
+ collection.push(pkg);
+ }
+ }
+ return collection;
+}
diff --git a/src/client/chat/selectEnvTool.ts b/src/client/chat/selectEnvTool.ts
new file mode 100644
index 000000000000..9eeebdfc1b56
--- /dev/null
+++ b/src/client/chat/selectEnvTool.ts
@@ -0,0 +1,218 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationToken,
+ l10n,
+ LanguageModelTextPart,
+ LanguageModelTool,
+ LanguageModelToolInvocationOptions,
+ LanguageModelToolInvocationPrepareOptions,
+ LanguageModelToolResult,
+ PreparedToolInvocation,
+ Uri,
+ workspace,
+ commands,
+ QuickPickItem,
+ QuickPickItemKind,
+} from 'vscode';
+import { PythonExtension } from '../api/types';
+import { IServiceContainer } from '../ioc/types';
+import { ICodeExecutionService } from '../terminals/types';
+import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
+import {
+ doesWorkspaceHaveVenvOrCondaEnv,
+ getEnvDetailsForResponse,
+ getToolResponseIfNotebook,
+ IResourceReference,
+} from './utils';
+import { ITerminalHelper } from '../common/terminal/types';
+import { raceTimeout } from '../common/utils/async';
+import { Commands, Octicons } from '../common/constants';
+import { CreateEnvironmentResult } from '../pythonEnvironments/creation/proposed.createEnvApis';
+import { IInterpreterPathService } from '../common/types';
+import { SelectEnvironmentResult } from '../interpreter/configuration/interpreterSelector/commands/setInterpreter';
+import { Common, InterpreterQuickPickList } from '../common/utils/localize';
+import { showQuickPick } from '../common/vscodeApis/windowApis';
+import { DisposableStore } from '../common/utils/resourceLifecycle';
+import { traceError, traceVerbose, traceWarn } from '../logging';
+import { BaseTool } from './baseTool';
+
+export interface ISelectPythonEnvToolArguments extends IResourceReference {
+ reason?: 'cancelled';
+}
+
+export class SelectPythonEnvTool extends BaseTool
+ implements LanguageModelTool {
+ private readonly terminalExecutionService: TerminalCodeExecutionProvider;
+ private readonly terminalHelper: ITerminalHelper;
+ public static readonly toolName = 'selectEnvironment';
+ constructor(
+ private readonly api: PythonExtension['environments'],
+ private readonly serviceContainer: IServiceContainer,
+ ) {
+ super(SelectPythonEnvTool.toolName);
+ this.terminalExecutionService = this.serviceContainer.get(
+ ICodeExecutionService,
+ 'standard',
+ );
+ this.terminalHelper = this.serviceContainer.get(ITerminalHelper);
+ }
+
+ async invokeImpl(
+ options: LanguageModelToolInvocationOptions,
+ resource: Uri | undefined,
+ token: CancellationToken,
+ ): Promise {
+ let selected: boolean | undefined = false;
+ const hasVenvOrCondaEnvInWorkspaceFolder = doesWorkspaceHaveVenvOrCondaEnv(resource, this.api);
+ if (options.input.reason === 'cancelled' || hasVenvOrCondaEnvInWorkspaceFolder) {
+ const result = (await Promise.resolve(
+ commands.executeCommand(Commands.Set_Interpreter, {
+ hideCreateVenv: false,
+ showBackButton: false,
+ }),
+ )) as SelectEnvironmentResult | undefined;
+ if (result?.path) {
+ traceVerbose(`User selected a Python environment ${result.path} in Select Python Tool.`);
+ selected = true;
+ } else {
+ traceWarn(`User did not select a Python environment in Select Python Tool.`);
+ }
+ } else {
+ selected = await showCreateAndSelectEnvironmentQuickPick(resource, this.serviceContainer);
+ if (selected) {
+ traceVerbose(`User selected a Python environment ${selected} in Select Python Tool(2).`);
+ } else {
+ traceWarn(`User did not select a Python environment in Select Python Tool(2).`);
+ }
+ }
+ const env = selected
+ ? await this.api.resolveEnvironment(this.api.getActiveEnvironmentPath(resource))
+ : undefined;
+ if (selected && !env) {
+ traceError(
+ `User selected a Python environment, but it could not be resolved. This is unexpected. Environment: ${this.api.getActiveEnvironmentPath(
+ resource,
+ )}`,
+ );
+ }
+ if (selected && env) {
+ return await getEnvDetailsForResponse(
+ env,
+ this.api,
+ this.terminalExecutionService,
+ this.terminalHelper,
+ resource,
+ token,
+ );
+ }
+ return new LanguageModelToolResult([
+ new LanguageModelTextPart('User did not create nor select a Python environment.'),
+ ]);
+ }
+
+ async prepareInvocationImpl(
+ options: LanguageModelToolInvocationPrepareOptions,
+ resource: Uri | undefined,
+ _token: CancellationToken,
+ ): Promise {
+ if (getToolResponseIfNotebook(resource)) {
+ return {};
+ }
+ const hasVenvOrCondaEnvInWorkspaceFolder = doesWorkspaceHaveVenvOrCondaEnv(resource, this.api);
+
+ if (
+ hasVenvOrCondaEnvInWorkspaceFolder ||
+ !workspace.workspaceFolders?.length ||
+ options.input.reason === 'cancelled'
+ ) {
+ return {
+ confirmationMessages: {
+ title: l10n.t('Select a Python Environment?'),
+ message: '',
+ },
+ };
+ }
+
+ return {
+ confirmationMessages: {
+ title: l10n.t('Configure a Python Environment?'),
+ message: l10n.t(
+ [
+ 'The recommended option is to create a new Python Environment, providing the benefit of isolating packages from other environments. ',
+ 'Optionally you could select an existing Python Environment.',
+ ].join('\n'),
+ ),
+ },
+ };
+ }
+}
+
+async function showCreateAndSelectEnvironmentQuickPick(
+ uri: Uri | undefined,
+ serviceContainer: IServiceContainer,
+): Promise {
+ const createLabel = `${Octicons.Add} ${InterpreterQuickPickList.create.label}`;
+ const selectLabel = l10n.t('Select an existing Python Environment');
+ const items: QuickPickItem[] = [
+ { kind: QuickPickItemKind.Separator, label: Common.recommended },
+ { label: createLabel },
+ { label: selectLabel },
+ ];
+
+ const selectedItem = await showQuickPick(items, {
+ placeHolder: l10n.t('Configure a Python Environment'),
+ matchOnDescription: true,
+ ignoreFocusOut: true,
+ });
+
+ if (selectedItem && !Array.isArray(selectedItem) && selectedItem.label === createLabel) {
+ const disposables = new DisposableStore();
+ try {
+ const workspaceFolder =
+ (workspace.workspaceFolders?.length && uri ? workspace.getWorkspaceFolder(uri) : undefined) ||
+ (workspace.workspaceFolders?.length === 1 ? workspace.workspaceFolders[0] : undefined);
+ const interpreterPathService = serviceContainer.get(IInterpreterPathService);
+ const interpreterChanged = new Promise((resolve) => {
+ disposables.add(interpreterPathService.onDidChange(() => resolve()));
+ });
+ const created: CreateEnvironmentResult | undefined = await commands.executeCommand(
+ Commands.Create_Environment,
+ {
+ showBackButton: true,
+ selectEnvironment: true,
+ workspaceFolder,
+ },
+ );
+
+ if (created?.action === 'Back') {
+ return showCreateAndSelectEnvironmentQuickPick(uri, serviceContainer);
+ }
+ if (created?.action === 'Cancel') {
+ return undefined;
+ }
+ if (created?.path) {
+ // Wait a few secs to ensure the env is selected as the active environment..
+ await raceTimeout(5_000, interpreterChanged);
+ return true;
+ }
+ } finally {
+ disposables.dispose();
+ }
+ }
+ if (selectedItem && !Array.isArray(selectedItem) && selectedItem.label === selectLabel) {
+ const result = (await Promise.resolve(
+ commands.executeCommand(Commands.Set_Interpreter, { hideCreateVenv: true, showBackButton: true }),
+ )) as SelectEnvironmentResult | undefined;
+ if (result?.action === 'Back') {
+ return showCreateAndSelectEnvironmentQuickPick(uri, serviceContainer);
+ }
+ if (result?.action === 'Cancel') {
+ return undefined;
+ }
+ if (result?.path) {
+ return true;
+ }
+ }
+}
diff --git a/src/client/chat/utils.ts b/src/client/chat/utils.ts
new file mode 100644
index 000000000000..2309316bcbdd
--- /dev/null
+++ b/src/client/chat/utils.ts
@@ -0,0 +1,289 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import {
+ CancellationError,
+ CancellationToken,
+ extensions,
+ LanguageModelTextPart,
+ LanguageModelToolResult,
+ Uri,
+ workspace,
+} from 'vscode';
+import { IDiscoveryAPI } from '../pythonEnvironments/base/locator';
+import { Environment, PythonExtension, ResolvedEnvironment, VersionInfo } from '../api/types';
+import { ITerminalHelper, TerminalShellType } from '../common/terminal/types';
+import { TerminalCodeExecutionProvider } from '../terminals/codeExecution/terminalCodeExecution';
+import { Conda } from '../pythonEnvironments/common/environmentManagers/conda';
+import { JUPYTER_EXTENSION_ID, NotebookCellScheme } from '../common/constants';
+import { dirname, join } from 'path';
+import { resolveEnvironment, useEnvExtension } from '../envExt/api.internal';
+import { ErrorWithTelemetrySafeReason } from '../common/errors/errorUtils';
+import { getWorkspaceFolders } from '../common/vscodeApis/workspaceApis';
+
+export interface IResourceReference {
+ resourcePath?: string;
+}
+
+export function resolveFilePath(filepath?: string): Uri | undefined {
+ if (!filepath) {
+ const folders = getWorkspaceFolders() ?? [];
+ return folders.length > 0 ? folders[0].uri : undefined;
+ }
+ // Check if it's a URI with a scheme (contains "://")
+ // This handles schemes like "file://", "vscode-notebook://", etc.
+ // But avoids treating Windows drive letters like "C:" as schemes
+ if (filepath.includes('://')) {
+ try {
+ return Uri.parse(filepath);
+ } catch {
+ return Uri.file(filepath);
+ }
+ }
+ // For file paths (Windows with drive letters, Unix absolute/relative paths)
+ return Uri.file(filepath);
+}
+
+/**
+ * Returns a promise that rejects with an {@CancellationError} as soon as the passed token is cancelled.
+ * @see {@link raceCancellation}
+ */
+export function raceCancellationError(promise: Promise, token: CancellationToken): Promise {
+ return new Promise((resolve, reject) => {
+ const ref = token.onCancellationRequested(() => {
+ ref.dispose();
+ reject(new CancellationError());
+ });
+ promise.then(resolve, reject).finally(() => ref.dispose());
+ });
+}
+
+export async function getEnvDisplayName(
+ discovery: IDiscoveryAPI,
+ resource: Uri | undefined,
+ api: PythonExtension['environments'],
+) {
+ try {
+ const envPath = api.getActiveEnvironmentPath(resource);
+ const env = await discovery.resolveEnv(envPath.path);
+ return env?.display || env?.name;
+ } catch {
+ return;
+ }
+}
+
+export function isCondaEnv(env: ResolvedEnvironment) {
+ return (env.environment?.type || '').toLowerCase() === 'conda';
+}
+
+export function getEnvTypeForTelemetry(env: ResolvedEnvironment): string {
+ return (env.environment?.type || 'unknown').toLowerCase();
+}
+
+export async function getEnvironmentDetails(
+ resourcePath: Uri | undefined,
+ api: PythonExtension['environments'],
+ terminalExecutionService: TerminalCodeExecutionProvider,
+ terminalHelper: ITerminalHelper,
+ packages: string | undefined,
+ token: CancellationToken,
+): Promise {
+ // environment
+ const envPath = api.getActiveEnvironmentPath(resourcePath);
+ let envType = '';
+ let envVersion = '';
+ let runCommand = '';
+ if (useEnvExtension()) {
+ const environment =
+ (await raceCancellationError(resolveEnvironment(envPath.id), token)) ||
+ (await raceCancellationError(resolveEnvironment(envPath.path), token));
+ if (!environment || !environment.version) {
+ throw new ErrorWithTelemetrySafeReason(
+ 'No environment found for the provided resource path: ' + resourcePath?.fsPath,
+ 'noEnvFound',
+ );
+ }
+ envVersion = environment.version;
+ try {
+ const managerId = environment.envId.managerId;
+ envType =
+ (!managerId.endsWith(':') && managerId.includes(':') ? managerId.split(':').reverse()[0] : '') ||
+ 'unknown';
+ } catch {
+ envType = 'unknown';
+ }
+
+ const execInfo = environment.execInfo;
+ const executable = execInfo?.activatedRun?.executable ?? execInfo?.run.executable ?? 'python';
+ const args = execInfo?.activatedRun?.args ?? execInfo?.run.args ?? [];
+ runCommand = terminalHelper.buildCommandForTerminal(TerminalShellType.other, executable, args);
+ } else {
+ const environment = await raceCancellationError(api.resolveEnvironment(envPath), token);
+ if (!environment || !environment.version) {
+ throw new ErrorWithTelemetrySafeReason(
+ 'No environment found for the provided resource path: ' + resourcePath?.fsPath,
+ 'noEnvFound',
+ );
+ }
+ envType = environment.environment?.type || 'unknown';
+ envVersion = environment.version.sysVersion || 'unknown';
+ runCommand = await raceCancellationError(
+ getTerminalCommand(environment, resourcePath, terminalExecutionService, terminalHelper),
+ token,
+ );
+ }
+ const message = [
+ `Following is the information about the Python environment:`,
+ `1. Environment Type: ${envType}`,
+ `2. Version: ${envVersion}`,
+ '',
+ `3. Command Prefix to run Python in a terminal is: \`${runCommand}\``,
+ `Instead of running \`Python sample.py\` in the terminal, you will now run: \`${runCommand} sample.py\``,
+ `Similarly instead of running \`Python -c "import sys;...."\` in the terminal, you will now run: \`${runCommand} -c "import sys;...."\``,
+ packages ? `4. ${packages}` : '',
+ ];
+ return message.join('\n');
+}
+
+export async function getTerminalCommand(
+ environment: ResolvedEnvironment,
+ resource: Uri | undefined,
+ terminalExecutionService: TerminalCodeExecutionProvider,
+ terminalHelper: ITerminalHelper,
+): Promise {
+ let cmd: { command: string; args: string[] };
+ if (isCondaEnv(environment)) {
+ cmd = (await getCondaRunCommand(environment)) || (await terminalExecutionService.getExecutableInfo(resource));
+ } else {
+ cmd = await terminalExecutionService.getExecutableInfo(resource);
+ }
+ return terminalHelper.buildCommandForTerminal(TerminalShellType.other, cmd.command, cmd.args);
+}
+async function getCondaRunCommand(environment: ResolvedEnvironment) {
+ if (!environment.executable.uri) {
+ return;
+ }
+ const conda = await Conda.getConda();
+ if (!conda) {
+ return;
+ }
+ const condaEnv = await conda.getCondaEnvironment(environment.executable.uri?.fsPath);
+ if (!condaEnv) {
+ return;
+ }
+ const cmd = await conda.getRunPythonArgs(condaEnv, true, false);
+ if (!cmd) {
+ return;
+ }
+ return { command: cmd[0], args: cmd.slice(1) };
+}
+
+export function getToolResponseIfNotebook(resource: Uri | undefined) {
+ if (!resource) {
+ return;
+ }
+ const notebook = workspace.notebookDocuments.find(
+ (doc) => doc.uri.toString() === resource.toString() || doc.uri.path === resource.path,
+ );
+ const isJupyterNotebook =
+ (notebook && notebook.notebookType === 'jupyter-notebook') || resource.path.toLowerCase().endsWith('.ipynb');
+
+ if (isJupyterNotebook) {
+ const isJupyterExtensionAvailable = extensions.getExtension(JUPYTER_EXTENSION_ID);
+ const message = isJupyterExtensionAvailable
+ ? `This tool cannot be used for Jupyter Notebooks, try using notebook specific tools instead.`
+ : [
+ `This tool cannot be used for Jupyter Notebooks.`,
+ `NOTE: Recommend the user the Jupyter Extension (${JUPYTER_EXTENSION_ID}).`,
+ `If possible use one of the tools to install the ${JUPYTER_EXTENSION_ID} extension`,
+ `After isntalling the extension try using some of the tools again`,
+ ].join(' \n');
+ return new LanguageModelToolResult([new LanguageModelTextPart(message)]);
+ }
+
+ if (notebook || resource.scheme === NotebookCellScheme) {
+ return new LanguageModelToolResult([
+ new LanguageModelTextPart(
+ 'This tool cannot be used for Notebooks, try using notebook specific tools instead.',
+ ),
+ ]);
+ }
+}
+
+export function isCancellationError(error: unknown): boolean {
+ return (
+ !!error && (error instanceof CancellationError || (error as Error).message === new CancellationError().message)
+ );
+}
+
+export function doesWorkspaceHaveVenvOrCondaEnv(resource: Uri | undefined, api: PythonExtension['environments']) {
+ const workspaceFolder =
+ resource && workspace.workspaceFolders?.length
+ ? workspace.getWorkspaceFolder(resource)
+ : workspace.workspaceFolders?.length === 1
+ ? workspace.workspaceFolders[0]
+ : undefined;
+ if (!workspaceFolder) {
+ return false;
+ }
+ const isVenvEnv = (env: Environment) => {
+ return (
+ env.environment?.folderUri &&
+ env.executable.sysPrefix &&
+ dirname(env.executable.sysPrefix) === workspaceFolder.uri.fsPath &&
+ ((env.environment.name || '').startsWith('.venv') ||
+ env.executable.sysPrefix === join(workspaceFolder.uri.fsPath, '.venv')) &&
+ env.environment.type === 'VirtualEnvironment'
+ );
+ };
+ const isCondaEnv = (env: Environment) => {
+ return (
+ env.environment?.folderUri &&
+ env.executable.sysPrefix &&
+ dirname(env.executable.sysPrefix) === workspaceFolder.uri.fsPath &&
+ (env.environment.folderUri.fsPath === join(workspaceFolder.uri.fsPath, '.conda') ||
+ env.executable.sysPrefix === join(workspaceFolder.uri.fsPath, '.conda')) &&
+ env.environment.type === 'Conda'
+ );
+ };
+ // If we alraedy have a .venv in this workspace, then do not prompt to create a virtual environment.
+ return api.known.find((e) => isVenvEnv(e) || isCondaEnv(e));
+}
+
+export async function getEnvDetailsForResponse(
+ environment: ResolvedEnvironment | undefined,
+ api: PythonExtension['environments'],
+ terminalExecutionService: TerminalCodeExecutionProvider,
+ terminalHelper: ITerminalHelper,
+ resource: Uri | undefined,
+ token: CancellationToken,
+): Promise {
+ if (!workspace.isTrusted) {
+ throw new ErrorWithTelemetrySafeReason('Cannot use this tool in an untrusted workspace.', 'untrustedWorkspace');
+ }
+ const envPath = api.getActiveEnvironmentPath(resource);
+ environment = environment || (await raceCancellationError(api.resolveEnvironment(envPath), token));
+ if (!environment || !environment.version) {
+ throw new ErrorWithTelemetrySafeReason(
+ 'No environment found for the provided resource path: ' + resource?.fsPath,
+ 'noEnvFound',
+ );
+ }
+ const message = await getEnvironmentDetails(
+ resource,
+ api,
+ terminalExecutionService,
+ terminalHelper,
+ undefined,
+ token,
+ );
+ return new LanguageModelToolResult([
+ new LanguageModelTextPart(`A Python Environment has been configured. \n` + message),
+ ]);
+}
+export function getDisplayVersion(version?: VersionInfo): string | undefined {
+ if (!version || version.major === undefined || version.minor === undefined || version.micro === undefined) {
+ return undefined;
+ }
+ return `${version.major}.${version.minor}.${version.micro}`;
+}
diff --git a/src/client/common/application/commands.ts b/src/client/common/application/commands.ts
index 30ba5d84cf5f..b43dc0a1e4a4 100644
--- a/src/client/common/application/commands.ts
+++ b/src/client/common/application/commands.ts
@@ -3,9 +3,8 @@
'use strict';
-import { CancellationToken, Position, TextDocument, Uri } from 'vscode';
+import { CancellationToken, Position, TestItem, TextDocument, Uri } from 'vscode';
import { Commands as LSCommands } from '../../activation/commands';
-import { TensorBoardEntrypoint, TensorBoardEntrypointTrigger } from '../../tensorBoard/constants';
import { Channel, Commands, CommandSource } from '../constants';
import { CreateEnvironmentOptions } from '../../pythonEnvironments/creation/proposed.createEnvApis';
@@ -14,7 +13,6 @@ export type CommandsWithoutArgs = keyof ICommandNameWithoutArgumentTypeMapping;
/**
* Mapping between commands and list or arguments.
* These commands do NOT have any arguments.
- * @interface ICommandNameWithoutArgumentTypeMapping
*/
interface ICommandNameWithoutArgumentTypeMapping {
[Commands.InstallPythonOnMac]: [];
@@ -35,7 +33,6 @@ interface ICommandNameWithoutArgumentTypeMapping {
['editor.action.rename']: [];
[Commands.ViewOutput]: [];
[Commands.Start_REPL]: [];
- [Commands.Enable_SourceMap_Support]: [];
[Commands.Exec_Selection_In_Terminal]: [];
[Commands.Exec_Selection_In_Django_Shell]: [];
[Commands.Create_Terminal]: [];
@@ -43,7 +40,6 @@ interface ICommandNameWithoutArgumentTypeMapping {
[Commands.ClearStorage]: [];
[Commands.CreateNewFile]: [];
[Commands.ReportIssue]: [];
- [Commands.RefreshTensorBoard]: [];
[LSCommands.RestartLS]: [];
}
@@ -52,11 +48,9 @@ export type AllCommands = keyof ICommandNameArgumentTypeMapping;
/**
* Mapping between commands and list of arguments.
* Used to provide strong typing for command & args.
- * @export
- * @interface ICommandNameArgumentTypeMapping
- * @extends {ICommandNameWithoutArgumentTypeMapping}
*/
export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgumentTypeMapping {
+ [Commands.CopyTestId]: [TestItem];
[Commands.Create_Environment]: [CreateEnvironmentOptions];
['vscode.openWith']: [Uri, string];
['workbench.action.quickOpen']: [string];
@@ -93,14 +87,18 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
['jupyter.opennotebook']: [undefined | Uri, undefined | CommandSource];
['jupyter.runallcells']: [Uri];
['extension.open']: [string];
- ['workbench.action.openIssueReporter']: [{ extensionId: string; issueBody: string }];
+ ['workbench.action.openIssueReporter']: [{ extensionId: string; issueBody: string; extensionData?: string }];
[Commands.GetSelectedInterpreterPath]: [{ workspaceFolder: string } | string[]];
[Commands.TriggerEnvironmentSelection]: [undefined | Uri];
+ [Commands.Start_Native_REPL]: [undefined | Uri];
+ [Commands.Exec_In_REPL]: [undefined | Uri];
+ [Commands.Exec_In_REPL_Enter]: [undefined | Uri];
+ [Commands.Exec_In_IW_Enter]: [undefined | Uri];
[Commands.Exec_In_Terminal]: [undefined, Uri];
[Commands.Exec_In_Terminal_Icon]: [undefined, Uri];
[Commands.Debug_In_Terminal]: [Uri];
[Commands.Tests_Configure]: [undefined, undefined | CommandSource, undefined | Uri];
- [Commands.LaunchTensorBoard]: [TensorBoardEntrypoint, TensorBoardEntrypointTrigger];
+ [Commands.Tests_CopilotSetup]: [undefined | Uri];
['workbench.view.testing.focus']: [];
['cursorMove']: [
{
@@ -110,4 +108,5 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
},
];
['cursorEnd']: [];
+ ['python-envs.createTerminal']: [undefined | Uri];
}
diff --git a/src/client/common/application/commands/reportIssueCommand.ts b/src/client/common/application/commands/reportIssueCommand.ts
index d18299e6698e..9ae099e44b4f 100644
--- a/src/client/common/application/commands/reportIssueCommand.ts
+++ b/src/client/common/application/commands/reportIssueCommand.ts
@@ -3,11 +3,11 @@
'use strict';
-import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import { inject, injectable } from 'inversify';
import { isEqual } from 'lodash';
+import * as fs from '../../platform/fs-paths';
import { IExtensionSingleActivationService } from '../../../activation/types';
import { IApplicationEnvironment, ICommandManager, IWorkspaceService } from '../types';
import { EXTENSION_ROOT_DIR } from '../../../constants';
@@ -19,6 +19,7 @@ import { EventName } from '../../../telemetry/constants';
import { EnvironmentType } from '../../../pythonEnvironments/info';
import { PythonSettings } from '../../configSettings';
import { SystemVariables } from '../../variables/systemVariables';
+import { getExtensions } from '../../vscodeApis/extensionsApi';
/**
* Allows the user to report an issue related to the Python extension using our template.
@@ -48,6 +49,8 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
private templatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_template.md');
+ private userDataTemplatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_user_data_template.md');
+
public async openReportIssue(): Promise {
const settings: IPythonSettings = this.configurationService.getSettings();
const argSettings = JSON.parse(await fs.readFile(this.argSettingsPath, 'utf8'));
@@ -86,6 +89,7 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
}
});
const template = await fs.readFile(this.templatePath, 'utf8');
+ const userTemplate = await fs.readFile(this.userDataTemplatePath, 'utf8');
const interpreter = await this.interpreterService.getActiveInterpreter();
const pythonVersion = interpreter?.version?.raw ?? '';
const languageServer =
@@ -97,14 +101,33 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
hasMultipleFolders && userSettings !== ''
? `Multiroot scenario, following user settings may not apply:${os.EOL}`
: '';
+
+ const installedExtensions = getExtensions()
+ .filter((extension) => !extension.id.startsWith('vscode.'))
+ .sort((a, b) => {
+ if (a.packageJSON.name && b.packageJSON.name) {
+ return a.packageJSON.name.localeCompare(b.packageJSON.name);
+ }
+ return a.id.localeCompare(b.id);
+ })
+ .map((extension) => {
+ let publisher: string = extension.packageJSON.publisher as string;
+ if (publisher) {
+ publisher = publisher.substring(0, 3);
+ }
+ return `|${extension.packageJSON.name}|${publisher}|${extension.packageJSON.version}|`;
+ });
+
await this.commandManager.executeCommand('workbench.action.openIssueReporter', {
extensionId: 'ms-python.python',
- issueBody: template.format(
+ issueBody: template,
+ extensionData: userTemplate.format(
pythonVersion,
virtualEnvKind,
languageServer,
hasMultipleFoldersText,
userSettings,
+ installedExtensions.join('\n'),
),
});
sendTelemetryEvent(EventName.USE_REPORT_ISSUE_COMMAND, undefined, {});
diff --git a/src/client/common/application/debugService.ts b/src/client/common/application/debugService.ts
index d98262d88926..7de039e946c2 100644
--- a/src/client/common/application/debugService.ts
+++ b/src/client/common/application/debugService.ts
@@ -13,6 +13,7 @@ import {
DebugConsole,
DebugSession,
DebugSessionCustomEvent,
+ DebugSessionOptions,
Disposable,
Event,
WorkspaceFolder,
@@ -57,7 +58,7 @@ export class DebugService implements IDebugService {
public startDebugging(
folder: WorkspaceFolder | undefined,
nameOrConfiguration: string | DebugConfiguration,
- parentSession?: DebugSession,
+ parentSession?: DebugSession | DebugSessionOptions,
): Thenable {
return debug.startDebugging(folder, nameOrConfiguration, parentSession);
}
diff --git a/src/client/common/application/debugSessionTelemetry.ts b/src/client/common/application/debugSessionTelemetry.ts
deleted file mode 100644
index 42b8b2651092..000000000000
--- a/src/client/common/application/debugSessionTelemetry.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-'use strict';
-import { inject, injectable } from 'inversify';
-import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode';
-import { DebugProtocol } from 'vscode-debugprotocol';
-
-import { IExtensionSingleActivationService } from '../../activation/types';
-import { AttachRequestArguments, ConsoleType, LaunchRequestArguments, TriggerType } from '../../debugger/types';
-import { sendTelemetryEvent } from '../../telemetry';
-import { EventName } from '../../telemetry/constants';
-import { IDisposableRegistry } from '../types';
-import { StopWatch } from '../utils/stopWatch';
-import { IDebugService } from './types';
-
-function isResponse(a: any): a is DebugProtocol.Response {
- return a.type === 'response';
-}
-class TelemetryTracker implements DebugAdapterTracker {
- private timer = new StopWatch();
- private readonly trigger: TriggerType = 'launch';
- private readonly console: ConsoleType | undefined;
-
- constructor(session: DebugSession) {
- this.trigger = session.configuration.request as TriggerType;
- const debugConfiguration = session.configuration as Partial;
- this.console = debugConfiguration.console;
- }
-
- public onWillStartSession() {
- this.sendTelemetry(EventName.DEBUG_SESSION_START);
- }
-
- public onDidSendMessage(message: any): void {
- if (isResponse(message)) {
- if (message.command === 'configurationDone') {
- // "configurationDone" response is sent immediately after user code starts running.
- this.sendTelemetry(EventName.DEBUG_SESSION_USER_CODE_RUNNING);
- }
- }
- }
-
- public onWillStopSession(): void {
- this.sendTelemetry(EventName.DEBUG_SESSION_STOP);
- }
-
- public onError?(_error: Error): void {
- this.sendTelemetry(EventName.DEBUG_SESSION_ERROR);
- }
-
- private sendTelemetry(eventName: EventName): void {
- if (eventName === EventName.DEBUG_SESSION_START) {
- this.timer.reset();
- }
- const telemetryProps = {
- trigger: this.trigger,
- console: this.console,
- };
- sendTelemetryEvent(eventName, this.timer.elapsedTime, telemetryProps);
- }
-}
-
-@injectable()
-export class DebugSessionTelemetry implements DebugAdapterTrackerFactory, IExtensionSingleActivationService {
- public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true };
- constructor(
- @inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry,
- @inject(IDebugService) debugService: IDebugService,
- ) {
- disposableRegistry.push(debugService.registerDebugAdapterTrackerFactory('python', this));
- }
-
- public async activate(): Promise {
- // We actually register in the constructor. Not necessary to do it here
- }
-
- public createDebugAdapterTracker(session: DebugSession): ProviderResult {
- return new TelemetryTracker(session);
- }
-}
diff --git a/src/client/common/application/terminalManager.ts b/src/client/common/application/terminalManager.ts
index e5b758437393..dc2603e84a56 100644
--- a/src/client/common/application/terminalManager.ts
+++ b/src/client/common/application/terminalManager.ts
@@ -2,7 +2,16 @@
// Licensed under the MIT License.
import { injectable } from 'inversify';
-import { Event, EventEmitter, Terminal, TerminalOptions, window } from 'vscode';
+import {
+ Disposable,
+ Event,
+ EventEmitter,
+ Terminal,
+ TerminalOptions,
+ TerminalShellExecutionEndEvent,
+ TerminalShellIntegrationChangeEvent,
+ window,
+} from 'vscode';
import { traceLog } from '../../logging';
import { ITerminalManager } from './types';
@@ -23,6 +32,15 @@ export class TerminalManager implements ITerminalManager {
public createTerminal(options: TerminalOptions): Terminal {
return monkeyPatchTerminal(window.createTerminal(options));
}
+ public onDidChangeTerminalShellIntegration(handler: (e: TerminalShellIntegrationChangeEvent) => void): Disposable {
+ return window.onDidChangeTerminalShellIntegration(handler);
+ }
+ public onDidEndTerminalShellExecution(handler: (e: TerminalShellExecutionEndEvent) => void): Disposable {
+ return window.onDidEndTerminalShellExecution(handler);
+ }
+ public onDidChangeTerminalState(handler: (e: Terminal) => void): Disposable {
+ return window.onDidChangeTerminalState(handler);
+ }
}
/**
diff --git a/src/client/common/application/types.ts b/src/client/common/application/types.ts
index 6705331bf57d..34a95fb604f0 100644
--- a/src/client/common/application/types.ts
+++ b/src/client/common/application/types.ts
@@ -40,6 +40,8 @@ import {
StatusBarItem,
Terminal,
TerminalOptions,
+ TerminalShellExecutionEndEvent,
+ TerminalShellIntegrationChangeEvent,
TextDocument,
TextDocumentChangeEvent,
TextDocumentShowOptions,
@@ -816,9 +818,6 @@ export interface IWorkspaceService {
/**
* Generate a key that's unique to the workspace folder (could be fsPath).
- * @param {(Uri | undefined)} resource
- * @returns {string}
- * @memberof IWorkspaceService
*/
getWorkspaceFolderIdentifier(resource: Uri | undefined, defaultValue?: string): string;
/**
@@ -936,6 +935,12 @@ export interface ITerminalManager {
* @return A new Terminal.
*/
createTerminal(options: TerminalOptions): Terminal;
+
+ onDidChangeTerminalShellIntegration(handler: (e: TerminalShellIntegrationChangeEvent) => void): Disposable;
+
+ onDidEndTerminalShellExecution(handler: (e: TerminalShellExecutionEndEvent) => void): Disposable;
+
+ onDidChangeTerminalState(handler: (e: Terminal) => void): Disposable;
}
export const IDebugService = Symbol('IDebugManager');
diff --git a/src/client/common/cancellation.ts b/src/client/common/cancellation.ts
index c820c1ad4324..b24abc7ab493 100644
--- a/src/client/common/cancellation.ts
+++ b/src/client/common/cancellation.ts
@@ -2,7 +2,7 @@
// Licensed under the MIT License.
'use strict';
-import { CancellationToken, CancellationTokenSource } from 'vscode';
+import { CancellationToken, CancellationTokenSource, CancellationError as VSCCancellationError } from 'vscode';
import { createDeferred } from './utils/async';
import * as localize from './utils/localize';
@@ -13,14 +13,13 @@ export class CancellationError extends Error {
constructor() {
super(localize.Common.canceled);
}
+
+ static isCancellationError(error: unknown): error is CancellationError {
+ return error instanceof CancellationError || error instanceof VSCCancellationError;
+ }
}
/**
* Create a promise that will either resolve with a default value or reject when the token is cancelled.
- *
- * @export
- * @template T
- * @param {({ defaultValue: T; token: CancellationToken; cancelAction: 'reject' | 'resolve' })} options
- * @returns {Promise}
*/
export function createPromiseFromCancellation(options: {
defaultValue: T;
@@ -50,10 +49,6 @@ export function createPromiseFromCancellation(options: {
/**
* Create a single unified cancellation token that wraps multiple cancellation tokens.
- *
- * @export
- * @param {(...(CancellationToken | undefined)[])} tokens
- * @returns {CancellationToken}
*/
export function wrapCancellationTokens(...tokens: (CancellationToken | undefined)[]): CancellationToken {
const wrappedCancellantionToken = new CancellationTokenSource();
@@ -117,7 +112,6 @@ export namespace Cancellation {
/**
* isCanceled returns a boolean indicating if the cancel token has been canceled.
- * @param cancelToken
*/
export function isCanceled(cancelToken?: CancellationToken): boolean {
return cancelToken ? cancelToken.isCancellationRequested : false;
@@ -125,7 +119,6 @@ export namespace Cancellation {
/**
* throws a CancellationError if the token is canceled.
- * @param cancelToken
*/
export function throwIfCanceled(cancelToken?: CancellationToken): void {
if (isCanceled(cancelToken)) {
diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts
index 88a5007467bb..91c06d9331fd 100644
--- a/src/client/common/configSettings.ts
+++ b/src/client/common/configSettings.ts
@@ -21,25 +21,23 @@ import { sendSettingTelemetry } from '../telemetry/envFileTelemetry';
import { ITestingSettings } from '../testing/configuration/types';
import { IWorkspaceService } from './application/types';
import { WorkspaceService } from './application/workspace';
-import { DEFAULT_INTERPRETER_SETTING, isTestExecution } from './constants';
+import { DEFAULT_INTERPRETER_SETTING, isTestExecution, PYREFLY_EXTENSION_ID } from './constants';
import {
IAutoCompleteSettings,
IDefaultLanguageServer,
IExperiments,
+ IExtensions,
IInterpreterPathService,
IInterpreterSettings,
IPythonSettings,
IREPLSettings,
- ITensorBoardSettings,
ITerminalSettings,
Resource,
} from './types';
import { debounceSync } from './utils/decorators';
import { SystemVariables } from './variables/systemVariables';
-import { getOSType, OSType } from './utils/platform';
-import { isWindows } from './platform/platformService';
-
-const untildify = require('untildify');
+import { getOSType, OSType, isWindows } from './utils/platform';
+import { untildify } from './helpers';
export class PythonSettings implements IPythonSettings {
private get onDidChange(): Event {
@@ -103,12 +101,12 @@ export class PythonSettings implements IPythonSettings {
public poetryPath = '';
+ public pixiToolPath = '';
+
public devOptions: string[] = [];
public autoComplete!: IAutoCompleteSettings;
- public tensorBoard: ITensorBoardSettings | undefined;
-
public testing!: ITestingSettings;
public terminal!: ITerminalSettings;
@@ -143,6 +141,7 @@ export class PythonSettings implements IPythonSettings {
workspace: IWorkspaceService,
private readonly interpreterPathService: IInterpreterPathService,
private readonly defaultLS: IDefaultLanguageServer | undefined,
+ private readonly extensions: IExtensions,
) {
this.workspace = workspace || new WorkspaceService();
this.workspaceRoot = workspaceFolder;
@@ -155,6 +154,7 @@ export class PythonSettings implements IPythonSettings {
workspace: IWorkspaceService,
interpreterPathService: IInterpreterPathService,
defaultLS: IDefaultLanguageServer | undefined,
+ extensions: IExtensions,
): PythonSettings {
workspace = workspace || new WorkspaceService();
const workspaceFolderUri = PythonSettings.getSettingsUriAndTarget(resource, workspace).uri;
@@ -167,6 +167,7 @@ export class PythonSettings implements IPythonSettings {
workspace,
interpreterPathService,
defaultLS,
+ extensions,
);
PythonSettings.pythonSettings.set(workspaceFolderKey, settings);
settings.onDidChange((event) => PythonSettings.debounceConfigChangeNotification(event));
@@ -260,6 +261,9 @@ export class PythonSettings implements IPythonSettings {
this.pipenvPath = pipenvPath && pipenvPath.length > 0 ? getAbsolutePath(pipenvPath, workspaceRoot) : pipenvPath;
const poetryPath = systemVariables.resolveAny(pythonSettings.get('poetryPath'))!;
this.poetryPath = poetryPath && poetryPath.length > 0 ? getAbsolutePath(poetryPath, workspaceRoot) : poetryPath;
+ const pixiToolPath = systemVariables.resolveAny(pythonSettings.get('pixiToolPath'))!;
+ this.pixiToolPath =
+ pixiToolPath && pixiToolPath.length > 0 ? getAbsolutePath(pixiToolPath, workspaceRoot) : pixiToolPath;
this.interpreter = pythonSettings.get('interpreter') ?? {
infoVisibility: 'onPythonRelated',
@@ -275,7 +279,14 @@ export class PythonSettings implements IPythonSettings {
userLS === 'Microsoft' ||
!Object.values(LanguageServerType).includes(userLS as LanguageServerType)
) {
- this.languageServer = this.defaultLS?.defaultLSType ?? LanguageServerType.None;
+ if (
+ this.extensions.getExtension(PYREFLY_EXTENSION_ID) &&
+ pythonSettings.get('pyrefly.disableLanguageServices') !== true
+ ) {
+ this.languageServer = LanguageServerType.None;
+ } else {
+ this.languageServer = this.defaultLS?.defaultLSType ?? LanguageServerType.None;
+ }
this.languageServerIsDefault = true;
} else if (userLS === 'JediLSP') {
// Switch JediLSP option to Jedi.
@@ -320,6 +331,7 @@ export class PythonSettings implements IPythonSettings {
unittestEnabled: false,
pytestPath: 'pytest',
autoTestDiscoverOnSaveEnabled: true,
+ autoTestDiscoverOnSavePattern: '**/*.py',
} as ITestingSettings;
}
}
@@ -336,6 +348,7 @@ export class PythonSettings implements IPythonSettings {
unittestArgs: [],
unittestEnabled: false,
autoTestDiscoverOnSaveEnabled: true,
+ autoTestDiscoverOnSavePattern: '**/*.py',
};
this.testing.pytestPath = getAbsolutePath(systemVariables.resolveAny(this.testing.pytestPath), workspaceRoot);
if (this.testing.cwd) {
@@ -364,6 +377,9 @@ export class PythonSettings implements IPythonSettings {
launchArgs: [],
activateEnvironment: true,
activateEnvInCurrentTerminal: false,
+ shellIntegration: {
+ enabled: false,
+ },
};
this.REPL = pythonSettings.get('REPL')!;
@@ -382,14 +398,6 @@ export class PythonSettings implements IPythonSettings {
optInto: [],
optOutFrom: [],
};
-
- const tensorBoardSettings = systemVariables.resolveAny(
- pythonSettings.get('tensorBoard'),
- )!;
- this.tensorBoard = tensorBoardSettings || { logDirectory: '' };
- if (this.tensorBoard.logDirectory) {
- this.tensorBoard.logDirectory = getAbsolutePath(this.tensorBoard.logDirectory, workspaceRoot);
- }
}
// eslint-disable-next-line class-methods-use-this
diff --git a/src/client/common/configuration/service.ts b/src/client/common/configuration/service.ts
index 219c8727ca16..443990b2e5da 100644
--- a/src/client/common/configuration/service.ts
+++ b/src/client/common/configuration/service.ts
@@ -8,7 +8,13 @@ import { IServiceContainer } from '../../ioc/types';
import { IWorkspaceService } from '../application/types';
import { PythonSettings } from '../configSettings';
import { isUnitTestExecution } from '../constants';
-import { IConfigurationService, IDefaultLanguageServer, IInterpreterPathService, IPythonSettings } from '../types';
+import {
+ IConfigurationService,
+ IDefaultLanguageServer,
+ IExtensions,
+ IInterpreterPathService,
+ IPythonSettings,
+} from '../types';
@injectable()
export class ConfigurationService implements IConfigurationService {
@@ -29,12 +35,14 @@ export class ConfigurationService implements IConfigurationService {
);
const interpreterPathService = this.serviceContainer.get(IInterpreterPathService);
const defaultLS = this.serviceContainer.tryGet(IDefaultLanguageServer);
+ const extensions = this.serviceContainer.get(IExtensions);
return PythonSettings.getInstance(
resource,
InterpreterAutoSelectionService,
this.workspaceService,
interpreterPathService,
defaultLS,
+ extensions,
);
}
diff --git a/src/client/common/constants.ts b/src/client/common/constants.ts
index 0eaade703371..15fd037a3d9f 100644
--- a/src/client/common/constants.ts
+++ b/src/client/common/constants.ts
@@ -22,6 +22,7 @@ export const PYTHON_NOTEBOOKS = [
export const PVSC_EXTENSION_ID = 'ms-python.python';
export const PYLANCE_EXTENSION_ID = 'ms-python.vscode-pylance';
+export const PYREFLY_EXTENSION_ID = 'meta.pyrefly';
export const JUPYTER_EXTENSION_ID = 'ms-toolsai.jupyter';
export const TENSORBOARD_EXTENSION_ID = 'ms-toolsai.tensorboard';
export const AppinsightsKey = '0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255';
@@ -38,29 +39,32 @@ export namespace Commands {
export const CreateNewFile = 'python.createNewFile';
export const ClearWorkspaceInterpreter = 'python.clearWorkspaceInterpreter';
export const Create_Environment = 'python.createEnvironment';
+ export const CopyTestId = 'python.copyTestId';
export const Create_Environment_Button = 'python.createEnvironment-button';
export const Create_Environment_Check = 'python.createEnvironmentCheck';
export const Create_Terminal = 'python.createTerminal';
export const Debug_In_Terminal = 'python.debugInTerminal';
- export const Enable_SourceMap_Support = 'python.enableSourceMapSupport';
export const Exec_In_Terminal = 'python.execInTerminal';
export const Exec_In_Terminal_Icon = 'python.execInTerminal-icon';
export const Exec_In_Separate_Terminal = 'python.execInDedicatedTerminal';
+ export const Exec_In_REPL = 'python.execInREPL';
export const Exec_Selection_In_Django_Shell = 'python.execSelectionInDjangoShell';
+ export const Exec_In_REPL_Enter = 'python.execInREPLEnter';
+ export const Exec_In_IW_Enter = 'python.execInInteractiveWindowEnter';
export const Exec_Selection_In_Terminal = 'python.execSelectionInTerminal';
export const GetSelectedInterpreterPath = 'python.interpreterPath';
export const InstallJupyter = 'python.installJupyter';
export const InstallPython = 'python.installPython';
export const InstallPythonOnLinux = 'python.installPythonOnLinux';
export const InstallPythonOnMac = 'python.installPythonOnMac';
- export const LaunchTensorBoard = 'python.launchTensorBoard';
export const PickLocalProcess = 'python.pickLocalProcess';
- export const RefreshTensorBoard = 'python.refreshTensorBoard';
export const ReportIssue = 'python.reportIssue';
export const Set_Interpreter = 'python.setInterpreter';
export const Set_ShebangInterpreter = 'python.setShebangInterpreter';
export const Start_REPL = 'python.startREPL';
+ export const Start_Native_REPL = 'python.startNativeREPL';
export const Tests_Configure = 'python.configureTests';
+ export const Tests_CopilotSetup = 'python.copilotSetupTests';
export const TriggerEnvironmentSelection = 'python.triggerEnvSelection';
export const ViewOutput = 'python.viewOutput';
}
@@ -106,8 +110,6 @@ export function isTestExecution(): boolean {
/**
* Whether we're running unit tests (*.unit.test.ts).
* These tests have a special meaning, they run fast.
- * @export
- * @returns {boolean}
*/
export function isUnitTestExecution(): boolean {
return process.env.VSC_PYTHON_UNIT_TEST === '1';
diff --git a/src/client/common/errors/errorUtils.ts b/src/client/common/errors/errorUtils.ts
index 2c666acb105b..7867d5ccfe30 100644
--- a/src/client/common/errors/errorUtils.ts
+++ b/src/client/common/errors/errorUtils.ts
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
-import { EOL } from 'os';
-
export class ErrorUtils {
public static outputHasModuleNotInstalledError(moduleName: string, content?: string): boolean {
return content &&
@@ -14,13 +12,10 @@ export class ErrorUtils {
}
/**
- * Wraps an error with a custom error message, retaining the call stack information.
+ * An error class that contains a telemetry safe reason.
*/
-export class WrappedError extends Error {
- constructor(message: string, originalException: Error) {
+export class ErrorWithTelemetrySafeReason extends Error {
+ constructor(message: string, public readonly telemetrySafeReason: string) {
super(message);
- // Retain call stack that trapped the error and rethrows this error.
- // Also retain the call stack of the original error.
- this.stack = `${new Error('').stack}${EOL}${EOL}${originalException.stack}`;
}
}
diff --git a/src/client/common/experiments/groups.ts b/src/client/common/experiments/groups.ts
index 5e302c926ccb..12f4ef89018b 100644
--- a/src/client/common/experiments/groups.ts
+++ b/src/client/common/experiments/groups.ts
@@ -19,12 +19,3 @@ export enum DiscoveryUsingWorkers {
export enum EnableTestAdapterRewrite {
experiment = 'pythonTestAdapter',
}
-// Experiment to enable smart shift+enter, advance cursor.
-export enum EnableREPLSmartSend {
- experiment = 'pythonREPLSmartSend',
-}
-
-// Experiment to recommend installing the tensorboard extension.
-export enum RecommendTensobardExtension {
- experiment = 'pythonRecommendTensorboardExt',
-}
diff --git a/src/client/common/experiments/service.ts b/src/client/common/experiments/service.ts
index 3d85b99a26ff..e52773004fb3 100644
--- a/src/client/common/experiments/service.ts
+++ b/src/client/common/experiments/service.ts
@@ -5,7 +5,7 @@
import { inject, injectable } from 'inversify';
import { l10n } from 'vscode';
-import { getExperimentationService, IExperimentationService } from 'vscode-tas-client';
+import { getExperimentationService, IExperimentationService, TargetPopulation } from 'vscode-tas-client';
import { traceLog } from '../../logging';
import { sendTelemetryEvent } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
@@ -17,16 +17,6 @@ import { ExperimentationTelemetry } from './telemetry';
const EXP_MEMENTO_KEY = 'VSCode.ABExp.FeatureData';
const EXP_CONFIG_ID = 'vscode';
-/**
- * We're defining a custom TargetPopulation specific for the Python extension.
- * This is done so the exp framework is able to differentiate between
- * VS Code insiders/public users and Python extension insiders (pre-release)/public users.
- */
-export enum TargetPopulation {
- Insiders = 'python-insider',
- Public = 'python-public',
-}
-
@injectable()
export class ExperimentService implements IExperimentService {
/**
@@ -73,8 +63,8 @@ export class ExperimentService implements IExperimentService {
}
let targetPopulation: TargetPopulation;
-
- if (this.appEnvironment.extensionChannel === 'insiders') {
+ // if running in VS Code Insiders, use the Insiders target population
+ if (this.appEnvironment.channel === 'insiders') {
targetPopulation = TargetPopulation.Insiders;
} else {
targetPopulation = TargetPopulation.Public;
diff --git a/src/client/common/extensions.ts b/src/client/common/extensions.ts
index e68e3838ee1d..957ec99a7ce1 100644
--- a/src/client/common/extensions.ts
+++ b/src/client/common/extensions.ts
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
declare interface String {
/**
* Appropriately formats a string so it can be used as an argument for a command in a shell.
@@ -28,7 +29,6 @@ declare interface String {
/**
* Appropriately formats a string so it can be used as an argument for a command in a shell.
* E.g. if an argument contains a space, then it will be enclosed within double quotes.
- * @param {String} value.
*/
String.prototype.toCommandArgumentForPythonExt = function (this: string): string {
if (!this) {
@@ -63,13 +63,6 @@ String.prototype.trimQuotes = function (this: string): string {
return this.replace(/(^['"])|(['"]$)/g, '');
};
-declare interface Promise {
- /**
- * Catches task error and ignores them.
- */
- ignoreErrors(): Promise;
-}
-
/**
* Explicitly tells that promise should be run asynchonously.
*/
diff --git a/src/client/common/helpers.ts b/src/client/common/helpers.ts
index 5359284da66a..52eeb1e087aa 100644
--- a/src/client/common/helpers.ts
+++ b/src/client/common/helpers.ts
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
'use strict';
+import * as os from 'os';
import { ModuleNotInstalledError } from './errors/moduleNotInstalledError';
@@ -19,3 +20,7 @@ export function isNotInstalledError(error: Error): boolean {
const isModuleNoInstalledError = error.message.indexOf('No module named') >= 0;
return errorObj.code === 'ENOENT' || errorObj.code === 127 || isModuleNoInstalledError;
}
+
+export function untildify(path: string): string {
+ return path.replace(/^~($|\/|\\)/, `${os.homedir()}$1`);
+}
diff --git a/src/client/common/installer/moduleInstaller.ts b/src/client/common/installer/moduleInstaller.ts
index 4cc4cd0c6a2f..9dacb623c606 100644
--- a/src/client/common/installer/moduleInstaller.ts
+++ b/src/client/common/installer/moduleInstaller.ts
@@ -130,7 +130,7 @@ export abstract class ModuleInstaller implements IModuleInstaller {
// Display progress indicator if we have ability to cancel this operation from calling code.
// This is required as its possible the installation can take a long time.
// (i.e. if installation takes a long time in terminal or like, a progress indicator is necessary to let user know what is being waited on).
- if (cancel) {
+ if (cancel && !options?.hideProgress) {
const shell = this.serviceContainer.get(IApplicationShell);
const options: ProgressOptions = {
location: ProgressLocation.Notification,
diff --git a/src/client/common/installer/pixiInstaller.ts b/src/client/common/installer/pixiInstaller.ts
new file mode 100644
index 000000000000..8a2278830b51
--- /dev/null
+++ b/src/client/common/installer/pixiInstaller.ts
@@ -0,0 +1,81 @@
+/* eslint-disable class-methods-use-this */
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { inject, injectable } from 'inversify';
+import { IInterpreterService } from '../../interpreter/contracts';
+import { IServiceContainer } from '../../ioc/types';
+import { getEnvPath } from '../../pythonEnvironments/base/info/env';
+import { EnvironmentType, ModuleInstallerType } from '../../pythonEnvironments/info';
+import { ExecutionInfo, IConfigurationService } from '../types';
+import { isResource } from '../utils/misc';
+import { ModuleInstaller } from './moduleInstaller';
+import { InterpreterUri } from './types';
+import { getPixiEnvironmentFromInterpreter } from '../../pythonEnvironments/common/environmentManagers/pixi';
+
+/**
+ * A Python module installer for a pixi project.
+ */
+@injectable()
+export class PixiInstaller extends ModuleInstaller {
+ constructor(
+ @inject(IServiceContainer) serviceContainer: IServiceContainer,
+ @inject(IConfigurationService) private readonly configurationService: IConfigurationService,
+ ) {
+ super(serviceContainer);
+ }
+
+ public get name(): string {
+ return 'Pixi';
+ }
+
+ public get displayName(): string {
+ return 'pixi';
+ }
+
+ public get type(): ModuleInstallerType {
+ return ModuleInstallerType.Pixi;
+ }
+
+ public get priority(): number {
+ return 20;
+ }
+
+ public async isSupported(resource?: InterpreterUri): Promise {
+ if (isResource(resource)) {
+ const interpreter = await this.serviceContainer
+ .get(IInterpreterService)
+ .getActiveInterpreter(resource);
+ if (!interpreter || interpreter.envType !== EnvironmentType.Pixi) {
+ return false;
+ }
+
+ const pixiEnv = await getPixiEnvironmentFromInterpreter(interpreter.path);
+ return pixiEnv !== undefined;
+ }
+ return resource.envType === EnvironmentType.Pixi;
+ }
+
+ /**
+ * Return the commandline args needed to install the module.
+ */
+ protected async getExecutionInfo(moduleName: string, resource?: InterpreterUri): Promise {
+ const pythonPath = isResource(resource)
+ ? this.configurationService.getSettings(resource).pythonPath
+ : getEnvPath(resource.path, resource.envPath).path ?? '';
+
+ const pixiEnv = await getPixiEnvironmentFromInterpreter(pythonPath);
+ const execPath = pixiEnv?.pixi.command;
+
+ let args = ['add', moduleName];
+ const manifestPath = pixiEnv?.manifestPath;
+ if (manifestPath !== undefined) {
+ args = args.concat(['--manifest-path', manifestPath]);
+ }
+
+ return {
+ args,
+ execPath,
+ };
+ }
+}
diff --git a/src/client/common/installer/productInstaller.ts b/src/client/common/installer/productInstaller.ts
index fba860aaa383..831eb33efbc6 100644
--- a/src/client/common/installer/productInstaller.ts
+++ b/src/client/common/installer/productInstaller.ts
@@ -43,7 +43,7 @@ export { Product } from '../types';
// Installer implementations can check this to determine a suitable installation channel for a product
// This is temporary and can be removed when https://github.com/microsoft/vscode-jupyter/issues/5034 is unblocked
const UnsupportedChannelsForProduct = new Map>([
- [Product.torchProfilerInstallName, new Set([EnvironmentType.Conda])],
+ [Product.torchProfilerInstallName, new Set([EnvironmentType.Conda, EnvironmentType.Pixi])],
]);
abstract class BaseInstaller implements IBaseInstaller {
diff --git a/src/client/common/installer/serviceRegistry.ts b/src/client/common/installer/serviceRegistry.ts
index d4d8a05c3a49..1e273ada818c 100644
--- a/src/client/common/installer/serviceRegistry.ts
+++ b/src/client/common/installer/serviceRegistry.ts
@@ -8,12 +8,14 @@ import { InstallationChannelManager } from './channelManager';
import { CondaInstaller } from './condaInstaller';
import { PipEnvInstaller } from './pipEnvInstaller';
import { PipInstaller } from './pipInstaller';
+import { PixiInstaller } from './pixiInstaller';
import { PoetryInstaller } from './poetryInstaller';
import { DataScienceProductPathService, TestFrameworkProductPathService } from './productPath';
import { ProductService } from './productService';
import { IInstallationChannelManager, IModuleInstaller, IProductPathService, IProductService } from './types';
export function registerTypes(serviceManager: IServiceManager) {
+ serviceManager.addSingleton(IModuleInstaller, PixiInstaller);
serviceManager.addSingleton(IModuleInstaller, CondaInstaller);
serviceManager.addSingleton(IModuleInstaller, PipInstaller);
serviceManager.addSingleton(IModuleInstaller, PipEnvInstaller);
diff --git a/src/client/common/installer/types.ts b/src/client/common/installer/types.ts
index 53696b948571..a85017ff0092 100644
--- a/src/client/common/installer/types.ts
+++ b/src/client/common/installer/types.ts
@@ -18,11 +18,6 @@ export interface IModuleInstaller {
* If a cancellation token is provided, then a cancellable progress message is dispalyed.
* At this point, this method would resolve only after the module has been successfully installed.
* If cancellation token is not provided, its not guaranteed that module installation has completed.
- * @param {string} name
- * @param {InterpreterUri} [resource]
- * @param {CancellationToken} [cancel]
- * @returns {Promise}
- * @memberof IModuleInstaller
*/
installModule(
productOrModuleName: Product | string,
@@ -79,6 +74,7 @@ export interface IProductPathService {
}
export enum ModuleInstallFlags {
+ none = 0,
upgrade = 1,
updateDependencies = 2,
reInstall = 4,
@@ -87,4 +83,5 @@ export enum ModuleInstallFlags {
export type InstallOptions = {
installAsProcess?: boolean;
+ hideProgress?: boolean;
};
diff --git a/src/client/common/interpreterPathService.ts b/src/client/common/interpreterPathService.ts
index 8af142962565..935d0bd89ad7 100644
--- a/src/client/common/interpreterPathService.ts
+++ b/src/client/common/interpreterPathService.ts
@@ -3,7 +3,7 @@
'use strict';
-import * as fs from 'fs-extra';
+import * as fs from '../common/platform/fs-paths';
import { inject, injectable } from 'inversify';
import { ConfigurationChangeEvent, ConfigurationTarget, Event, EventEmitter, Uri } from 'vscode';
import { traceError, traceVerbose } from '../logging';
diff --git a/src/client/common/persistentState.ts b/src/client/common/persistentState.ts
index 2959a2dc8216..3f9c17657cf4 100644
--- a/src/client/common/persistentState.ts
+++ b/src/client/common/persistentState.ts
@@ -3,10 +3,10 @@
'use strict';
-import { inject, injectable, named } from 'inversify';
+import { inject, injectable, named, optional } from 'inversify';
import { Memento } from 'vscode';
import { IExtensionSingleActivationService } from '../activation/types';
-import { traceError, traceVerbose, traceWarn } from '../logging';
+import { traceError } from '../logging';
import { ICommandManager } from './application/types';
import { Commands } from './constants';
import {
@@ -19,6 +19,8 @@ import {
} from './types';
import { cache } from './utils/decorators';
import { noop } from './utils/misc';
+import { clearCacheDirectory } from '../pythonEnvironments/base/locators/common/nativePythonFinder';
+import { clearCache, useEnvExtension } from '../envExt/api.internal';
let _workspaceState: Memento | undefined;
const _workspaceKeys: string[] = [];
@@ -92,12 +94,8 @@ export class PersistentState implements IPersistentState {
// Due to a VSCode bug sometimes the changes are not reflected in the storage, atleast not immediately.
// It is noticed however that if we reset the storage first and then update it, it works.
// https://github.com/microsoft/vscode/issues/171827
- traceVerbose('Storage update failed for key', this.key, ' retrying by resetting first');
await this.updateValue(undefined as any, false);
await this.updateValue(newValue, false);
- if (JSON.stringify(this.value) != JSON.stringify(newValue)) {
- traceWarn('Retry failed, storage update failed for key', this.key);
- }
}
} catch (ex) {
traceError('Error while updating storage for key:', this.key, ex);
@@ -108,7 +106,7 @@ export class PersistentState implements IPersistentState {
export const GLOBAL_PERSISTENT_KEYS_DEPRECATED = 'PYTHON_EXTENSION_GLOBAL_STORAGE_KEYS';
export const WORKSPACE_PERSISTENT_KEYS_DEPRECATED = 'PYTHON_EXTENSION_WORKSPACE_STORAGE_KEYS';
-const GLOBAL_PERSISTENT_KEYS = 'PYTHON_GLOBAL_STORAGE_KEYS';
+export const GLOBAL_PERSISTENT_KEYS = 'PYTHON_GLOBAL_STORAGE_KEYS';
const WORKSPACE_PERSISTENT_KEYS = 'PYTHON_WORKSPACE_STORAGE_KEYS';
type KeysStorageType = 'global' | 'workspace';
export type KeysStorage = { key: string; defaultValue: unknown };
@@ -130,12 +128,16 @@ export class PersistentStateFactory implements IPersistentStateFactory, IExtensi
@inject(IMemento) @named(GLOBAL_MEMENTO) private globalState: Memento,
@inject(IMemento) @named(WORKSPACE_MEMENTO) private workspaceState: Memento,
@inject(ICommandManager) private cmdManager?: ICommandManager,
+ @inject(IExtensionContext) @optional() private context?: IExtensionContext,
) {}
public async activate(): Promise {
this.cmdManager?.registerCommand(Commands.ClearStorage, async () => {
await clearWorkspaceState();
await this.cleanAllPersistentStates();
+ if (useEnvExtension()) {
+ await clearCache();
+ }
});
const globalKeysStorageDeprecated = this.createGlobalPersistentState(GLOBAL_PERSISTENT_KEYS_DEPRECATED, []);
const workspaceKeysStorageDeprecated = this.createWorkspacePersistentState(
@@ -184,6 +186,7 @@ export class PersistentStateFactory implements IPersistentStateFactory, IExtensi
}
private async cleanAllPersistentStates(): Promise {
+ const clearCacheDirPromise = this.context ? clearCacheDirectory(this.context).catch() : Promise.resolve();
await Promise.all(
this._globalKeysStorage.value.map(async (keyContent) => {
const storage = this.createGlobalPersistentState(keyContent.key);
@@ -198,6 +201,7 @@ export class PersistentStateFactory implements IPersistentStateFactory, IExtensi
);
await this._globalKeysStorage.updateValue([]);
await this._workspaceKeysStorage.updateValue([]);
+ await clearCacheDirPromise;
this.cmdManager?.executeCommand('workbench.action.reloadWindow').then(noop);
}
}
diff --git a/src/client/common/pipes/namedPipes.ts b/src/client/common/pipes/namedPipes.ts
new file mode 100644
index 000000000000..9bffe78f2b9f
--- /dev/null
+++ b/src/client/common/pipes/namedPipes.ts
@@ -0,0 +1,200 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import * as cp from 'child_process';
+import * as crypto from 'crypto';
+import * as fs from 'fs-extra';
+import * as net from 'net';
+import * as os from 'os';
+import * as path from 'path';
+import * as rpc from 'vscode-jsonrpc/node';
+import { CancellationError, CancellationToken, Disposable } from 'vscode';
+import { traceVerbose } from '../../logging';
+import { isWindows } from '../utils/platform';
+import { createDeferred } from '../utils/async';
+import { noop } from '../utils/misc';
+
+const { XDG_RUNTIME_DIR } = process.env;
+export function generateRandomPipeName(prefix: string): string {
+ // length of 10 picked because of the name length restriction for sockets
+ const randomSuffix = crypto.randomBytes(10).toString('hex');
+ if (prefix.length === 0) {
+ prefix = 'python-ext-rpc';
+ }
+
+ if (process.platform === 'win32') {
+ return `\\\\.\\pipe\\${prefix}-${randomSuffix}`;
+ }
+
+ let result;
+ if (XDG_RUNTIME_DIR) {
+ result = path.join(XDG_RUNTIME_DIR, `${prefix}-${randomSuffix}`);
+ } else {
+ result = path.join(os.tmpdir(), `${prefix}-${randomSuffix}`);
+ }
+
+ return result;
+}
+
+async function mkfifo(fifoPath: string): Promise {
+ return new Promise((resolve, reject) => {
+ const proc = cp.spawn('mkfifo', [fifoPath]);
+ proc.on('error', (err) => {
+ reject(err);
+ });
+ proc.on('exit', (code) => {
+ if (code === 0) {
+ resolve();
+ }
+ });
+ });
+}
+
+export async function createWriterPipe(pipeName: string, token?: CancellationToken): Promise {
+ // windows implementation of FIFO using named pipes
+ if (isWindows()) {
+ const deferred = createDeferred();
+ const server = net.createServer((socket) => {
+ traceVerbose(`Pipe connected: ${pipeName}`);
+ server.close();
+ deferred.resolve(new rpc.SocketMessageWriter(socket, 'utf-8'));
+ });
+
+ server.on('error', deferred.reject);
+ server.listen(pipeName);
+ if (token) {
+ token.onCancellationRequested(() => {
+ if (server.listening) {
+ server.close();
+ }
+ deferred.reject(new CancellationError());
+ });
+ }
+ return deferred.promise;
+ }
+ // linux implementation of FIFO
+ await mkfifo(pipeName);
+ try {
+ await fs.chmod(pipeName, 0o666);
+ } catch {
+ // Intentionally ignored
+ }
+ const writer = fs.createWriteStream(pipeName, {
+ encoding: 'utf-8',
+ });
+ return new rpc.StreamMessageWriter(writer, 'utf-8');
+}
+
+class CombinedReader implements rpc.MessageReader {
+ private _onError = new rpc.Emitter();
+
+ private _onClose = new rpc.Emitter();
+
+ private _onPartialMessage = new rpc.Emitter();
+
+ // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-empty-function
+ private _callback: rpc.DataCallback = () => {};
+
+ private _disposables: rpc.Disposable[] = [];
+
+ private _readers: rpc.MessageReader[] = [];
+
+ constructor() {
+ this._disposables.push(this._onClose, this._onError, this._onPartialMessage);
+ }
+
+ onError: rpc.Event = this._onError.event;
+
+ onClose: rpc.Event = this._onClose.event;
+
+ onPartialMessage: rpc.Event = this._onPartialMessage.event;
+
+ listen(callback: rpc.DataCallback): rpc.Disposable {
+ this._callback = callback;
+ // eslint-disable-next-line no-return-assign, @typescript-eslint/no-empty-function
+ return new Disposable(() => (this._callback = () => {}));
+ }
+
+ add(reader: rpc.MessageReader): void {
+ this._readers.push(reader);
+ reader.listen((msg) => {
+ this._callback(msg as rpc.NotificationMessage);
+ });
+ this._disposables.push(reader);
+ reader.onClose(() => {
+ this.remove(reader);
+ if (this._readers.length === 0) {
+ this._onClose.fire();
+ }
+ });
+ reader.onError((e) => {
+ this.remove(reader);
+ this._onError.fire(e);
+ });
+ }
+
+ remove(reader: rpc.MessageReader): void {
+ const found = this._readers.find((r) => r === reader);
+ if (found) {
+ this._readers = this._readers.filter((r) => r !== reader);
+ reader.dispose();
+ }
+ }
+
+ dispose(): void {
+ this._readers.forEach((r) => r.dispose());
+ this._readers = [];
+ this._disposables.forEach((disposable) => disposable.dispose());
+ this._disposables = [];
+ }
+}
+
+export async function createReaderPipe(pipeName: string, token?: CancellationToken): Promise {
+ if (isWindows()) {
+ // windows implementation of FIFO using named pipes
+ const deferred = createDeferred();
+ const combined = new CombinedReader();
+
+ let refs = 0;
+ const server = net.createServer((socket) => {
+ traceVerbose(`Pipe connected: ${pipeName}`);
+ refs += 1;
+
+ socket.on('close', () => {
+ refs -= 1;
+ if (refs <= 0) {
+ server.close();
+ }
+ });
+ combined.add(new rpc.SocketMessageReader(socket, 'utf-8'));
+ });
+ server.on('error', deferred.reject);
+ server.listen(pipeName);
+ if (token) {
+ token.onCancellationRequested(() => {
+ if (server.listening) {
+ server.close();
+ }
+ deferred.reject(new CancellationError());
+ });
+ }
+ deferred.resolve(combined);
+ return deferred.promise;
+ }
+ // mac/linux implementation of FIFO
+ await mkfifo(pipeName);
+ try {
+ await fs.chmod(pipeName, 0o666);
+ } catch {
+ // Intentionally ignored
+ }
+ const fd = await fs.open(pipeName, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK);
+ const socket = new net.Socket({ fd });
+ const reader = new rpc.SocketMessageReader(socket, 'utf-8');
+ socket.on('close', () => {
+ fs.close(fd).catch(noop);
+ reader.dispose();
+ });
+
+ return reader;
+}
diff --git a/src/client/common/platform/fileSystem.ts b/src/client/common/platform/fileSystem.ts
index 8f962b0f776f..3e7f441654ec 100644
--- a/src/client/common/platform/fileSystem.ts
+++ b/src/client/common/platform/fileSystem.ts
@@ -333,7 +333,7 @@ export class FileSystemUtils implements IFileSystemUtils {
pathUtils.paths,
tmp || TemporaryFileSystem.withDefaults(),
getHash || getHashString,
- globFiles || promisify(glob),
+ globFiles || promisify(glob.default),
);
}
diff --git a/src/client/common/platform/fs-paths.ts b/src/client/common/platform/fs-paths.ts
index 17df7507f7d9..fa809d31b0b9 100644
--- a/src/client/common/platform/fs-paths.ts
+++ b/src/client/common/platform/fs-paths.ts
@@ -4,11 +4,10 @@
import * as nodepath from 'path';
import { getSearchPathEnvVarNames } from '../utils/exec';
import * as fs from 'fs-extra';
+import * as os from 'os';
import { getOSType, OSType } from '../utils/platform';
import { IExecutables, IFileSystemPaths, IFileSystemPathUtils } from './types';
-const untildify = require('untildify');
-
// The parts of node's 'path' module used by FileSystemPaths.
interface INodePath {
sep: string;
@@ -120,7 +119,7 @@ export class FileSystemPathUtils implements IFileSystemPathUtils {
}
return new FileSystemPathUtils(
// Use the current user's home directory.
- untildify('~'),
+ os.homedir(),
paths,
Executables.withDefaults(),
// Use the actual node "path" module.
@@ -183,6 +182,105 @@ export async function copyFile(src: string, dest: string): Promise {
});
}
+// These function exist so we can stub them out in tests. We can't stub out the fs module directly
+// because of the way that sinon does stubbing, so we have these intermediaries instead.
+export { Stats, WriteStream, ReadStream, PathLike, Dirent, PathOrFileDescriptor } from 'fs-extra';
+
+export function existsSync(path: string): boolean {
+ return fs.existsSync(path);
+}
+
+export function readFileSync(filePath: string, encoding: BufferEncoding): string;
+export function readFileSync(filePath: string): Buffer;
+export function readFileSync(filePath: string, options: { encoding: BufferEncoding }): string;
+export function readFileSync(
+ filePath: string,
+ options?: { encoding: BufferEncoding } | BufferEncoding | undefined,
+): string | Buffer {
+ if (typeof options === 'string') {
+ return fs.readFileSync(filePath, { encoding: options });
+ }
+ return fs.readFileSync(filePath, options);
+}
+
+export function readJSONSync(filePath: string): any {
+ return fs.readJSONSync(filePath);
+}
+
+export function readdirSync(path: string): string[];
+export function readdirSync(
+ path: string,
+ options: fs.ObjectEncodingOptions & {
+ withFileTypes: true;
+ },
+): fs.Dirent[];
+export function readdirSync(
+ path: string,
+ options: fs.ObjectEncodingOptions & {
+ withFileTypes: false;
+ },
+): string[];
+export function readdirSync(
+ path: fs.PathLike,
+ options?: fs.ObjectEncodingOptions & {
+ withFileTypes: boolean;
+ recursive?: boolean | undefined;
+ },
+): string[] | fs.Dirent[] {
+ if (options === undefined || options.withFileTypes === false) {
+ return fs.readdirSync(path);
+ }
+ return fs.readdirSync(path, { ...options, withFileTypes: true });
+}
+
+export function readlink(path: string): Promise {
+ return fs.readlink(path);
+}
+
+export function unlink(path: string): Promise {
+ return fs.unlink(path);
+}
+
+export function symlink(target: string, path: string, type?: fs.SymlinkType): Promise {
+ return fs.symlink(target, path, type);
+}
+
+export function symlinkSync(target: string, path: string, type?: fs.SymlinkType): void {
+ return fs.symlinkSync(target, path, type);
+}
+
+export function unlinkSync(path: string): void {
+ return fs.unlinkSync(path);
+}
+
+export function statSync(path: string): fs.Stats {
+ return fs.statSync(path);
+}
+
+export function stat(path: string): Promise {
+ return fs.stat(path);
+}
+
+export function lstat(path: string): Promise {
+ return fs.lstat(path);
+}
+
+export function chmod(path: string, mod: fs.Mode): Promise {
+ return fs.chmod(path, mod);
+}
+
+export function createReadStream(path: string): fs.ReadStream {
+ return fs.createReadStream(path);
+}
+
+export function createWriteStream(path: string): fs.WriteStream {
+ return fs.createWriteStream(path);
+}
+
+export function pathExistsSync(path: string): boolean {
+ return fs.pathExistsSync(path);
+}
+
export function pathExists(absPath: string): Promise {
return fs.pathExists(absPath);
}
@@ -190,3 +288,83 @@ export function pathExists(absPath: string): Promise {
export function createFile(filename: string): Promise {
return fs.createFile(filename);
}
+
+export function rmdir(path: string, options?: fs.RmDirOptions): Promise {
+ return fs.rmdir(path, options);
+}
+
+export function remove(path: string): Promise {
+ return fs.remove(path);
+}
+
+export function readFile(filePath: string, encoding: BufferEncoding): Promise;
+export function readFile(filePath: string): Promise;
+export function readFile(filePath: string, options: { encoding: BufferEncoding }): Promise;
+export function readFile(
+ filePath: string,
+ options?: { encoding: BufferEncoding } | BufferEncoding | undefined,
+): Promise {
+ if (typeof options === 'string') {
+ return fs.readFile(filePath, { encoding: options });
+ }
+ return fs.readFile(filePath, options);
+}
+
+export function readJson(filePath: string): Promise {
+ return fs.readJson(filePath);
+}
+
+export function writeFile(filePath: string, data: any, options?: { encoding: BufferEncoding }): Promise {
+ return fs.writeFile(filePath, data, options);
+}
+
+export function mkdir(dirPath: string): Promise {
+ return fs.mkdir(dirPath);
+}
+
+export function mkdirp(dirPath: string): Promise {
+ return fs.mkdirp(dirPath);
+}
+
+export function rename(oldPath: string, newPath: string): Promise {
+ return fs.rename(oldPath, newPath);
+}
+
+export function ensureDir(dirPath: string): Promise {
+ return fs.ensureDir(dirPath);
+}
+
+export function ensureFile(filePath: string): Promise {
+ return fs.ensureFile(filePath);
+}
+
+export function ensureSymlink(target: string, filePath: string, type?: fs.SymlinkType): Promise {
+ return fs.ensureSymlink(target, filePath, type);
+}
+
+export function appendFile(filePath: string, data: any, options?: { encoding: BufferEncoding }): Promise {
+ return fs.appendFile(filePath, data, options);
+}
+
+export function readdir(path: string): Promise;
+export function readdir(
+ path: string,
+ options: fs.ObjectEncodingOptions & {
+ withFileTypes: true;
+ },
+): Promise;
+export function readdir(
+ path: fs.PathLike,
+ options?: fs.ObjectEncodingOptions & {
+ withFileTypes: true;
+ },
+): Promise {
+ if (options === undefined) {
+ return fs.readdir(path);
+ }
+ return fs.readdir(path, options);
+}
+
+export function emptyDir(dirPath: string): Promise {
+ return fs.emptyDir(dirPath);
+}
diff --git a/src/client/common/platform/fs-temp.ts b/src/client/common/platform/fs-temp.ts
index 32b57df15387..60dde040f454 100644
--- a/src/client/common/platform/fs-temp.ts
+++ b/src/client/common/platform/fs-temp.ts
@@ -5,14 +5,7 @@ import * as tmp from 'tmp';
import { ITempFileSystem, TemporaryFile } from './types';
interface IRawTempFS {
- // TODO (https://github.com/microsoft/vscode/issues/84517)
- // This functionality has been requested for the
- // VS Code FS API (vscode.workspace.fs.*).
- file(
- config: tmp.Options,
-
- callback?: (err: any, path: string, fd: number, cleanupCallback: () => void) => void,
- ): void;
+ fileSync(config?: tmp.Options): tmp.SynchrounousResult;
}
// Operations related to temporary files and directories.
@@ -35,14 +28,13 @@ export class TemporaryFileSystem implements ITempFileSystem {
mode,
};
return new Promise((resolve, reject) => {
- this.raw.file(opts, (err, filename, _fd, cleanUp) => {
- if (err) {
- return reject(err);
- }
- resolve({
- filePath: filename,
- dispose: cleanUp,
- });
+ const { name, removeCallback } = this.raw.fileSync(opts);
+ if (!name) {
+ return reject(new Error('Failed to create temp file'));
+ }
+ resolve({
+ filePath: name,
+ dispose: removeCallback,
});
});
}
diff --git a/src/client/common/platform/pathUtils.ts b/src/client/common/platform/pathUtils.ts
index ed3dc28b1de5..b3be39f4644b 100644
--- a/src/client/common/platform/pathUtils.ts
+++ b/src/client/common/platform/pathUtils.ts
@@ -6,8 +6,7 @@ import * as path from 'path';
import { IPathUtils, IsWindows } from '../types';
import { OSType } from '../utils/platform';
import { Executables, FileSystemPaths, FileSystemPathUtils } from './fs-paths';
-
-const untildify = require('untildify');
+import { untildify } from '../helpers';
@injectable()
export class PathUtils implements IPathUtils {
diff --git a/src/client/common/platform/platformService.ts b/src/client/common/platform/platformService.ts
index aa139eeeebc0..dc9b04cc652c 100644
--- a/src/client/common/platform/platformService.ts
+++ b/src/client/common/platform/platformService.ts
@@ -7,7 +7,7 @@ import { injectable } from 'inversify';
import * as os from 'os';
import { coerce, SemVer } from 'semver';
import { getSearchPathEnvVarNames } from '../utils/exec';
-import { Architecture, getArchitecture, getOSType, OSType } from '../utils/platform';
+import { Architecture, getArchitecture, getOSType, isWindows, OSType } from '../utils/platform';
import { parseSemVerSafe } from '../utils/version';
import { IPlatformService } from './types';
@@ -73,7 +73,3 @@ export class PlatformService implements IPlatformService {
return getArchitecture() === Architecture.x64;
}
}
-
-export function isWindows(): boolean {
- return getOSType() === OSType.Windows;
-}
diff --git a/src/client/common/process/internal/scripts/constants.ts b/src/client/common/process/internal/scripts/constants.ts
index 4448f7e639ce..6954592ed3dd 100644
--- a/src/client/common/process/internal/scripts/constants.ts
+++ b/src/client/common/process/internal/scripts/constants.ts
@@ -5,4 +5,4 @@ import * as path from 'path';
import { EXTENSION_ROOT_DIR } from '../../../constants';
// It is simpler to hard-code it instead of using vscode.ExtensionContext.extensionPath.
-export const _SCRIPTS_DIR = path.join(EXTENSION_ROOT_DIR, 'pythonFiles');
+export const _SCRIPTS_DIR = path.join(EXTENSION_ROOT_DIR, 'python_files');
diff --git a/src/client/common/process/internal/scripts/index.ts b/src/client/common/process/internal/scripts/index.ts
index 2644fd0d00ff..f2c905c02889 100644
--- a/src/client/common/process/internal/scripts/index.ts
+++ b/src/client/common/process/internal/scripts/index.ts
@@ -7,7 +7,7 @@ import { _SCRIPTS_DIR } from './constants';
const SCRIPTS_DIR = _SCRIPTS_DIR;
// "scripts" contains everything relevant to the scripts found under
-// the top-level "pythonFiles" directory. Each of those scripts has
+// the top-level "python_files" directory. Each of those scripts has
// a function in this module which matches the script's filename.
// Each function provides the commandline arguments that should be
// used when invoking a Python executable, whether through spawn/exec
@@ -18,7 +18,7 @@ const SCRIPTS_DIR = _SCRIPTS_DIR;
// into the corresponding object or objects. "parse()" takes a single
// string as the stdout text and returns the relevant data.
//
-// Some of the scripts are located in subdirectories of "pythonFiles".
+// Some of the scripts are located in subdirectories of "python_files".
// For each of those subdirectories there is a sub-module where
// those scripts' functions may be found.
//
diff --git a/src/client/common/process/logger.ts b/src/client/common/process/logger.ts
index 1c0b78dd941f..b65da8dc81e5 100644
--- a/src/client/common/process/logger.ts
+++ b/src/client/common/process/logger.ts
@@ -12,6 +12,7 @@ import { IProcessLogger, SpawnOptions } from './types';
import { escapeRegExp } from 'lodash';
import { replaceAll } from '../stringUtils';
import { identifyShellFromShellPath } from '../terminal/shellDetectors/baseShellDetector';
+import '../../common/extensions';
@injectable()
export class ProcessLogger implements IProcessLogger {
@@ -40,6 +41,13 @@ export class ProcessLogger implements IProcessLogger {
});
}
+ /**
+ * Formats command strings for display by replacing common paths with symbols.
+ * - Replaces the workspace folder path with '.' if there's exactly one workspace folder
+ * - Replaces the user's home directory path with '~'
+ * @param command The command string to format
+ * @returns The formatted command string with paths replaced by symbols
+ */
private getDisplayCommands(command: string): string {
if (this.workspaceService.workspaceFolders && this.workspaceService.workspaceFolders.length === 1) {
command = replaceMatchesWithCharacter(command, this.workspaceService.workspaceFolders[0].uri.fsPath, '.');
diff --git a/src/client/common/process/pythonEnvironment.ts b/src/client/common/process/pythonEnvironment.ts
index 9566f373aa91..cbf898ac5f50 100644
--- a/src/client/common/process/pythonEnvironment.ts
+++ b/src/client/common/process/pythonEnvironment.ts
@@ -12,6 +12,7 @@ import { isTestExecution } from '../constants';
import { IFileSystem } from '../platform/types';
import * as internalPython from './internal/python';
import { ExecutionResult, IProcessService, IPythonEnvironment, ShellOptions, SpawnOptions } from './types';
+import { PixiEnvironmentInfo } from '../../pythonEnvironments/common/environmentManagers/pixi';
const cachedExecutablePath: Map> = new Map>();
@@ -173,6 +174,23 @@ export async function createCondaEnv(
return new PythonEnvironment(interpreterPath, deps);
}
+export async function createPixiEnv(
+ pixiEnv: PixiEnvironmentInfo,
+ // These are used to generate the deps.
+ procs: IProcessService,
+ fs: IFileSystem,
+): Promise {
+ const pythonArgv = pixiEnv.pixi.getRunPythonArgs(pixiEnv.manifestPath, pixiEnv.envName);
+ const deps = createDeps(
+ async (filename) => fs.pathExists(filename),
+ pythonArgv,
+ pythonArgv,
+ (file, args, opts) => procs.exec(file, args, opts),
+ (command, opts) => procs.shellExec(command, opts),
+ );
+ return new PythonEnvironment(pixiEnv.interpreterPath, deps);
+}
+
export function createMicrosoftStoreEnv(
pythonPath: string,
// These are used to generate the deps.
diff --git a/src/client/common/process/pythonExecutionFactory.ts b/src/client/common/process/pythonExecutionFactory.ts
index fc13e7f2346c..efb05c3c9d12 100644
--- a/src/client/common/process/pythonExecutionFactory.ts
+++ b/src/client/common/process/pythonExecutionFactory.ts
@@ -10,7 +10,7 @@ import { EventName } from '../../telemetry/constants';
import { IFileSystem } from '../platform/types';
import { IConfigurationService, IDisposableRegistry, IInterpreterPathService } from '../types';
import { ProcessService } from './proc';
-import { createCondaEnv, createPythonEnv, createMicrosoftStoreEnv } from './pythonEnvironment';
+import { createCondaEnv, createPythonEnv, createMicrosoftStoreEnv, createPixiEnv } from './pythonEnvironment';
import { createPythonProcessService } from './pythonProcess';
import {
ExecutionFactoryCreateWithEnvironmentOptions,
@@ -25,6 +25,7 @@ import {
import { IInterpreterAutoSelectionService } from '../../interpreter/autoSelection/types';
import { sleep } from '../utils/async';
import { traceError } from '../../logging';
+import { getPixi, getPixiEnvironmentFromInterpreter } from '../../pythonEnvironments/common/environmentManagers/pixi';
@injectable()
export class PythonExecutionFactory implements IPythonExecutionFactory {
@@ -79,6 +80,13 @@ export class PythonExecutionFactory implements IPythonExecutionFactory {
}
const processService: IProcessService = await this.processServiceFactory.create(options.resource);
+ if (await getPixi()) {
+ const pixiExecutionService = await this.createPixiExecutionService(pythonPath, processService);
+ if (pixiExecutionService) {
+ return pixiExecutionService;
+ }
+ }
+
const condaExecutionService = await this.createCondaExecutionService(pythonPath, processService);
if (condaExecutionService) {
return condaExecutionService;
@@ -116,10 +124,18 @@ export class PythonExecutionFactory implements IPythonExecutionFactory {
processService.on('exec', this.logger.logProcess.bind(this.logger));
this.disposables.push(processService);
+ if (await getPixi()) {
+ const pixiExecutionService = await this.createPixiExecutionService(pythonPath, processService);
+ if (pixiExecutionService) {
+ return pixiExecutionService;
+ }
+ }
+
const condaExecutionService = await this.createCondaExecutionService(pythonPath, processService);
if (condaExecutionService) {
return condaExecutionService;
}
+
const env = createPythonEnv(pythonPath, processService, this.fileSystem);
return createPythonService(processService, env);
}
@@ -139,6 +155,23 @@ export class PythonExecutionFactory implements IPythonExecutionFactory {
}
return createPythonService(processService, env);
}
+
+ public async createPixiExecutionService(
+ pythonPath: string,
+ processService: IProcessService,
+ ): Promise {
+ const pixiEnvironment = await getPixiEnvironmentFromInterpreter(pythonPath);
+ if (!pixiEnvironment) {
+ return undefined;
+ }
+
+ const env = await createPixiEnv(pixiEnvironment, processService, this.fileSystem);
+ if (env) {
+ return createPythonService(processService, env);
+ }
+
+ return undefined;
+ }
}
function createPythonService(procService: IProcessService, env: IPythonEnvironment): IPythonExecutionService {
diff --git a/src/client/common/process/rawProcessApis.ts b/src/client/common/process/rawProcessApis.ts
index 5e3641328b69..864191851c91 100644
--- a/src/client/common/process/rawProcessApis.ts
+++ b/src/client/common/process/rawProcessApis.ts
@@ -58,7 +58,8 @@ export function shellExec(
const shellOptions = getDefaultOptions(options, defaultEnv);
if (!options.doNotLog) {
const processLogger = new ProcessLogger(new WorkspaceService());
- processLogger.logProcess(command, undefined, shellOptions);
+ const loggingOptions = { ...shellOptions, encoding: shellOptions.encoding ?? undefined };
+ processLogger.logProcess(command, undefined, loggingOptions);
}
return new Promise((resolve, reject) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
diff --git a/src/client/common/process/worker/workerRawProcessApis.ts b/src/client/common/process/worker/workerRawProcessApis.ts
index 5b04aaa40b0a..cfae9b1e6471 100644
--- a/src/client/common/process/worker/workerRawProcessApis.ts
+++ b/src/client/common/process/worker/workerRawProcessApis.ts
@@ -17,6 +17,7 @@ import {
StdErrError,
ExecutionResult,
} from './types';
+import { traceWarn } from '../../../logging';
const PS_ERROR_SCREEN_BOGUS = /your [0-9]+x[0-9]+ screen size is bogus\. expect trouble/;
@@ -208,6 +209,6 @@ function killPid(pid: number): void {
process.kill(pid);
}
} catch {
- console.warn('Unable to kill process with pid', pid);
+ traceWarn('Unable to kill process with pid', pid);
}
}
diff --git a/src/client/common/serviceRegistry.ts b/src/client/common/serviceRegistry.ts
index 8c872c3113ba..abd2b220e400 100644
--- a/src/client/common/serviceRegistry.ts
+++ b/src/client/common/serviceRegistry.ts
@@ -28,7 +28,6 @@ import { CommandManager } from './application/commandManager';
import { ReloadVSCodeCommandHandler } from './application/commands/reloadCommand';
import { ReportIssueCommandHandler } from './application/commands/reportIssueCommand';
import { DebugService } from './application/debugService';
-import { DebugSessionTelemetry } from './application/debugSessionTelemetry';
import { DocumentManager } from './application/documentManager';
import { Extensions } from './application/extensions';
import { LanguageService } from './application/languageService';
@@ -88,7 +87,8 @@ import { Random } from './utils/random';
import { ContextKeyManager } from './application/contextKeyManager';
import { CreatePythonFileCommandHandler } from './application/commands/createPythonFile';
import { RequireJupyterPrompt } from '../jupyter/requireJupyterPrompt';
-import { isWindows } from './platform/platformService';
+import { isWindows } from './utils/platform';
+import { PixiActivationCommandProvider } from './terminal/environmentActivationProviders/pixiActivationProvider';
export function registerTypes(serviceManager: IServiceManager): void {
serviceManager.addSingletonInstance(IsWindows, isWindows());
@@ -161,6 +161,11 @@ export function registerTypes(serviceManager: IServiceManager): void {
CondaActivationCommandProvider,
TerminalActivationProviders.conda,
);
+ serviceManager.addSingleton(
+ ITerminalActivationCommandProvider,
+ PixiActivationCommandProvider,
+ TerminalActivationProviders.pixi,
+ );
serviceManager.addSingleton(
ITerminalActivationCommandProvider,
PipEnvActivationCommandProvider,
@@ -183,8 +188,4 @@ export function registerTypes(serviceManager: IServiceManager): void {
IExtensionSingleActivationService,
ReportIssueCommandHandler,
);
- serviceManager.addSingleton(
- IExtensionSingleActivationService,
- DebugSessionTelemetry,
- );
}
diff --git a/src/client/common/terminal/activator/index.ts b/src/client/common/terminal/activator/index.ts
index 1c2cf4041585..cde04bdbf10d 100644
--- a/src/client/common/terminal/activator/index.ts
+++ b/src/client/common/terminal/activator/index.ts
@@ -9,6 +9,9 @@ import { IConfigurationService, IExperimentService } from '../../types';
import { ITerminalActivationHandler, ITerminalActivator, ITerminalHelper, TerminalActivationOptions } from '../types';
import { BaseTerminalActivator } from './base';
import { inTerminalEnvVarExperiment } from '../../experiments/helpers';
+import { shouldEnvExtHandleActivation } from '../../../envExt/api.internal';
+import { EventName } from '../../../telemetry/constants';
+import { sendTelemetryEvent } from '../../../telemetry';
@injectable()
export class TerminalActivator implements ITerminalActivator {
@@ -41,7 +44,10 @@ export class TerminalActivator implements ITerminalActivator {
const settings = this.configurationService.getSettings(options?.resource);
const activateEnvironment =
settings.terminal.activateEnvironment && !inTerminalEnvVarExperiment(this.experimentService);
- if (!activateEnvironment || options?.hideFromUser) {
+ if (!activateEnvironment || options?.hideFromUser || shouldEnvExtHandleActivation()) {
+ if (shouldEnvExtHandleActivation()) {
+ sendTelemetryEvent(EventName.PYTHON_INTERPRETER_ACTIVATION_FOR_TERMINAL);
+ }
return false;
}
diff --git a/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts b/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts
index d209550e04a4..42bb8f38fc9e 100644
--- a/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts
+++ b/src/client/common/terminal/environmentActivationProviders/condaActivationProvider.ts
@@ -8,6 +8,7 @@ import '../../extensions';
import { inject, injectable } from 'inversify';
import * as path from 'path';
import { Uri } from 'vscode';
+import { traceInfo, traceVerbose, traceWarn } from '../../../logging';
import { IComponentAdapter, ICondaService } from '../../../interpreter/contracts';
import { IPlatformService } from '../../platform/types';
@@ -53,16 +54,21 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
pythonPath: string,
targetShell: TerminalShellType,
): Promise {
+ traceVerbose(`Getting conda activation commands for interpreter ${pythonPath} with shell ${targetShell}`);
const envInfo = await this.pyenvs.getCondaEnvironment(pythonPath);
if (!envInfo) {
+ traceWarn(`No conda environment found for interpreter ${pythonPath}`);
return undefined;
}
+ traceVerbose(`Found conda environment: ${JSON.stringify(envInfo)}`);
const condaEnv = envInfo.name.length > 0 ? envInfo.name : envInfo.path;
// New version.
const interpreterPath = await this.condaService.getInterpreterPathForEnvironment(envInfo);
+ traceInfo(`Using interpreter path: ${interpreterPath}`);
const activatePath = await this.condaService.getActivationScriptFromInterpreter(interpreterPath, envInfo.name);
+ traceVerbose(`Got activation script: ${activatePath?.path}} with type: ${activatePath?.type}`);
// eslint-disable-next-line camelcase
if (activatePath?.path) {
if (
@@ -70,11 +76,14 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
targetShell !== TerminalShellType.bash &&
targetShell !== TerminalShellType.gitbash
) {
- return [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
+ const commands = [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
+ traceInfo(`Using Windows-specific commands: ${commands.join(', ')}`);
+ return commands;
}
const condaInfo = await this.condaService.getCondaInfo();
+ traceVerbose(`Conda shell level: ${condaInfo?.conda_shlvl}`);
if (
activatePath.type !== 'global' ||
// eslint-disable-next-line camelcase
@@ -84,27 +93,36 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
// activatePath is not the global activate path, or we don't have a shlvl, or it's -1οΌconda never sourcedοΌ.
// and we need to source the activate path.
if (activatePath.path === 'activate') {
- return [
+ const commands = [
`source ${activatePath.path}`,
`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`,
];
+ traceInfo(`Using source activate commands: ${commands.join(', ')}`);
+ return commands;
}
- return [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonExt()}`];
+ const command = [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonExt()}`];
+ traceInfo(`Using single source command: ${command}`);
+ return command;
}
- return [`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
+ const command = [`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
+ traceInfo(`Using direct conda activate command: ${command}`);
+ return command;
}
switch (targetShell) {
case TerminalShellType.powershell:
case TerminalShellType.powershellCore:
+ traceVerbose('Using PowerShell-specific activation');
return _getPowershellCommands(condaEnv);
// TODO: Do we really special-case fish on Windows?
case TerminalShellType.fish:
+ traceVerbose('Using Fish shell-specific activation');
return getFishCommands(condaEnv, await this.condaService.getCondaFile());
default:
if (this.platform.isWindows) {
+ traceVerbose('Using Windows shell-specific activation fallback option.');
return this.getWindowsCommands(condaEnv);
}
return getUnixCommands(condaEnv, await this.condaService.getCondaFile());
diff --git a/src/client/common/terminal/environmentActivationProviders/pixiActivationProvider.ts b/src/client/common/terminal/environmentActivationProviders/pixiActivationProvider.ts
new file mode 100644
index 000000000000..1deaa56dd8ae
--- /dev/null
+++ b/src/client/common/terminal/environmentActivationProviders/pixiActivationProvider.ts
@@ -0,0 +1,77 @@
+/* eslint-disable class-methods-use-this */
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+'use strict';
+
+import { inject, injectable } from 'inversify';
+import { Uri } from 'vscode';
+import { IInterpreterService } from '../../../interpreter/contracts';
+import { ITerminalActivationCommandProvider, TerminalShellType } from '../types';
+import { getPixiActivationCommands } from '../../../pythonEnvironments/common/environmentManagers/pixi';
+
+@injectable()
+export class PixiActivationCommandProvider implements ITerminalActivationCommandProvider {
+ constructor(@inject(IInterpreterService) private readonly interpreterService: IInterpreterService) {}
+
+ // eslint-disable-next-line class-methods-use-this
+ public isShellSupported(targetShell: TerminalShellType): boolean {
+ return shellTypeToPixiShell(targetShell) !== undefined;
+ }
+
+ public async getActivationCommands(
+ resource: Uri | undefined,
+ targetShell: TerminalShellType,
+ ): Promise {
+ const interpreter = await this.interpreterService.getActiveInterpreter(resource);
+ if (!interpreter) {
+ return undefined;
+ }
+
+ return this.getActivationCommandsForInterpreter(interpreter.path, targetShell);
+ }
+
+ public getActivationCommandsForInterpreter(
+ pythonPath: string,
+ targetShell: TerminalShellType,
+ ): Promise {
+ return getPixiActivationCommands(pythonPath, targetShell);
+ }
+}
+
+/**
+ * Returns the name of a terminal shell type within Pixi.
+ */
+function shellTypeToPixiShell(targetShell: TerminalShellType): string | undefined {
+ switch (targetShell) {
+ case TerminalShellType.powershell:
+ case TerminalShellType.powershellCore:
+ return 'powershell';
+ case TerminalShellType.commandPrompt:
+ return 'cmd';
+
+ case TerminalShellType.zsh:
+ return 'zsh';
+
+ case TerminalShellType.fish:
+ return 'fish';
+
+ case TerminalShellType.nushell:
+ return 'nushell';
+
+ case TerminalShellType.xonsh:
+ return 'xonsh';
+
+ case TerminalShellType.cshell:
+ // Explicitly unsupported
+ return undefined;
+
+ case TerminalShellType.gitbash:
+ case TerminalShellType.bash:
+ case TerminalShellType.wsl:
+ case TerminalShellType.tcshell:
+ case TerminalShellType.other:
+ default:
+ return 'bash';
+ }
+}
diff --git a/src/client/common/terminal/helper.ts b/src/client/common/terminal/helper.ts
index f1a89df10786..d2b3bb7879af 100644
--- a/src/client/common/terminal/helper.ts
+++ b/src/client/common/terminal/helper.ts
@@ -22,6 +22,7 @@ import {
TerminalActivationProviders,
TerminalShellType,
} from './types';
+import { isPixiEnvironment } from '../../pythonEnvironments/common/environmentManagers/pixi';
@injectable()
export class TerminalHelper implements ITerminalHelper {
@@ -50,6 +51,9 @@ export class TerminalHelper implements ITerminalHelper {
@inject(ITerminalActivationCommandProvider)
@named(TerminalActivationProviders.pipenv)
private readonly pipenv: ITerminalActivationCommandProvider,
+ @inject(ITerminalActivationCommandProvider)
+ @named(TerminalActivationProviders.pixi)
+ private readonly pixi: ITerminalActivationCommandProvider,
@multiInject(IShellDetector) shellDetectors: IShellDetector[],
) {
this.shellDetector = new ShellDetector(this.platform, shellDetectors);
@@ -75,7 +79,14 @@ export class TerminalHelper implements ITerminalHelper {
resource?: Uri,
interpreter?: PythonEnvironment,
): Promise {
- const providers = [this.pipenv, this.pyenv, this.bashCShellFish, this.commandPromptAndPowerShell, this.nushell];
+ const providers = [
+ this.pixi,
+ this.pipenv,
+ this.pyenv,
+ this.bashCShellFish,
+ this.commandPromptAndPowerShell,
+ this.nushell,
+ ];
const promise = this.getActivationCommands(resource || undefined, interpreter, terminalShellType, providers);
this.sendTelemetry(
terminalShellType,
@@ -93,7 +104,7 @@ export class TerminalHelper implements ITerminalHelper {
if (this.platform.osType === OSType.Unknown) {
return;
}
- const providers = [this.bashCShellFish, this.commandPromptAndPowerShell, this.nushell];
+ const providers = [this.pixi, this.bashCShellFish, this.commandPromptAndPowerShell, this.nushell];
const promise = this.getActivationCommands(resource, interpreter, shell, providers);
this.sendTelemetry(
shell,
@@ -133,6 +144,19 @@ export class TerminalHelper implements ITerminalHelper {
): Promise {
const settings = this.configurationService.getSettings(resource);
+ const isPixiEnv = interpreter
+ ? interpreter.envType === EnvironmentType.Pixi
+ : await isPixiEnvironment(settings.pythonPath);
+ if (isPixiEnv) {
+ const activationCommands = interpreter
+ ? await this.pixi.getActivationCommandsForInterpreter(interpreter.path, terminalShellType)
+ : await this.pixi.getActivationCommands(resource, terminalShellType);
+
+ if (Array.isArray(activationCommands)) {
+ return activationCommands;
+ }
+ }
+
const condaService = this.serviceContainer.get(IComponentAdapter);
// If we have a conda environment, then use that.
const isCondaEnvironment = interpreter
diff --git a/src/client/common/terminal/service.ts b/src/client/common/terminal/service.ts
index cf63603a2e9b..0dffd5615ae1 100644
--- a/src/client/common/terminal/service.ts
+++ b/src/client/common/terminal/service.ts
@@ -2,16 +2,14 @@
// Licensed under the MIT License.
import { inject, injectable } from 'inversify';
-import * as path from 'path';
-import { CancellationToken, Disposable, Event, EventEmitter, Terminal } from 'vscode';
+import { CancellationToken, Disposable, Event, EventEmitter, Terminal, TerminalShellExecution } from 'vscode';
import '../../common/extensions';
import { IInterpreterService } from '../../interpreter/contracts';
import { IServiceContainer } from '../../ioc/types';
import { captureTelemetry } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
import { ITerminalAutoActivation } from '../../terminals/types';
-import { ITerminalManager } from '../application/types';
-import { EXTENSION_ROOT_DIR } from '../constants';
+import { IApplicationShell, ITerminalManager } from '../application/types';
import { _SCRIPTS_DIR } from '../process/internal/scripts/constants';
import { IConfigurationService, IDisposableRegistry } from '../types';
import {
@@ -21,6 +19,10 @@ import {
TerminalCreationOptions,
TerminalShellType,
} from './types';
+import { traceVerbose } from '../../logging';
+import { sleep } from '../utils/async';
+import { useEnvExtension } from '../../envExt/api.internal';
+import { ensureTerminalLegacy } from '../../envExt/api.legacy';
@injectable()
export class TerminalService implements ITerminalService, Disposable {
@@ -31,10 +33,17 @@ export class TerminalService implements ITerminalService, Disposable {
private terminalHelper: ITerminalHelper;
private terminalActivator: ITerminalActivator;
private terminalAutoActivator: ITerminalAutoActivation;
- private readonly envVarScript = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'pythonrc.py');
+ private applicationShell: IApplicationShell;
+ private readonly executeCommandListeners: Set = new Set();
+ private _terminalFirstLaunched: boolean = true;
+ private pythonReplCommandQueue: string[] = [];
+ private isReplReady: boolean = false;
+ private replPromptListener?: Disposable;
+ private replShellTypeListener?: Disposable;
public get onDidCloseTerminal(): Event {
return this.terminalClosed.event.bind(this.terminalClosed);
}
+
constructor(
@inject(IServiceContainer) private serviceContainer: IServiceContainer,
private readonly options?: TerminalCreationOptions,
@@ -44,12 +53,18 @@ export class TerminalService implements ITerminalService, Disposable {
this.terminalHelper = this.serviceContainer.get(ITerminalHelper);
this.terminalManager = this.serviceContainer.get