From 47a174518017f17fa9354391046f6fabe03f0202 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Tue, 18 Apr 2023 21:44:05 -0700 Subject: [PATCH] Revert "Merge from vscode merge-base (#22769)" (#22779) This reverts commit 6bd0a17d3c038f120c0b8d6b1babd32c5d378624. --- .eslintrc.json | 2 - .github/pull_request_template.md | 2 + .github/workflows/bad-tag.yml | 22 - .github/workflows/basic.yml | 177 - .github/workflows/ci.yml | 118 +- .github/workflows/pr-chat.yml | 26 - .nvmrc | 1 - .vscode/extensions.json | 2 +- .vscode/launch.json | 185 +- .vscode/notebooks/api.github-issues | 2 +- .vscode/notebooks/endgame.github-issues | 2 +- .vscode/notebooks/inbox.github-issues | 2 +- .vscode/notebooks/my-endgame.github-issues | 4 +- .vscode/notebooks/my-work.github-issues | 4 +- .vscode/notebooks/verification.github-issues | 2 +- .vscode/notebooks/vscode-dev.github-issues | 8 +- .vscode/settings.json | 7 - ThirdPartyNotices.txt | 1088 +-- build/.cachesalt | 2 +- build/.gitignore | 1 - build/.moduleignore | 8 - .../common/computeNodeModulesCacheKey.js | 4 +- .../common/computeNodeModulesCacheKey.ts | 4 +- build/azure-pipelines/common/createAsset.js | 2 +- build/azure-pipelines/common/createAsset.ts | 2 + build/azure-pipelines/common/createBuild.js | 2 +- build/azure-pipelines/common/createBuild.ts | 2 + .../azure-pipelines/common/listNodeModules.js | 2 +- .../azure-pipelines/common/listNodeModules.ts | 2 + build/azure-pipelines/common/releaseBuild.js | 2 +- build/azure-pipelines/common/releaseBuild.ts | 2 + build/azure-pipelines/common/retry.js | 2 +- build/azure-pipelines/common/retry.ts | 2 + .../darwin/product-build-darwin-sign.yml | 47 +- .../darwin/product-build-darwin-test.yml | 435 +- .../darwin/product-build-darwin-universal.yml | 44 - .../darwin/product-build-darwin.yml | 319 +- .../darwin/sql-product-build-darwin.yml | 25 +- build/azure-pipelines/distro-build.yml | 4 +- .../linux/product-build-alpine.yml | 4 +- .../linux/product-build-linux-client-test.yml | 272 - .../linux/product-build-linux-client.yml | 528 +- .../linux/product-build-linux-server.yml | 103 +- .../linux/sql-product-build-linux.yml | 92 +- build/azure-pipelines/mixin.js | 2 +- build/azure-pipelines/mixin.ts | 2 + .../product-build-pr-cache.yml | 59 - build/azure-pipelines/product-build-pr.yml | 189 - build/azure-pipelines/product-build.yml | 242 +- build/azure-pipelines/product-compile.yml | 177 +- build/azure-pipelines/product-publish.ps1 | 1 - build/azure-pipelines/product-publish.yml | 1 - .../publish-types/check-version.js | 2 +- .../publish-types/check-version.ts | 2 + .../publish-types/update-types.js | 2 +- .../publish-types/update-types.ts | 2 + build/azure-pipelines/upload-cdn.js | 2 +- build/azure-pipelines/upload-cdn.ts | 2 + build/azure-pipelines/upload-configuration.js | 4 +- build/azure-pipelines/upload-configuration.ts | 4 +- build/azure-pipelines/upload-nlsmetadata.js | 12 +- build/azure-pipelines/upload-nlsmetadata.ts | 14 +- build/azure-pipelines/upload-sourcemaps.js | 2 +- build/azure-pipelines/upload-sourcemaps.ts | 2 + .../azure-pipelines/web/product-build-web.yml | 1 - .../win32/product-build-win32-test.yml | 247 - .../win32/product-build-win32.yml | 521 +- build/darwin/create-universal-app.js | 4 +- build/darwin/create-universal-app.ts | 4 +- build/darwin/sign.js | 2 +- build/darwin/sign.ts | 2 + build/filters.js | 2 + build/gulpfile.editor.js | 57 +- build/gulpfile.extensions.js | 34 +- build/gulpfile.hygiene.js | 2 +- build/gulpfile.js | 6 +- build/gulpfile.reh.js | 20 +- build/gulpfile.vscode.js | 24 +- build/gulpfile.vscode.linux.js | 11 +- build/gulpfile.vscode.web.js | 4 +- build/hygiene.js | 6 +- build/lib/asar.js | 4 +- build/lib/asar.ts | 4 +- build/lib/builtInExtensions.js | 4 +- build/lib/builtInExtensions.ts | 4 +- build/lib/bundle.js | 36 +- build/lib/bundle.ts | 57 +- build/lib/compilation.js | 47 +- build/lib/compilation.ts | 45 +- build/lib/dependencies.js | 2 +- build/lib/dependencies.ts | 2 + build/lib/electron.js | 2 +- build/lib/electron.ts | 2 + build/lib/eslint/code-no-look-behind-regex.js | 2 +- build/lib/eslint/code-no-look-behind-regex.ts | 2 + .../eslint/code-no-unexternalized-strings.js | 4 +- .../eslint/code-no-unexternalized-strings.ts | 4 +- .../lib/eslint/code-no-unused-expressions.js | 8 +- .../lib/eslint/code-no-unused-expressions.ts | 2 + build/lib/eslint/vscode-dts-cancellation.js | 2 +- build/lib/eslint/vscode-dts-cancellation.ts | 2 +- build/lib/eslint/vscode-dts-event-naming.js | 2 +- build/lib/eslint/vscode-dts-event-naming.ts | 3 +- build/lib/extensions.js | 129 +- build/lib/extensions.ts | 10 +- build/lib/git.js | 8 +- build/lib/git.ts | 4 +- build/lib/i18n.js | 196 +- build/lib/i18n.resources.json | 26 +- build/lib/i18n.ts | 209 +- build/lib/layersChecker.js | 5 - build/lib/monaco-api.js | 84 +- build/lib/monaco-api.ts | 86 +- build/lib/optimize.js | 66 +- build/lib/optimize.ts | 73 +- build/lib/policies.js | 497 -- build/lib/policies.ts | 697 -- build/lib/preLaunch.js | 2 +- build/lib/preLaunch.ts | 2 + build/lib/reporter.js | 2 +- build/lib/reporter.ts | 2 + build/lib/snapshotLoader.js | 2 +- build/lib/snapshotLoader.ts | 2 + build/lib/standalone.js | 31 +- build/lib/standalone.ts | 31 +- build/lib/task.js | 2 +- build/lib/task.ts | 2 + build/lib/treeshaking.js | 70 +- build/lib/treeshaking.ts | 66 +- build/lib/tsb/builder.js | 491 - build/lib/tsb/builder.ts | 608 -- build/lib/tsb/index.js | 130 - build/lib/tsb/index.ts | 164 - build/lib/tsb/transpiler.js | 220 - build/lib/tsb/transpiler.ts | 285 - build/lib/tsb/utils.js | 124 - build/lib/tsb/utils.ts | 140 - build/lib/typings/gulp-tsb.d.ts | 18 + build/lib/util.js | 13 +- build/lib/util.ts | 13 +- build/lib/watch/.gitignore | 1 + build/lib/watch/package.json | 12 + build/lib/watch/yarn.lock | 400 + build/linux/debian/dep-lists.js | 156 - build/linux/debian/dep-lists.ts | 157 - build/linux/debian/dependencies-generator.js | 129 - build/linux/debian/dependencies-generator.ts | 145 - build/linux/debian/install-sysroot.js | 81 - build/linux/debian/install-sysroot.ts | 90 - build/linux/debian/sysroots.js | 26 - build/linux/debian/sysroots.ts | 24 - build/linux/debian/types.js | 6 - build/linux/libcxx-fetcher.js | 4 +- build/linux/libcxx-fetcher.ts | 2 + build/linux/rpm/dep-lists.js | 6 + build/linux/rpm/dep-lists.ts | 6 + build/linux/rpm/dependencies-generator.js | 4 +- build/linux/rpm/dependencies-generator.ts | 4 +- build/monaco/monaco.d.ts.recipe | 2 +- build/npm/dirs.js | 2 +- build/npm/postinstall.js | 28 +- build/npm/preinstall.js | 7 +- build/npm/setupBuildYarnrc.js | 25 - build/package-lock.json | 7877 ----------------- build/package.json | 19 +- build/tsconfig.json | 1 - build/win32/code.iss | 2 +- build/yarn.lock | 1301 ++- cglicenses.json | 53 - cgmanifest.json | 42 +- extensions/configuration-editing/package.json | 7 +- .../devContainer.codespaces.schema.json | 189 - .../devContainer.schema.generated.json | 920 +- .../schemas/devContainer.schema.src.json | 183 +- .../schemas/devContainer.vscode.schema.json | 56 - .../src/configurationEditingMain.ts | 60 +- .../src/extensionsProposals.ts | 8 +- .../src/settingsDocumentHelper.ts | 146 +- .../src/test/completion.test.ts | 594 -- .../server/src/utils/validation.ts | 108 - .../typings/markdown-it-named-headers.d.ts | 4 +- extensions/fsharp/cgmanifest.json | 2 +- .../fsharp/syntaxes/fsharp.tmLanguage.json | 28 +- extensions/git-base/src/remoteSource.ts | 9 +- extensions/git/extension.webpack.config.js | 3 +- extensions/git/package.json | 394 +- extensions/git/package.nls.json | 65 +- extensions/git/src/actionButton.ts | 287 +- extensions/git/src/api/api1.ts | 100 +- extensions/git/src/api/git.d.ts | 13 +- extensions/git/src/askpass.ts | 50 +- extensions/git/src/commands.ts | 502 +- extensions/git/src/decorationProvider.ts | 2 +- extensions/git/src/encoding.ts | 2 +- extensions/git/src/git-editor-empty.sh | 1 - extensions/git/src/git-editor-main.ts | 21 - extensions/git/src/git-editor.sh | 4 - extensions/git/src/git.ts | 75 +- extensions/git/src/gitEditor.ts | 63 - extensions/git/src/ipc/ipcServer.ts | 9 +- extensions/git/src/log.ts | 113 +- extensions/git/src/main.ts | 55 +- extensions/git/src/model.ts | 75 +- extensions/git/src/postCommitCommands.ts | 32 - extensions/git/src/protocolHandler.ts | 10 +- extensions/git/src/repository.ts | 140 +- extensions/git/src/staging.ts | 2 +- extensions/git/src/statusbar.ts | 8 +- extensions/git/src/terminal.ts | 36 +- extensions/git/src/test/git.test.ts | 6 - extensions/git/src/uri.ts | 11 - extensions/git/src/util.ts | 14 +- extensions/git/tsconfig.json | 2 +- extensions/git/yarn.lock | 64 +- extensions/github-authentication/package.json | 6 +- .../github-authentication/src/common/utils.ts | 2 +- .../github-authentication/src/github.ts | 28 +- .../github-authentication/src/githubServer.ts | 3 - extensions/github-authentication/yarn.lock | 65 +- extensions/github/package.json | 46 - extensions/github/package.nls.json | 4 - extensions/github/src/auth.ts | 2 +- extensions/github/src/commands.ts | 38 - extensions/github/src/extension.ts | 20 +- extensions/github/src/links.ts | 135 - extensions/github/src/pushErrorHandler.ts | 21 +- extensions/github/src/remoteSourceProvider.ts | 14 +- extensions/github/src/test/github.test.ts | 22 +- extensions/github/src/util.ts | 16 - .../client/src/languageParticipants.ts | 87 - .../server/src/utils/validation.ts | 108 - extensions/image-preview/media/main.js | 2 +- extensions/image-preview/package.json | 4 +- extensions/image-preview/yarn.lock | 47 +- extensions/ipynb/.gitignore | 1 - extensions/ipynb/.vscodeignore | 2 +- extensions/ipynb/esbuild.js | 47 - extensions/ipynb/package.json | 16 +- .../ipynb/src/cellAttachmentRenderer.ts | 47 - extensions/ipynb/yarn.lock | 34 +- .../javascript-language-configuration.json | 2 +- .../snippets/javascript.code-snippets | 9 - .../syntaxes/JavaScript.tmLanguage.json | 44 +- .../syntaxes/JavaScriptReact.tmLanguage.json | 44 +- .../client/src/browser/jsonClientMain.ts | 15 +- .../client/src/jsonClient.ts | 415 +- .../client/src/languageStatus.ts | 94 +- .../client/src/node/jsonClientMain.ts | 13 +- .../json-language-features/package.json | 14 +- .../json-language-features/package.nls.json | 1 - .../json-language-features/server/README.md | 6 + .../server/package.json | 6 +- .../server/src/jsonServer.ts | 194 +- .../server/src/languageModelCache.ts | 22 +- .../server/src/utils/runner.ts | 4 +- .../server/src/utils/strings.ts | 2 +- .../server/src/utils/validation.ts | 108 - .../json-language-features/server/yarn.lock | 83 +- extensions/json-language-features/yarn.lock | 103 +- extensions/json/language-configuration.json | 3 +- extensions/markdown-basics/cgmanifest.json | 2 +- extensions/markdown-basics/package.json | 5 +- .../syntaxes/markdown.tmLanguage.json | 39 +- .../markdown-language-features/.vscodeignore | 9 +- .../extension-browser.webpack.config.js | 2 +- .../notebook/index.ts | 133 +- .../markdown-language-features/package.json | 96 +- .../package.nls.json | 14 +- .../preview-src/loading.ts | 4 +- .../server/.npmignore | 12 - .../server/.vscode/launch.json | 16 - .../server/.vscode/settings.json | 2 - .../server/.vscode/tasks.json | 27 - .../server/README.md | 120 - .../extension-browser.webpack.config.js | 24 - .../server/extension.webpack.config.js | 22 - .../server/package.json | 26 - .../server/src/browser/main.ts | 16 - .../server/src/config.ts | 24 - .../server/src/configuration.ts | 59 - .../src/languageFeatures/diagnostics.ts | 95 - .../server/src/logging.ts | 47 - .../server/src/node/main.ts | 19 - .../server/src/protocol.ts | 27 - .../server/src/server.ts | 252 - .../server/src/util/arrays.ts | 11 - .../server/src/util/dispose.ts | 80 - .../server/src/util/file.ts | 16 - .../server/src/util/limiter.ts | 67 - .../server/src/util/resourceMap.ts | 69 - .../server/src/util/schemes.ts | 8 - .../server/src/workspace.ts | 251 - .../server/tsconfig.json | 9 - .../server/yarn.lock | 69 - .../markdown-language-features/src/client.ts | 114 - .../src/commands/openDocumentLink.ts | 9 +- .../src/commands/refreshPreview.ts | 4 +- .../src/commands/reloadPlugins.ts | 4 +- .../src/commands/renderDocument.ts | 8 +- .../src/extension.browser.ts | 42 - .../src/extension.shared.ts | 90 - .../src/extension.ts | 119 +- .../src/languageFeatures/copyPaste.ts | 29 - .../languageFeatures/definitionProvider.ts | 21 + .../src/languageFeatures/diagnostics.ts | 319 +- .../languageFeatures/documentLinkProvider.ts | 421 + .../documentSymbolProvider.ts | 76 + .../src/languageFeatures/dropIntoEditor.ts | 81 +- .../src/languageFeatures/fileReferences.ts | 17 +- .../src/languageFeatures/foldingProvider.ts | 113 + .../src/languageFeatures/pathCompletions.ts | 353 + .../src/languageFeatures/references.ts | 308 + .../src/languageFeatures/rename.ts | 272 + .../src/languageFeatures/smartSelect.ts | 251 + .../src/languageFeatures/workspaceCache.ts | 61 + .../workspaceSymbolProvider.ts | 29 + .../src/{logging.ts => logger.ts} | 39 +- .../src/markdownEngine.ts | 60 +- .../src/preview/preview.ts | 88 +- ...tRenderer.ts => previewContentProvider.ts} | 43 +- .../src/preview/previewManager.ts | 31 +- .../src/preview/topmostLineMonitor.ts | 32 +- .../src/protocol.ts | 28 - .../markdown-language-features/src/slugify.ts | 2 +- .../src/tableOfContents.ts | 97 +- .../src/test/definitionProvider.test.ts | 137 + .../src/test/diagnostic.test.ts | 160 + .../src/test/documentLink.test.ts | 8 +- .../src/test/documentLinkProvider.test.ts | 270 + .../src/test/documentSymbolProvider.test.ts | 97 + .../src/test/engine.test.ts | 2 +- .../src/test/engine.ts | 7 +- .../src/test/fileReferences.test.ts | 118 + .../src/test/foldingProvider.test.ts | 223 + .../src/test/inMemoryWorkspace.ts | 66 +- .../src/test/nulLogging.ts | 12 - .../src/test/pathCompletion.test.ts | 169 + .../src/test/references.test.ts | 580 ++ .../src/test/rename.test.ts | 616 ++ .../src/test/smartSelect.test.ts | 726 ++ .../src/test/tableOfContentsProvider.test.ts | 130 + .../src/test/util.ts | 35 +- .../src/test/workspaceSymbolProvider.test.ts | 103 + .../src/types/textDocument.ts | 22 - .../src/util/async.ts | 4 - .../src/util/cancellation.ts | 13 - .../src/util/dispose.ts | 52 +- .../src/util/dom.ts | 18 - .../src/util/file.ts | 17 - .../src/util/inMemoryDocument.ts | 16 +- .../src/util/openDocumentLink.ts | 72 +- .../src/util/resourceMap.ts | 68 - .../src/util/schemes.ts | 45 +- .../src/util/workspaceCache.ts | 116 - .../{workspace.ts => workspaceContents.ts} | 111 +- .../markdown-language-features/tsconfig.json | 2 +- .../markdown-language-features/yarn.lock | 162 +- extensions/markdown-math/.gitignore | 1 - extensions/markdown-math/notebook/katex.ts | 4 +- extensions/markdown-math/package.json | 8 +- .../markdown-math/preview-styles/index.css | 2 +- extensions/markdown-math/yarn.lock | 4 +- extensions/merge-conflict/package.json | 8 +- .../merge-conflict/src/codelensProvider.ts | 12 +- .../merge-conflict/src/commandHandler.ts | 14 +- .../merge-conflict/src/contentProvider.ts | 4 +- extensions/merge-conflict/src/delayer.ts | 4 +- .../src/documentMergeConflict.ts | 4 +- .../merge-conflict/src/documentTracker.ts | 12 +- .../merge-conflict/src/mergeConflictParser.ts | 8 +- .../merge-conflict/src/mergeDecorator.ts | 12 +- extensions/merge-conflict/src/services.ts | 16 +- .../microsoft-authentication/package.json | 4 +- .../microsoft-authentication/src/AADHelper.ts | 67 +- .../microsoft-authentication/src/extension.ts | 10 +- .../microsoft-authentication/src/utils.ts | 33 - extensions/microsoft-authentication/yarn.lock | 47 +- extensions/notebook-renderers/package.json | 2 +- extensions/notebook-renderers/src/index.ts | 34 +- extensions/package.json | 2 +- .../resource-deployment/src/test/utils.ts | 2 +- extensions/search-result/src/extension.ts | 4 +- extensions/shared.webpack.config.js | 10 +- extensions/simple-browser/.vscodeignore | 1 - extensions/simple-browser/package.json | 4 +- extensions/simple-browser/yarn.lock | 47 +- .../src/models/loginMigrationModel.ts | 2 +- extensions/sql/cgmanifest.json | 2 +- extensions/sql/syntaxes/sql.tmLanguage.json | 2 +- extensions/theme-defaults/themes/dark_vs.json | 2 +- .../theme-defaults/themes/light_vs.json | 3 +- .../theme-seti/build/update-icon-theme.js | 3 +- extensions/theme-seti/cgmanifest.json | 2 +- extensions/theme-seti/icons/seti.woff | Bin 37200 -> 37204 bytes .../theme-seti/icons/vs-seti-icon-theme.json | 28 +- .../themes/solarized-light-color-theme.json | 3 - .../tomorrow-night-blue-color-theme.json | 2 +- .../src/experimentationService.ts | 93 - .../interactiveWindow.test.ts | 108 - .../vscode-test-resolver/src/extension.ts | 4 +- .../xml-language-features/tsconfig.json | 3 +- .../xml/xml.language-configuration.json | 3 +- .../xml/xsl.language-configuration.json | 3 +- extensions/yarn.lock | 26 +- package.json | 34 +- remote/.yarnrc | 2 +- remote/package.json | 11 +- remote/web/package.json | 9 +- remote/web/yarn.lock | 169 +- remote/yarn.lock | 247 +- resources/darwin/bin/code.sh | 9 - resources/linux/bin/code.sh | 15 +- resources/linux/debian/control.template | 3 +- resources/linux/rpm/code.spec.template | 12 +- resources/linux/snap/snapcraft.yaml | 2 + resources/win32/policies/Code.admx | 48 + resources/win32/policies/en-US/Code.adml | 23 + scripts/test-remote-integration.bat | 8 +- scripts/test-remote-integration.sh | 26 +- scripts/test-web-integration.bat | 20 +- scripts/test-web-integration.sh | 20 +- src/bootstrap-fork.js | 72 +- src/bootstrap.js | 2 +- src/buildfile.js | 13 +- src/main.js | 15 +- src/server-main.js | 2 +- src/sql/azdata.d.ts | 5 - src/sql/azdata.proposed.d.ts | 6 +- .../base/browser/globalPointerMoveMonitor.ts | 126 - .../base/browser/ui/panel/panel.component.ts | 2 - .../browser/menuEntryActionViewItem.ts | 13 +- .../connection/common/connectionStore.ts | 4 +- .../api/common/extHostModelViewTree.ts | 5 +- .../api/common/sqlExtHost.protocol.ts | 4 +- .../browser/designer/designerScriptEditor.ts | 14 +- .../declarativeTable.component.ts | 2 +- .../modelComponents/queryTextEditor.ts | 15 +- .../modelComponents/table.component.ts | 2 +- .../workbench/contrib/charts/browser/utils.ts | 4 +- .../common/configurationUpgrader.ts | 4 +- .../contents/webviewContent.component.ts | 13 +- .../insights/insightsWidget.component.ts | 4 +- .../webview/webviewWidget.component.ts | 11 +- .../editData/browser/editDataEditor.ts | 3 +- .../executionPlanComparisonEditorView.ts | 5 +- .../browser/executionPlanContribution.ts | 16 +- .../browser/executionPlanView.ts | 4 +- .../widgets/highlightExpensiveNodeWidget.ts | 4 +- .../browser/scenarioRecommendations.ts | 4 +- .../modelView/browser/webview.component.ts | 13 +- .../notebook/browser/cellViews/interfaces.ts | 4 +- .../notebook/browser/notebook.contribution.ts | 25 +- .../notebook/browser/notebookEditor.ts | 4 +- .../browser/markdownTextTransformer.test.ts | 2 +- .../test/browser/notebookEditor.test.ts | 3 +- .../contrib/notebook/test/testCommon.ts | 5 +- .../browser/connectionTreeActions.test.ts | 40 +- .../browser/profilerResourceEditor.ts | 15 +- .../contrib/query/browser/actions.ts | 2 +- .../query/browser/query.contribution.ts | 20 +- .../contrib/query/browser/queryEditor.ts | 4 +- .../contrib/webview/browser/webViewDialog.ts | 13 +- .../browser/abstractEnablePreviewFeatures.ts | 6 +- .../notifyEncryptionDialog.ts | 4 +- .../welcome/page/browser/welcomePage.ts | 2 +- .../browser/accountManagementService.ts | 2 +- .../browser/connectionManagementService.ts | 2 +- .../services/insights/common/insightsUtils.ts | 2 - .../notebook/browser/notebookService.ts | 4 +- .../notebook/browser/notebookServiceImpl.ts | 4 +- .../objectExplorer/browser/asyncServerTree.ts | 10 +- .../profiler/browser/profilerService.ts | 2 +- src/tsconfig.monaco.json | 9 +- src/tsconfig.vscode-dts.json | 1 - src/tsec.exemptions.json | 3 +- src/vs/base/browser/broadcast.ts | 69 - src/vs/base/browser/browser.ts | 4 +- src/vs/base/browser/defaultWorkerFactory.ts | 10 +- src/vs/base/browser/deviceAccess.ts | 108 - src/vs/base/browser/dom.ts | 316 +- src/vs/base/browser/formattedTextRenderer.ts | 2 +- .../base/browser/globalPointerMoveMonitor.ts | 50 +- src/vs/base/browser/history.ts | 8 - src/vs/base/browser/iframe.ts | 8 +- src/vs/base/browser/indexedDB.ts | 13 +- src/vs/base/browser/keyboardEvent.ts | 8 +- src/vs/base/browser/markdownRenderer.ts | 108 +- src/vs/base/browser/mouseEvent.ts | 6 +- src/vs/base/browser/touch.ts | 48 +- .../browser/ui/actionbar/actionViewItems.ts | 48 +- src/vs/base/browser/ui/actionbar/actionbar.ts | 4 +- .../ui/breadcrumbs/breadcrumbsWidget.ts | 16 +- src/vs/base/browser/ui/button/button.css | 32 +- src/vs/base/browser/ui/button/button.ts | 40 +- .../browser/ui/codicons/codicon/codicon.ttf | Bin 72504 -> 70800 bytes .../browser/ui/contextview/contextview.css | 2 + .../browser/ui/contextview/contextview.ts | 25 +- src/vs/base/browser/ui/dialog/dialog.ts | 10 +- src/vs/base/browser/ui/dropdown/dropdown.ts | 6 +- .../ui/dropdown/dropdownActionViewItem.ts | 13 - src/vs/base/browser/ui/findinput/findInput.ts | 56 +- .../base/browser/ui/findinput/replaceInput.ts | 14 +- src/vs/base/browser/ui/grid/grid.ts | 46 +- src/vs/base/browser/ui/grid/gridview.ts | 33 +- .../browser/ui/iconLabel/iconHoverDelegate.ts | 3 +- .../browser/ui/iconLabel/iconLabelHover.ts | 34 +- src/vs/base/browser/ui/inputbox/inputBox.ts | 30 +- .../ui/keybindingLabel/keybindingLabel.ts | 2 +- src/vs/base/browser/ui/list/list.css | 77 +- src/vs/base/browser/ui/list/listPaging.ts | 10 +- src/vs/base/browser/ui/list/listView.ts | 81 +- src/vs/base/browser/ui/list/listWidget.ts | 174 +- src/vs/base/browser/ui/list/rangeMap.ts | 8 +- src/vs/base/browser/ui/list/rowCache.ts | 4 +- src/vs/base/browser/ui/menu/menu.ts | 87 +- src/vs/base/browser/ui/menu/menubar.css | 46 +- src/vs/base/browser/ui/menu/menubar.ts | 79 +- src/vs/base/browser/ui/sash/sash.ts | 2 +- .../browser/ui/scrollbar/abstractScrollbar.ts | 5 +- .../browser/ui/scrollbar/scrollableElement.ts | 4 +- .../browser/ui/scrollbar/scrollbarArrow.ts | 3 +- .../scrollbarVisibilityController.ts | 8 +- .../browser/ui/selectBox/selectBoxCustom.ts | 16 +- src/vs/base/browser/ui/splitview/paneview.css | 5 +- src/vs/base/browser/ui/splitview/paneview.ts | 4 +- src/vs/base/browser/ui/splitview/splitview.ts | 23 +- src/vs/base/browser/ui/table/tableWidget.ts | 8 +- src/vs/base/browser/ui/toggle/toggle.ts | 15 +- src/vs/base/browser/ui/toolbar/toolbar.ts | 6 +- src/vs/base/browser/ui/tree/abstractTree.ts | 668 +- src/vs/base/browser/ui/tree/asyncDataTree.ts | 60 +- src/vs/base/browser/ui/tree/dataTree.ts | 4 +- src/vs/base/browser/ui/tree/indexTreeModel.ts | 4 +- src/vs/base/browser/ui/tree/media/tree.css | 52 - src/vs/base/browser/ui/tree/objectTree.ts | 8 +- src/vs/base/browser/ui/tree/tree.ts | 3 +- src/vs/base/browser/ui/widget.ts | 4 +- src/vs/base/common/actions.ts | 5 +- src/vs/base/common/amd.ts | 6 +- src/vs/base/common/arrays.ts | 114 +- src/vs/base/common/async.ts | 16 +- src/vs/base/common/codicons.ts | 17 +- src/vs/base/common/collections.ts | 25 +- src/vs/base/common/comparers.ts | 2 +- src/vs/base/common/console.ts | 2 +- src/vs/base/common/dataTransfer.ts | 90 - src/vs/base/common/diff/diff.ts | 4 +- src/vs/base/common/errors.ts | 38 +- src/vs/base/common/event.ts | 101 +- src/vs/base/common/fuzzyScorer.ts | 2 +- src/vs/base/common/htmlContent.ts | 4 - src/vs/base/common/json.ts | 26 +- src/vs/base/common/jsonEdit.ts | 4 +- src/vs/base/common/jsonSchema.ts | 23 +- src/vs/base/common/keyCodes.ts | 4 +- src/vs/base/common/labels.ts | 30 +- src/vs/base/common/lifecycle.ts | 2 +- src/vs/base/common/map.ts | 30 +- src/vs/base/common/marked/cgmanifest.json | 4 +- src/vs/base/common/marked/marked.js | 252 +- src/vs/base/common/mime.ts | 16 +- src/vs/base/common/network.ts | 12 +- src/vs/base/common/objects.ts | 3 +- src/vs/base/common/observable.ts | 30 - src/vs/base/common/observableImpl/autorun.ts | 167 - src/vs/base/common/observableImpl/base.ts | 244 - src/vs/base/common/observableImpl/derived.ts | 167 - src/vs/base/common/observableImpl/logging.ts | 312 - src/vs/base/common/observableImpl/utils.ts | 281 - src/vs/base/common/observableValue.ts | 11 - src/vs/base/common/platform.ts | 20 +- src/vs/base/common/product.ts | 4 - src/vs/base/common/resources.ts | 3 +- src/vs/base/common/scrollable.ts | 4 +- src/vs/base/common/skipList.ts | 6 +- src/vs/base/common/strings.ts | 18 +- src/vs/base/common/stripComments.js | 10 +- src/vs/base/common/types.ts | 17 +- src/vs/base/common/uriIpc.ts | 4 +- src/vs/base/common/worker/simpleWorker.ts | 14 +- src/vs/base/node/id.ts | 2 +- src/vs/base/node/macAddress.ts | 2 +- src/vs/base/node/pfs.ts | 7 +- src/vs/base/node/processes.ts | 2 +- src/vs/base/node/ps.ts | 5 - .../electron-sandbox/contextmenu.ts | 8 +- src/vs/base/parts/ipc/common/ipc.net.ts | 5 +- src/vs/base/parts/ipc/common/ipc.ts | 24 +- src/vs/base/parts/ipc/node/ipc.cp.ts | 4 +- src/vs/base/parts/ipc/node/ipc.net.ts | 39 +- .../quickinput/browser/media/quickInput.css | 5 +- .../parts/quickinput/browser/quickInput.ts | 26 +- .../quickinput/browser/quickInputList.ts | 60 +- .../parts/quickinput/common/quickInput.ts | 7 - .../test/browser/quickinput.test.ts | 48 +- src/vs/base/parts/request/browser/request.ts | 2 +- .../parts/sandbox/electron-browser/preload.js | 8 +- .../parts/sandbox/electron-sandbox/globals.ts | 4 - src/vs/base/parts/storage/common/storage.ts | 8 +- src/vs/base/parts/storage/node/storage.ts | 12 +- .../parts/storage/test/node/storage.test.ts | 91 +- src/vs/base/test/browser/actionbar.test.ts | 20 +- src/vs/base/test/browser/dom.test.ts | 167 +- .../browser/formattedTextRenderer.test.ts | 22 +- .../test/browser/markdownRenderer.test.ts | 51 +- src/vs/base/test/browser/ui/grid/grid.test.ts | 38 +- .../test/browser/ui/list/listWidget.test.ts | 97 - .../ui/scrollbar/scrollbarState.test.ts | 4 +- .../browser/ui/splitview/splitview.test.ts | 2 +- .../browser/ui/tree/asyncDataTree.test.ts | 59 +- .../browser/ui/tree/indexTreeModel.test.ts | 2 +- .../browser/ui/tree/objectTreeModel.test.ts | 2 +- src/vs/base/test/common/arrays.test.ts | 40 +- src/vs/base/test/common/async.test.ts | 148 +- src/vs/base/test/common/buffer.test.ts | 38 +- src/vs/base/test/common/cancellation.test.ts | 12 +- src/vs/base/test/common/collections.test.ts | 28 +- src/vs/base/test/common/color.test.ts | 8 +- src/vs/base/test/common/diff/diff.test.ts | 18 +- src/vs/base/test/common/event.test.ts | 86 +- src/vs/base/test/common/filters.test.ts | 26 +- src/vs/base/test/common/fuzzyScorer.test.ts | 72 +- src/vs/base/test/common/glob.test.ts | 78 +- src/vs/base/test/common/history.test.ts | 2 +- src/vs/base/test/common/iconLabels.test.ts | 2 +- src/vs/base/test/common/json.test.ts | 22 +- src/vs/base/test/common/jsonEdit.test.ts | 52 +- src/vs/base/test/common/jsonFormatter.test.ts | 2 +- src/vs/base/test/common/labels.test.ts | 14 + src/vs/base/test/common/lifecycle.test.ts | 10 +- src/vs/base/test/common/linkedList.test.ts | 10 +- src/vs/base/test/common/map.test.ts | 88 +- src/vs/base/test/common/marshalling.test.ts | 6 +- src/vs/base/test/common/network.test.ts | 10 +- src/vs/base/test/common/objects.test.ts | 26 +- src/vs/base/test/common/observable.test.ts | 507 -- src/vs/base/test/common/processes.test.ts | 2 +- src/vs/base/test/common/resourceTree.test.ts | 4 +- src/vs/base/test/common/resources.test.ts | 34 +- src/vs/base/test/common/scrollable.test.ts | 7 +- src/vs/base/test/common/skipList.test.ts | 26 +- src/vs/base/test/common/stream.test.ts | 4 +- src/vs/base/test/common/stripComments.test.ts | 22 - .../base/test/common/timeTravelScheduler.ts | 7 +- src/vs/base/test/common/troubleshooting.ts | 8 +- src/vs/base/test/common/uri.test.ts | 30 +- src/vs/base/test/node/css.build.test.ts | 313 - src/vs/base/test/node/pfs/pfs.test.ts | 24 +- src/vs/base/test/node/uri.test.perf.ts | 18 +- src/vs/base/worker/workerMain.ts | 31 +- src/vs/code/browser/workbench/workbench.html | 15 +- .../contrib/extensionsCleaner.ts | 169 +- .../contrib/languagePackCachedDataCleaner.ts | 2 +- .../contrib/localizationsUpdater.ts | 6 +- .../sharedProcess/sharedProcessMain.ts | 54 +- .../electron-browser/workbench/workbench.html | 19 + .../electron-browser/workbench/workbench.js | 214 + src/vs/code/electron-main/app.ts | 60 +- src/vs/code/electron-main/main.ts | 61 +- .../issue/issueReporterMain.ts | 17 +- .../issue/issueReporterModel.ts | 11 +- .../electron-sandbox/workbench/workbench.html | 2 +- .../electron-sandbox/workbench/workbench.js | 7 +- src/vs/code/node/cli.ts | 21 +- src/vs/code/node/cliProcessMain.ts | 58 +- .../issue/testReporterModel.test.ts | 42 +- src/vs/css.build.ts | 304 - .../css.d.ts} | 2 - src/vs/css.js | 4 + src/vs/css.ts | 81 - src/vs/editor/browser/config/domFontInfo.ts | 6 +- .../browser/config/editorConfiguration.ts | 6 + .../editor/browser/config/fontMeasurements.ts | 4 +- .../editor/browser/config/migrateOptions.ts | 19 +- .../editor/browser/controller/mouseHandler.ts | 68 +- .../editor/browser/controller/mouseTarget.ts | 16 +- .../browser/controller/pointerHandler.ts | 6 +- .../browser/controller/textAreaHandler.ts | 9 +- src/vs/editor/browser/coreCommands.ts | 67 +- src/vs/editor/browser/dnd.ts | 76 - src/vs/editor/browser/editorBrowser.ts | 26 +- src/vs/editor/browser/editorDom.ts | 51 +- src/vs/editor/browser/editorExtensions.ts | 6 +- .../services/abstractCodeEditorService.ts | 26 +- .../browser/services/bulkEditService.ts | 70 +- .../browser/services/codeEditorService.ts | 6 - .../browser/services/editorWorkerService.ts | 4 +- .../editor/browser/services/openerService.ts | 2 +- src/vs/editor/browser/view.ts | 5 - .../browser/view/viewUserInputEvents.ts | 44 +- .../blockDecorations/blockDecorations.css | 14 - .../blockDecorations/blockDecorations.ts | 103 - .../viewParts/lineNumbers/lineNumbers.ts | 65 +- .../browser/viewParts/lines/viewLine.ts | 8 +- .../browser/viewParts/lines/viewLines.ts | 3 +- .../browser/viewParts/minimap/minimap.css | 9 - .../browser/viewParts/minimap/minimap.ts | 28 +- .../overviewRuler/decorationsOverviewRuler.ts | 12 +- .../scrollDecoration/scrollDecoration.ts | 2 +- .../viewParts/viewCursors/viewCursor.ts | 8 +- .../editor/browser/widget/codeEditorWidget.ts | 228 +- .../editor/browser/widget/diffEditorWidget.ts | 194 +- .../browser/widget/media/diffEditor.css | 9 - .../config/editorConfigurationSchema.ts | 5 - src/vs/editor/common/config/editorOptions.ts | 253 +- src/vs/editor/common/config/fontInfo.ts | 5 +- src/vs/editor/common/core/indentation.ts | 3 +- src/vs/editor/common/core/range.ts | 8 +- src/vs/editor/common/core/wordHelper.ts | 30 +- src/vs/editor/common/cursor/cursor.ts | 2 +- .../common/cursor/cursorMoveCommands.ts | 2 +- .../common/cursor/cursorWordOperations.ts | 8 +- src/vs/editor/common/diff/diffComputer.ts | 116 +- src/vs/editor/common/editorCommon.ts | 46 +- .../editor/common/encodedTokenAttributes.ts | 193 - .../editor/common/languageFeatureRegistry.ts | 16 +- src/vs/editor/common/languageSelector.ts | 10 +- src/vs/editor/common/languages.ts | 262 +- .../common/languages/languageConfiguration.ts | 2 +- .../editor/common/languages/linkComputer.ts | 10 +- .../editor/common/languages/nullTokenize.ts | 3 +- src/vs/editor/common/languages/supports.ts | 2 +- .../supports/inplaceReplaceSupport.ts | 2 +- .../common/languages/supports/tokenization.ts | 4 +- .../common/languages/textToHtmlTokenizer.ts | 3 +- src/vs/editor/common/model.ts | 13 +- .../bracketPairsImpl.ts | 6 +- .../bracketPairsTree/bracketPairsTree.ts | 16 +- .../bracketPairsTree/brackets.ts | 16 +- .../bracketPairsTree/tokenizer.ts | 4 +- src/vs/editor/common/model/editStack.ts | 2 +- .../pieceTreeTextBuffer/pieceTreeBase.ts | 3 +- src/vs/editor/common/model/textModel.ts | 32 +- src/vs/editor/common/model/textModelSearch.ts | 6 +- src/vs/editor/common/model/textModelTokens.ts | 7 +- .../common/model/tokenizationTextModelPart.ts | 2 +- .../common/services/editorSimpleWorker.ts | 18 +- .../editor/common/services/getIconClasses.ts | 1 + .../services/languageFeatureDebounce.ts | 4 +- .../common/services/languageFeatures.ts | 4 +- .../services/languageFeaturesService.ts | 3 +- .../editor/common/services/languageService.ts | 4 +- .../common/services/languagesRegistry.ts | 9 +- .../services/markerDecorationsService.ts | 6 +- src/vs/editor/common/services/modelService.ts | 19 +- .../editor/common/services/resolverService.ts | 6 - .../services/semanticTokensProviderStyling.ts | 72 +- .../services/unicodeTextModelHighlighter.ts | 2 +- .../common/standalone/standaloneEnums.ts | 209 +- src/vs/editor/common/tokenizationRegistry.ts | 3 +- .../common/tokenizationTextModelPart.ts | 2 +- .../common/tokens/contiguousTokensStore.ts | 3 +- src/vs/editor/common/tokens/lineTokens.ts | 3 +- .../editor/common/tokens/sparseTokensStore.ts | 3 +- .../common/viewLayout/lineDecorations.ts | 2 +- src/vs/editor/common/viewLayout/linePart.ts | 36 - .../editor/common/viewLayout/linesLayout.ts | 18 +- src/vs/editor/common/viewLayout/viewLayout.ts | 11 +- .../common/viewLayout/viewLineRenderer.ts | 98 +- .../viewLayout/viewLinesViewportData.ts | 2 +- src/vs/editor/common/viewModel.ts | 7 +- .../viewModel/minimapTokensColorTracker.ts | 3 +- .../common/viewModel/modelLineProjection.ts | 2 +- .../viewModel/monospaceLineBreaksComputer.ts | 6 +- .../common/viewModel/viewModelDecorations.ts | 16 +- .../editor/common/viewModel/viewModelImpl.ts | 117 +- .../editor/common/viewModel/viewModelLines.ts | 112 +- .../anchorSelect/browser/anchorSelect.ts | 30 +- .../browser/bracketMatching.ts | 29 +- .../caretOperations/browser/transpose.ts | 26 +- .../contrib/clipboard/browser/clipboard.ts | 1 - .../contrib/codeAction/browser/codeAction.ts | 6 +- .../codeAction/browser/codeActionCommands.ts | 216 +- .../browser/codeActionContributions.ts | 5 +- .../codeAction/browser/codeActionMenu.ts | 426 +- .../codeAction/browser/codeActionModel.ts | 12 +- .../codeAction/browser/codeActionUi.ts | 46 +- .../browser/codeActionWidgetContribution.ts | 22 - .../codeAction/browser/media/action.css | 111 - .../contrib/codeAction/browser/types.ts | 17 - .../test/browser/codeAction.test.ts | 30 +- .../contrib/codelens/browser/codelens.ts | 2 +- .../codelens/browser/codelensController.ts | 22 +- .../codelens/browser/codelensWidget.ts | 10 +- .../contrib/colorPicker/browser/color.ts | 4 +- .../colorPicker/browser/colorDetector.ts | 29 +- .../browser/colorHoverParticipant.ts | 2 +- .../colorPicker/browser/colorPickerWidget.ts | 6 +- .../comment/browser/blockCommentCommand.ts | 4 +- .../comment/browser/lineCommentCommand.ts | 10 +- .../test/browser/lineCommentCommand.test.ts | 3 +- .../contextmenu/browser/contextmenu.ts | 126 +- .../browser/copyPasteContribution.ts | 25 - .../copyPaste/browser/copyPasteController.ts | 230 - src/vs/editor/contrib/dnd/browser/dnd.ts | 23 +- .../contrib/dnd/browser/dragAndDropCommand.ts | 2 +- .../documentSymbols/browser/outlineModel.ts | 28 +- .../test/browser/outlineModel.test.ts | 32 +- .../browser/dropIntoEditorContribution.ts | 178 - .../test/browser/editorState.test.ts | 18 +- .../contrib/find/browser/findController.ts | 14 +- .../contrib/find/browser/findDecorations.ts | 22 +- .../editor/contrib/find/browser/findModel.ts | 60 +- .../contrib/find/browser/findOptionsWidget.ts | 8 +- .../editor/contrib/find/browser/findState.ts | 4 +- .../editor/contrib/find/browser/findWidget.ts | 44 +- .../contrib/find/browser/replaceAllCommand.ts | 4 +- .../contrib/find/browser/replacePattern.ts | 20 +- .../contrib/find/test/browser/find.test.ts | 18 +- .../find/test/browser/findController.test.ts | 10 +- .../find/test/browser/findModel.test.ts | 182 +- .../find/test/browser/replacePattern.test.ts | 50 +- .../contrib/folding/browser/folding.css | 5 +- .../editor/contrib/folding/browser/folding.ts | 234 +- .../folding/browser/foldingDecorations.ts | 66 +- .../contrib/folding/browser/foldingModel.ts | 302 +- .../contrib/folding/browser/foldingRanges.ts | 279 +- .../folding/browser/hiddenRangeModel.ts | 42 +- .../folding/browser/indentRangeProvider.ts | 40 +- .../browser/intializingRangeProvider.ts | 65 + .../folding/browser/syntaxRangeProvider.ts | 36 +- .../folding/test/browser/foldingModel.test.ts | 318 +- .../test/browser/foldingRanges.test.ts | 131 +- .../test/browser/hiddenRangeModel.test.ts | 10 +- .../folding/test/browser/indentFold.test.ts | 26 +- .../test/browser/indentRangeProvider.test.ts | 16 +- .../folding/test/browser/syntaxFold.test.ts | 30 +- .../editor/contrib/format/browser/format.ts | 16 +- .../contrib/format/browser/formatActions.ts | 6 +- .../contrib/format/browser/formattingEdit.ts | 4 +- .../gotoError/browser/gotoErrorWidget.ts | 16 +- .../browser/markerNavigationService.ts | 4 +- .../gotoSymbol/browser/goToCommands.ts | 13 +- .../contrib/gotoSymbol/browser/goToSymbol.ts | 2 +- .../browser/link/goToDefinitionAtPosition.ts | 19 +- .../browser/peek/referencesController.ts | 12 +- .../gotoSymbol/browser/peek/referencesTree.ts | 2 +- .../browser/peek/referencesWidget.ts | 24 +- .../gotoSymbol/browser/referencesModel.ts | 10 +- .../contrib/hover/browser/contentHover.ts | 103 +- src/vs/editor/contrib/hover/browser/hover.ts | 2 +- .../hover/browser/markerHoverParticipant.ts | 5 +- .../hover/test/browser/contentHover.test.ts | 27 - .../inPlaceReplace/browser/inPlaceReplace.ts | 13 +- .../indentation/browser/indentUtils.ts | 2 +- .../indentation/browser/indentation.ts | 97 +- .../contrib/inlayHints/browser/inlayHints.ts | 2 +- .../browser/inlayHintsController.ts | 50 +- .../inlayHints/browser/inlayHintsHover.ts | 2 +- .../browser/inlineCompletionsModel.ts | 39 +- .../browser/inlineCompletionsProvider.test.ts | 4 +- .../test/browser/suggestWidgetModel.test.ts | 2 +- .../browser/copyLinesCommand.ts | 2 +- .../browser/linesOperations.ts | 175 +- .../browser/moveLinesCommand.ts | 86 +- .../browser/sortLinesCommand.ts | 10 +- .../test/browser/linesOperations.test.ts | 178 +- .../test/browser/moveLinesCommand.test.ts | 2 +- .../linkedEditing/browser/linkedEditing.ts | 37 +- .../editor/contrib/links/browser/getLinks.ts | 2 +- src/vs/editor/contrib/links/browser/links.ts | 18 +- .../message/browser/messageController.ts | 12 +- .../multicursor/browser/multicursor.ts | 20 +- .../test/browser/multicursor.test.ts | 54 +- .../browser/parameterHintsWidget.ts | 12 +- .../contrib/peekView/browser/peekView.ts | 6 +- .../browser/gotoSymbolQuickAccess.ts | 23 +- .../readOnlyMessage/browser/contribution.ts | 36 - .../editor/contrib/rename/browser/rename.ts | 4 +- .../rename/browser/renameInputField.ts | 8 +- .../smartSelect/browser/bracketSelections.ts | 16 +- .../smartSelect/browser/smartSelect.ts | 12 +- .../smartSelect/browser/wordSelections.ts | 8 +- .../test/browser/smartSelect.test.ts | 24 +- .../snippet/browser/snippetController2.ts | 55 +- .../contrib/snippet/browser/snippetParser.ts | 68 +- .../contrib/snippet/browser/snippetSession.ts | 133 +- .../snippet/browser/snippetVariables.ts | 4 +- .../browser/snippetController2.old.test.ts | 4 +- .../test/browser/snippetController2.test.ts | 167 +- .../test/browser/snippetParser.test.ts | 57 +- .../test/browser/snippetSession.test.ts | 63 +- .../test/browser/snippetVariables.test.ts | 3 +- .../stickyScroll/browser/stickyScroll.ts | 408 - .../suggest/browser/completionModel.ts | 8 +- .../contrib/suggest/browser}/resizable.ts | 0 .../editor/contrib/suggest/browser/suggest.ts | 22 +- .../suggest/browser/suggestAlternatives.ts | 2 +- .../suggest/browser/suggestController.ts | 57 +- .../contrib/suggest/browser/suggestMemory.ts | 18 +- .../contrib/suggest/browser/suggestModel.ts | 33 +- .../contrib/suggest/browser/suggestWidget.ts | 24 +- .../suggest/browser/suggestWidgetDetails.ts | 11 +- .../suggest/browser/suggestWidgetRenderer.ts | 10 +- .../suggest/browser/suggestWidgetStatus.ts | 2 +- .../contrib/suggest/browser/wordDistance.ts | 8 +- .../test/browser/completionModel.test.ts | 19 +- .../test/browser/suggestController.test.ts | 34 +- .../test/browser/suggestMemory.test.ts | 24 +- .../suggest/test/browser/suggestModel.test.ts | 99 +- .../suggest/test/browser/wordDistance.test.ts | 6 +- .../browser/bannerController.ts | 4 +- .../browser/unicodeHighlighter.ts | 63 +- .../browser/wordHighlighter.ts | 71 +- .../wordOperations/browser/wordOperations.ts | 4 +- .../test/browser/wordTestUtils.ts | 4 +- .../browser/wordPartOperations.ts | 4 +- .../contrib/zoneWidget/browser/zoneWidget.ts | 62 +- src/vs/editor/editor.all.ts | 4 - src/vs/editor/standalone/browser/colorizer.ts | 3 +- .../browser/inspectTokens/inspectTokens.ts | 3 +- .../standaloneCommandsQuickAccess.ts | 16 +- .../standaloneGotoLineQuickAccess.ts | 16 +- .../standaloneGotoSymbolQuickAccess.ts | 24 +- .../quickAccess/standaloneHelpQuickAccess.ts | 2 +- .../quickInput/standaloneQuickInputService.ts | 3 +- .../browser/standaloneCodeEditor.ts | 10 +- .../browser/standaloneCodeEditorService.ts | 16 +- .../standalone/browser/standaloneEditor.ts | 41 +- .../standalone/browser/standaloneLanguages.ts | 16 +- .../browser/standaloneLayoutService.ts | 5 +- .../standalone/browser/standaloneServices.ts | 45 +- .../browser/standaloneThemeService.ts | 70 +- .../toggleHighContrast/toggleHighContrast.ts | 12 +- .../common/monarch/monarchCompile.ts | 6 +- .../standalone/common/monarch/monarchLexer.ts | 31 +- .../standalone/test/browser/monarch.test.ts | 59 +- .../test/browser/standaloneLanguages.test.ts | 3 +- .../browser/commands/shiftCommand.test.ts | 20 +- .../test/browser/commands/sideEditing.test.ts | 2 +- .../trimTrailingWhitespaceCommand.test.ts | 6 +- .../config/editorConfiguration.test.ts | 54 +- .../config/editorLayoutProvider.test.ts | 1 - .../test/browser/controller/cursor.test.ts | 122 +- .../test/browser/controller/imeRecorder.ts | 2 +- .../test/browser/controller/imeTester.ts | 34 +- .../browser/controller/textAreaInput.test.ts | 4 +- .../browser/controller/textAreaState.test.ts | 18 +- .../editor/test/browser/editorTestServices.ts | 2 +- .../services/decorationRenderOptions.test.ts | 6 +- .../browser/services/openerService.test.ts | 2 +- src/vs/editor/test/browser/testCommand.ts | 4 +- .../browser/view/minimapCharRenderer.test.ts | 22 +- .../test/browser/view/viewLayer.test.ts | 18 +- .../viewModel/modelLineProjection.test.ts | 57 +- .../viewModel/viewModelDecorations.test.ts | 18 +- .../browser/viewModel/viewModelImpl.test.ts | 6 +- .../browser/widget/codeEditorWidget.test.ts | 4 +- .../common/core/characterClassifier.test.ts | 2 +- .../test/common/core/lineTokens.test.ts | 6 +- src/vs/editor/test/common/core/range.test.ts | 10 +- .../editor/test/common/core/testLineToken.ts | 4 +- .../test/common/diff/diffComputer.test.ts | 556 +- .../beforeEditPositionMapper.test.ts | 2 +- .../bracketPairColorizer/brackets.test.ts | 2 +- .../concat23Trees.test.ts | 2 +- .../getBracketPairsInRange.test.ts | 6 +- .../model/bracketPairColorizer/length.test.ts | 2 +- .../smallImmutableSet.test.ts | 2 +- .../bracketPairColorizer/tokenizer.test.ts | 5 +- .../common/model/editableTextModel.test.ts | 18 +- .../model/editableTextModelAuto.test.ts | 34 +- .../model/editableTextModelTestUtils.ts | 26 +- .../test/common/model/intervalTree.test.ts | 54 +- .../linesTextBuffer/linesTextBuffer.test.ts | 2 +- .../textBufferAutoTestUtils.ts | 54 +- .../test/common/model/model.line.test.ts | 20 +- src/vs/editor/test/common/model/model.test.ts | 7 +- .../common/model/modelDecorations.test.ts | 64 +- .../common/model/modelEditOperation.test.ts | 8 +- .../pieceTreeTextBuffer.test.ts | 244 +- .../test/common/model/textChange.test.ts | 46 +- .../test/common/model/textModel.test.ts | 91 +- .../test/common/model/textModelSearch.test.ts | 90 +- .../common/model/textModelWithTokens.test.ts | 65 +- .../test/common/model/tokensStore.test.ts | 22 +- .../modes/languageConfiguration.test.ts | 22 +- .../common/modes/languageSelector.test.ts | 152 +- .../test/common/modes/linkComputer.test.ts | 20 +- .../modes/supports/characterPair.test.ts | 16 +- .../modes/supports/electricCharacter.test.ts | 10 +- .../common/modes/supports/onEnter.test.ts | 24 +- .../modes/supports/richEditBrackets.test.ts | 20 +- .../modes/supports/tokenization.test.ts | 54 +- .../common/modes/textToHtmlTokenizer.test.ts | 33 +- src/vs/editor/test/common/modesTestUtils.ts | 10 +- .../services/editorSimpleWorker.test.ts | 20 +- .../test/common/services/modelService.test.ts | 58 +- .../semanticTokensProviderStyling.test.ts | 94 +- src/vs/editor/test/common/testTextModel.ts | 55 +- .../viewLayout/viewLineRenderer.test.ts | 2135 ++--- .../common/viewModel/lineBreakData.test.ts | 2 +- .../monospaceLineBreaksComputer.test.ts | 11 +- .../node/classification/typescript.test.ts | 2 +- src/vs/loader.d.ts | 35 - src/vs/loader.js | 26 +- src/vs/monaco.d.ts | 445 +- src/vs/nls.build.ts | 84 - src/vs/nls.js | 9 +- src/vs/nls.mock.ts | 4 - src/vs/nls.ts | 228 - .../dropdownWithPrimaryActionViewItem.ts | 10 +- .../browser/menuEntryActionViewItem.css | 20 + .../browser/menuEntryActionViewItem.ts | 128 +- .../actions/common/actions.contribution.ts | 14 - src/vs/platform/actions/common/actions.ts | 66 +- .../actions/common/menuResetAction.ts | 29 - src/vs/platform/actions/common/menuService.ts | 212 +- .../actions/test/common/menuService.test.ts | 15 +- .../platform/assignment/common/assignment.ts | 14 +- .../backup/electron-main/backupMainService.ts | 6 +- src/vs/platform/commands/common/commands.ts | 6 +- .../configuration/common/configuration.ts | 14 +- .../common/configurationModels.ts | 154 +- .../common/configurationRegistry.ts | 91 +- .../common/configurationService.ts | 36 +- .../configuration/common/configurations.ts | 190 - .../test/common/configuration.test.ts | 26 +- .../test/common/configurationModels.test.ts | 144 +- .../test/common/configurationRegistry.test.ts | 26 - .../test/common/configurationService.test.ts | 24 +- .../test/common/policyConfiguration.test.ts | 206 - .../contextkey/browser/contextKeyService.ts | 63 +- .../platform/contextkey/common/contextkey.ts | 84 +- .../platform/contextkey/common/contextkeys.ts | 1 - .../test/browser/contextkey.test.ts | 99 +- .../contextkey/test/common/contextkey.test.ts | 31 +- .../browser/contextMenuHandler.css | 5 +- .../contextview/browser/contextMenuHandler.ts | 15 +- .../contextview/browser/contextMenuService.ts | 4 +- .../contextview/browser/contextViewService.ts | 5 +- .../diagnostics/node/diagnosticsService.ts | 16 +- src/vs/platform/dialogs/common/dialogs.ts | 5 - .../electron-main/dialogMainService.ts | 3 +- src/vs/platform/dnd/browser/dnd.ts | 345 - .../download/common/downloadService.ts | 2 +- src/vs/platform/driver/browser/driver.ts | 2 +- src/vs/platform/environment/common/argv.ts | 5 +- .../environment/common/environment.ts | 12 +- .../environment/common/environmentService.ts | 31 +- .../electron-main/environmentMainService.ts | 4 + src/vs/platform/environment/node/argv.ts | 70 +- .../platform/environment/node/argvHelper.ts | 3 - src/vs/platform/environment/node/stdin.ts | 23 +- .../abstractExtensionManagementService.ts | 190 +- .../common/extensionEnablementService.ts | 16 +- .../common/extensionGalleryService.ts | 128 +- .../common/extensionManagement.ts | 80 +- .../common/extensionManagementCLIService.ts | 12 +- .../common/extensionManagementIpc.ts | 72 +- .../common/extensionManagementUtil.ts | 14 +- .../common/extensionNls.ts | 4 +- .../common/extensionStorage.ts | 25 +- .../common/extensionTipsService.ts | 5 +- .../common/extensionsProfileScannerService.ts | 129 - .../common/extensionsScannerService.ts | 311 +- .../common/unsupportedExtensionsMigration.ts | 15 +- .../defaultExtensionsProfileInit.ts | 27 - .../defaultExtensionsProfileInit.ts | 45 - .../electron-sandbox/extensionTipsService.ts | 20 +- .../extensionsScannerService.ts | 8 +- .../node/extensionLifecycle.ts | 6 +- .../node/extensionManagementService.ts | 262 +- .../node/extensionsScannerService.ts | 8 +- .../common/extensionGalleryService.test.ts | 5 +- .../node/extensionsScannerService.test.ts | 14 +- .../extensions/common/extensionHostStarter.ts | 8 +- .../extensions/common/extensionValidator.ts | 24 +- .../platform/extensions/common/extensions.ts | 8 +- .../electron-main/extensionHostStarter.ts | 417 - .../workerMainProcessExtensionHostStarter.ts | 173 + .../node/extensionHostStarterWorker.ts | 243 + .../node/extensionHostStarterWorkerMain.ts | 66 + .../test/common/extensionValidator.test.ts | 6 +- .../externalServices/common/marketplace.ts | 13 +- .../common/serviceMachineId.ts | 8 +- .../node/externalTerminalService.ts | 8 +- .../files/browser/htmlFileSystemProvider.ts | 2 +- .../browser/indexedDBFileSystemProvider.ts | 205 +- src/vs/platform/files/common/files.ts | 3 +- .../common/inMemoryFilesystemProvider.ts | 38 +- src/vs/platform/files/common/watcher.ts | 27 +- .../files/node/diskFileSystemProvider.ts | 11 +- .../node/watcher/nodejs/nodejsWatcher.ts | 2 +- .../node/watcher/nodejs/nodejsWatcherLib.ts | 2 +- .../node/watcher/parcel/parcelWatcher.ts | 38 +- ...onTest.ts => indexedDBFileService.test.ts} | 94 +- .../files/test/common/watcher.test.ts | 2 +- .../files/test/node/diskFileService.test.ts | 21 +- .../node/nodejsWatcher.integrationTest.ts | 4 +- .../node/parcelWatcher.integrationTest.ts | 24 +- .../browser/contextScopedHistoryWidget.ts | 92 +- src/vs/platform/instantiation/common/graph.ts | 12 +- .../common/instantiationService.ts | 36 +- .../instantiation/common/serviceCollection.ts | 2 +- .../instantiation/test/common/graph.test.ts | 2 +- .../test/common/instantiationService.test.ts | 66 +- .../test/common/instantiationServiceMock.ts | 53 +- src/vs/platform/issue/common/issue.ts | 1 - .../issue/electron-main/issueMainService.ts | 4 +- .../common/abstractKeybindingService.ts | 11 +- .../platform/keybinding/common/keybinding.ts | 12 +- .../keybinding/common/keybindingResolver.ts | 17 +- .../keybinding/common/keybindingsRegistry.ts | 3 +- .../common/resolvedKeybindingItem.ts | 2 +- .../common/abstractKeybindingService.test.ts | 29 +- .../test/common/mockKeybindingService.ts | 17 +- .../keyboardLayout/common/keyboardLayout.ts | 6 +- .../keyboardLayoutMainService.ts | 14 +- src/vs/platform/label/common/label.ts | 7 - .../languagePacks/browser/languagePacks.ts | 13 - .../languagePacks/common/languagePacks.ts | 91 - .../launch/electron-main/launchMainService.ts | 1 - .../platform/layout/browser/layoutService.ts | 13 +- src/vs/platform/lifecycle/common/lifecycle.ts | 2 +- .../electron-main/lifecycleMainService.ts | 2 +- src/vs/platform/list/browser/listService.ts | 229 +- .../common/localizedStrings.ts | 0 .../node/localizations.ts} | 67 +- src/vs/platform/log/common/bufferLog.ts | 4 +- src/vs/platform/log/node/spdlogLog.ts | 4 +- .../platform/markers/common/markerService.ts | 18 +- src/vs/platform/markers/common/markers.ts | 2 +- .../markers/test/common/markerService.test.ts | 24 +- .../platform/menubar/electron-main/menubar.ts | 8 +- src/vs/platform/native/common/native.ts | 9 +- .../electron-main/nativeHostMainService.ts | 38 +- .../notification/common/notification.ts | 33 +- .../test/common/testNotificationService.ts | 8 +- src/vs/platform/opener/common/opener.ts | 3 +- .../opener/test/common/opener.test.ts | 2 +- .../policy/common/filePolicyService.ts | 82 - src/vs/platform/policy/common/policy.ts | 64 - src/vs/platform/policy/common/policyIpc.ts | 76 - .../policy/node/nativePolicyService.ts | 44 - src/vs/platform/progress/common/progress.ts | 1 - .../electron-main/protocolMainService.ts | 4 +- .../quickinput/browser/commandsQuickAccess.ts | 8 +- .../quickinput/browser/helpQuickAccess.ts | 38 +- .../platform/quickinput/browser/quickInput.ts | 8 +- .../platform/quickinput/common/quickAccess.ts | 4 +- .../registry/test/common/platform.test.ts | 2 +- .../remote/browser/browserSocketFactory.ts | 4 +- .../browser/remoteAuthorityResolverService.ts | 14 +- .../remote/common/remoteAgentConnection.ts | 72 +- src/vs/platform/remote/common/remoteHosts.ts | 48 - .../remoteAuthorityResolverService.ts | 10 +- .../platform/remote/node/nodeSocketFactory.ts | 4 +- .../remote/test/common/remoteHosts.test.ts | 42 - .../remoteAuthorityResolverService.test.ts | 5 +- src/vs/platform/request/common/request.ts | 2 +- src/vs/platform/request/common/requestIpc.ts | 17 +- .../sharedProcessRequestService.ts | 47 - .../platform/request/node/requestService.ts | 7 +- .../electron-main/sharedProcess.ts | 8 +- .../sharedProcess/node/sharedProcess.ts | 8 - src/vs/platform/state/electron-main/state.ts | 6 +- .../state/electron-main/stateMainService.ts | 179 +- src/vs/platform/state/node/state.ts | 17 - src/vs/platform/state/node/stateService.ts | 171 - .../state/test/electron-main/state.test.ts | 4 +- .../storage/browser/storageService.ts | 205 +- src/vs/platform/storage/common/storage.ts | 239 +- src/vs/platform/storage/common/storageIpc.ts | 92 +- .../storage/electron-main/storageIpc.ts | 65 +- .../storage/electron-main/storageMain.ts | 76 +- .../electron-main/storageMainService.ts | 206 +- .../electron-sandbox/storageService.ts | 147 +- .../test/browser/storageService.test.ts | 36 +- .../test/common/storageService.test.ts | 56 +- .../electron-main/storageMainService.test.ts | 133 +- .../platform/telemetry/browser/1dsAppender.ts | 5 +- .../telemetry/browser/errorTelemetry.ts | 16 +- .../platform/telemetry/common/1dsAppender.ts | 20 +- .../telemetry/common/commonProperties.ts | 7 +- .../telemetry/common/errorTelemetry.ts | 10 +- src/vs/platform/telemetry/common/telemetry.ts | 10 +- .../telemetry/common/telemetryService.ts | 16 +- .../telemetry/common/telemetryUtils.ts | 28 +- src/vs/platform/telemetry/node/1dsAppender.ts | 5 +- .../test/browser/1dsAppender.test.ts | 18 +- .../test/browser/telemetryService.test.ts | 202 +- .../common/capabilities/capabilities.ts | 74 +- .../commandDetectionCapability.ts | 174 +- .../terminal/common/environmentVariable.ts | 3 - src/vs/platform/terminal/common/terminal.ts | 84 +- .../terminal/common/terminalDataBuffering.ts | 4 +- .../terminal/common/terminalEnvironment.ts | 23 - .../common/terminalPlatformConfiguration.ts | 42 +- .../terminal/common/terminalProcess.ts | 18 +- .../terminal/common/terminalProfiles.ts | 2 +- .../terminal/common/terminalStrings.ts | 34 - .../common/xterm/shellIntegrationAddon.ts | 137 +- src/vs/platform/terminal/node/ptyHostMain.ts | 22 +- .../platform/terminal/node/ptyHostService.ts | 6 +- src/vs/platform/terminal/node/ptyService.ts | 129 +- .../terminal/node/terminalEnvironment.ts | 30 +- .../platform/terminal/node/terminalProcess.ts | 13 +- .../terminal/node/terminalProfiles.ts | 3 +- .../test/common/terminalEnvironment.test.ts | 40 - .../test/node/terminalEnvironment.test.ts | 33 +- .../platform/theme/browser/iconsStyleSheet.ts | 4 +- src/vs/platform/theme/common/colorRegistry.ts | 49 +- src/vs/platform/theme/common/iconRegistry.ts | 31 +- src/vs/platform/theme/common/styler.ts | 30 +- src/vs/platform/theme/common/theme.ts | 4 - src/vs/platform/theme/common/themeService.ts | 4 +- .../common/tokenClassificationRegistry.ts | 14 +- .../theme/electron-main/themeMainService.ts | 3 +- .../theme/test/common/testThemeService.ts | 4 +- src/vs/platform/tunnel/common/tunnel.ts | 46 +- src/vs/platform/tunnel/node/tunnelService.ts | 3 +- .../undoRedo/common/undoRedoService.ts | 6 +- .../common/update.config.contribution.ts | 6 +- src/vs/platform/update/common/update.ts | 1 - src/vs/platform/update/common/updateIpc.ts | 5 - .../electron-main/abstractUpdateService.ts | 12 +- .../electron-main/updateService.darwin.ts | 4 +- .../electron-main/updateService.snap.ts | 5 - .../electron-main/updateService.win32.ts | 51 +- .../uriIdentity/common/uriIdentityService.ts | 2 +- .../test/common/uriIdentityService.test.ts | 22 +- .../userData/common/fileUserDataProvider.ts | 14 +- .../test/browser/fileUserDataProvider.test.ts | 54 +- .../browser/userDataProfile.ts | 88 - .../userDataProfile/common/userDataProfile.ts | 400 - .../electron-main/userDataProfile.ts | 64 - .../electron-sandbox/userDataProfile.ts | 70 - .../userDataProfile/node/userDataProfile.ts | 35 - .../common/userDataProfileService.test.ts | 65 - .../userDataProfileMainService.test.ts | 76 - .../common/abstractSynchronizer.ts | 33 +- .../userDataSync/common/extensionsMerge.ts | 4 +- .../userDataSync/common/extensionsSync.ts | 18 +- .../userDataSync/common/globalStateSync.ts | 44 +- .../userDataSync/common/keybindingsMerge.ts | 2 +- .../userDataSync/common/keybindingsSync.ts | 29 +- .../userDataSync/common/settingsSync.ts | 30 +- .../userDataSync/common/snippetsSync.ts | 52 +- .../platform/userDataSync/common/tasksSync.ts | 27 +- .../common/userDataAutoSyncService.ts | 36 +- .../userDataSync/common/userDataSync.ts | 7 +- .../common/userDataSyncEnablementService.ts | 14 +- .../common/userDataSyncMachines.ts | 4 +- .../common/userDataSyncService.ts | 23 +- .../common/userDataSyncServiceIpc.ts | 2 - .../common/userDataSyncStoreService.ts | 40 +- .../test/common/globalStateSync.test.ts | 8 +- .../test/common/keybindingsSync.test.ts | 37 +- .../test/common/settingsSync.test.ts | 25 +- .../test/common/snippetsSync.test.ts | 17 +- .../test/common/synchronizer.test.ts | 2 - .../test/common/tasksSync.test.ts | 66 +- .../common/userDataAutoSyncService.test.ts | 601 +- .../test/common/userDataSyncClient.ts | 29 +- .../test/common/userDataSyncService.test.ts | 61 +- .../common/userDataSyncStoreService.test.ts | 12 +- .../electron-main/webviewProtocolProvider.ts | 1 + src/vs/platform/window/common/window.ts | 30 +- .../platform/window/electron-main/window.ts | 6 +- .../platform/windows/electron-main/window.ts | 175 +- .../platform/windows/electron-main/windows.ts | 2 - .../electron-main/windowsMainService.ts | 65 +- .../test/electron-main/windowsFinder.test.ts | 2 +- .../workspace/test/common/workspace.test.ts | 10 +- .../platform/workspaces/common/workspaces.ts | 12 +- .../workspacesHistoryMainService.ts | 35 +- .../workspacesManagementMainService.ts | 7 - .../workspaces/test/common/workspaces.test.ts | 6 +- .../workspacesHistoryStorage.test.ts | 8 +- .../workspacesManagementMainService.test.ts | 12 +- src/vs/server/node/extensionHostConnection.ts | 152 +- .../server/node/extensionsScannerService.ts | 8 +- .../server/node/remoteAgentEnvironmentImpl.ts | 47 +- .../node/remoteExtensionHostAgentCli.ts | 26 +- .../node/remoteExtensionHostAgentServer.ts | 28 +- src/vs/server/node/remoteLanguagePacks.ts | 4 +- src/vs/server/node/remoteTerminalChannel.ts | 3 +- src/vs/server/node/server.cli.ts | 49 +- src/vs/server/node/server.main.ts | 9 +- .../server/node/serverEnvironmentService.ts | 2 - src/vs/server/node/serverServices.ts | 39 +- src/vs/server/node/webClientServer.ts | 30 +- .../api/browser/extensionHost.contribution.ts | 1 + .../api/browser/mainThreadAuthentication.ts | 25 +- .../api/browser/mainThreadBulkEdits.ts | 31 +- .../api/browser/mainThreadCodeInsets.ts | 11 +- .../api/browser/mainThreadCommands.ts | 13 +- .../api/browser/mainThreadComments.ts | 67 +- .../api/browser/mainThreadCustomEditors.ts | 1 - .../api/browser/mainThreadDebugService.ts | 17 +- .../api/browser/mainThreadDecorations.ts | 2 +- .../api/browser/mainThreadDiagnostics.ts | 4 +- .../api/browser/mainThreadDialogs.ts | 9 +- .../api/browser/mainThreadDocuments.ts | 8 +- .../browser/mainThreadDocumentsAndEditors.ts | 8 +- .../workbench/api/browser/mainThreadEditor.ts | 4 +- .../api/browser/mainThreadEditorTabs.ts | 24 +- .../api/browser/mainThreadEditors.ts | 6 +- .../workbench/api/browser/mainThreadErrors.ts | 4 +- .../api/browser/mainThreadExtensionService.ts | 3 + .../api/browser/mainThreadFileSystem.ts | 40 +- .../mainThreadFileSystemEventService.ts | 11 +- .../api/browser/mainThreadLabelService.ts | 2 +- .../api/browser/mainThreadLanguageFeatures.ts | 165 +- .../api/browser/mainThreadLanguages.ts | 2 +- .../api/browser/mainThreadNotebook.ts | 2 +- .../api/browser/mainThreadNotebookDto.ts | 1 - .../api/browser/mainThreadNotebookEditors.ts | 21 +- .../api/browser/mainThreadNotebookKernels.ts | 31 +- .../browser/mainThreadNotebookProxyKernels.ts | 130 + .../api/browser/mainThreadOutputService.ts | 2 +- .../api/browser/mainThreadProgress.ts | 4 +- src/vs/workbench/api/browser/mainThreadSCM.ts | 10 - .../workbench/api/browser/mainThreadSearch.ts | 4 +- .../api/browser/mainThreadStorage.ts | 2 +- .../workbench/api/browser/mainThreadTask.ts | 165 +- .../api/browser/mainThreadTerminalService.ts | 12 +- .../api/browser/mainThreadTesting.ts | 9 +- .../api/browser/mainThreadTreeViews.ts | 53 +- .../api/browser/mainThreadWebviewPanels.ts | 9 +- .../api/browser/mainThreadWebviews.ts | 2 +- .../api/browser/mainThreadWorkspace.ts | 2 +- .../api/browser/viewsExtensionPoint.ts | 58 +- .../api/common/configurationExtensionPoint.ts | 16 +- .../workbench/api/common/extHost.api.impl.ts | 66 +- .../workbench/api/common/extHost.protocol.ts | 159 +- .../api/common/extHostApiCommands.ts | 6 - .../api/common/extHostAuthentication.ts | 6 +- .../workbench/api/common/extHostBulkEdits.ts | 7 +- .../workbench/api/common/extHostCodeInsets.ts | 4 +- .../workbench/api/common/extHostCommands.ts | 23 +- .../workbench/api/common/extHostComments.ts | 47 +- .../api/common/extHostConfiguration.ts | 6 +- .../api/common/extHostConsoleForwarder.ts | 124 - .../api/common/extHostDebugService.ts | 8 +- .../api/common/extHostDecorations.ts | 10 +- .../api/common/extHostDiagnostics.ts | 33 +- .../api/common/extHostDocumentData.ts | 4 +- .../common/extHostDocumentSaveParticipant.ts | 10 +- .../workbench/api/common/extHostEditorTabs.ts | 18 +- .../api/common/extHostExtensionActivator.ts | 8 +- .../api/common/extHostExtensionService.ts | 33 +- .../workbench/api/common/extHostFileSystem.ts | 2 +- .../common/extHostFileSystemEventService.ts | 21 +- .../api/common/extHostInteractive.ts | 7 +- .../api/common/extHostLanguageFeatures.ts | 208 +- .../workbench/api/common/extHostLanguages.ts | 2 +- src/vs/workbench/api/common/extHostMemento.ts | 2 +- .../api/common/extHostMessageService.ts | 2 +- .../api/common/extHostNotebookDocument.ts | 2 +- .../api/common/extHostNotebookEditor.ts | 31 +- .../api/common/extHostNotebookEditors.ts | 33 +- .../api/common/extHostNotebookKernels.ts | 15 +- .../api/common/extHostNotebookProxyKernels.ts | 157 + .../api/common/extHostNotebookRenderers.ts | 18 +- .../workbench/api/common/extHostQuickOpen.ts | 32 +- .../api/common/extHostRequireInterceptor.ts | 14 +- src/vs/workbench/api/common/extHostSCM.ts | 29 +- src/vs/workbench/api/common/extHostTask.ts | 120 +- .../api/common/extHostTerminalService.ts | 22 +- src/vs/workbench/api/common/extHostTesting.ts | 2 +- .../workbench/api/common/extHostTreeViews.ts | 34 +- .../api/common/extHostTypeConverters.ts | 138 +- src/vs/workbench/api/common/extHostTypes.ts | 265 +- .../workbench/api/common/extHostWorkspace.ts | 6 +- .../common/jsonValidationExtensionPoint.ts | 2 +- .../api/common/shared/dataTransfer.ts | 43 + .../api/common/shared/dataTransferCache.ts | 42 - src/vs/workbench/api/common/shared/tasks.ts | 71 +- src/vs/workbench/api/node/extHostCLIServer.ts | 5 +- .../api/node/extHostConsoleForwarder.ts | 64 - .../workbench/api/node/extHostDebugService.ts | 2 +- .../api/node/extHostExtensionService.ts | 21 +- src/vs/workbench/api/node/extHostSearch.ts | 4 +- .../workbench/api/node/extHostStoragePaths.ts | 4 +- src/vs/workbench/api/node/extHostTask.ts | 12 +- .../api/node/extHostTunnelService.ts | 23 +- .../api/node/extensionHostProcess.ts | 121 +- src/vs/workbench/api/node/proxyResolver.ts | 2 +- .../test/browser/extHostApiCommands.test.ts | 100 +- .../browser/extHostAuthentication.test.ts | 96 +- .../api/test/browser/extHostBulkEdits.test.ts | 20 +- .../api/test/browser/extHostCommands.test.ts | 24 - .../test/browser/extHostConfiguration.test.ts | 67 +- .../test/browser/extHostDecorations.test.ts | 2 +- .../test/browser/extHostDiagnostics.test.ts | 72 +- .../test/browser/extHostDocumentData.test.ts | 43 +- .../extHostDocumentSaveParticipant.test.ts | 58 +- .../test/browser/extHostEditorTabs.test.ts | 41 +- .../browser/extHostLanguageFeatures.test.ts | 85 +- .../browser/extHostMessagerService.test.ts | 15 +- .../api/test/browser/extHostNotebook.test.ts | 20 +- .../browser/extHostNotebookKernel.test.ts | 6 +- .../api/test/browser/extHostTesting.test.ts | 8 +- .../test/browser/extHostTextEditor.test.ts | 8 +- .../api/test/browser/extHostTreeViews.test.ts | 23 +- .../test/browser/extHostTypeConverter.test.ts | 15 +- .../api/test/browser/extHostTypes.test.ts | 72 +- .../api/test/browser/extHostWorkspace.test.ts | 12 +- .../browser/mainThreadConfiguration.test.ts | 2 +- .../browser/mainThreadDiagnostics.test.ts | 6 +- ...mainThreadDocumentContentProviders.test.ts | 6 +- .../test/browser/mainThreadDocuments.test.ts | 4 +- .../mainThreadDocumentsAndEditors.test.ts | 2 +- .../test/browser/mainThreadEditors.test.ts | 41 +- .../test/browser/mainThreadTreeViews.test.ts | 2 +- .../api/test/common/testRPCProtocol.ts | 8 +- .../api/test/node/extHostSearch.test.ts | 4 +- .../api/worker/extHostConsoleForwarder.ts | 22 - .../api/worker/extHostExtensionService.ts | 85 +- src/vs/workbench/browser/actions.ts | 2 +- .../browser/actions/developerActions.ts | 6 +- .../browser/actions/layoutActions.ts | 34 +- .../workbench/browser/actions/listCommands.ts | 54 +- .../browser/actions/quickAccessActions.ts | 5 +- .../browser/actions/windowActions.ts | 4 +- src/vs/workbench/browser/codeeditor.ts | 9 +- src/vs/workbench/browser/composite.ts | 4 +- src/vs/workbench/browser/contextkeys.ts | 7 +- src/vs/workbench/browser/dnd.ts | 376 +- src/vs/workbench/browser/labels.ts | 25 +- src/vs/workbench/browser/layout.ts | 157 +- src/vs/workbench/browser/layoutState.ts | 38 +- src/vs/workbench/browser/media/style.css | 48 +- src/vs/workbench/browser/panecomposite.ts | 2 +- src/vs/workbench/browser/part.ts | 2 +- .../parts/activitybar/activitybarActions.ts | 10 +- .../parts/activitybar/activitybarPart.ts | 39 +- .../parts/auxiliarybar/auxiliaryBarActions.ts | 18 +- .../browser/parts/banner/media/bannerpart.css | 2 - .../workbench/browser/parts/compositeBar.ts | 10 +- .../workbench/browser/parts/compositePart.ts | 12 +- .../browser/parts/editor/breadcrumbs.ts | 4 +- .../parts/editor/breadcrumbsControl.ts | 46 +- .../browser/parts/editor/breadcrumbsModel.ts | 15 +- .../browser/parts/editor/breadcrumbsPicker.ts | 2 +- .../parts/editor/editor.contribution.ts | 46 +- .../workbench/browser/parts/editor/editor.ts | 2 + .../browser/parts/editor/editorActions.ts | 104 +- .../browser/parts/editor/editorCommands.ts | 16 +- .../browser/parts/editor/editorDropTarget.ts | 21 +- .../browser/parts/editor/editorGroupView.ts | 80 +- .../browser/parts/editor/editorPane.ts | 2 +- .../browser/parts/editor/editorPart.ts | 40 +- .../browser/parts/editor/editorPlaceholder.ts | 8 +- .../browser/parts/editor/editorStatus.ts | 4 +- .../parts/editor/editorWithViewState.ts | 4 +- .../parts/editor/media/editorplaceholder.css | 4 +- .../parts/editor/media/notabstitlecontrol.css | 2 +- .../parts/editor/media/titlecontrol.css | 8 +- .../browser/parts/editor/tabsTitleControl.ts | 24 +- .../browser/parts/editor/textCodeEditor.ts | 112 - .../browser/parts/editor/textDiffEditor.ts | 149 +- .../browser/parts/editor/textEditor.ts | 191 +- .../parts/editor/textResourceEditor.ts | 65 +- .../notifications/notificationsActions.ts | 21 +- .../notifications/notificationsCenter.ts | 20 +- .../notifications/notificationsCommands.ts | 12 +- .../notifications/notificationsStatus.ts | 19 +- .../notifications/notificationsToasts.ts | 6 +- .../parts/panel/media/basepanelpart.css | 4 +- .../browser/parts/panel/panelActions.ts | 13 +- .../browser/parts/panel/panelPart.ts | 28 +- .../parts/statusbar/media/statusbarpart.css | 23 +- .../browser/parts/statusbar/statusbarItem.ts | 23 +- .../browser/parts/statusbar/statusbarModel.ts | 18 +- .../browser/parts/statusbar/statusbarPart.ts | 6 +- .../parts/titlebar/commandCenterControl.ts | 199 - .../parts/titlebar/media/titlebarpart.css | 158 +- .../browser/parts/titlebar/menubarControl.ts | 63 +- .../browser/parts/titlebar/titlebarPart.ts | 496 +- .../browser/parts/titlebar/windowTitle.ts | 249 - .../workbench/browser/parts/views/treeView.ts | 308 +- .../workbench/browser/parts/views/viewPane.ts | 6 +- .../browser/parts/views/viewPaneContainer.ts | 11 +- .../browser/parts/views/viewsViewlet.ts | 2 +- src/vs/workbench/browser/web.api.ts | 31 +- src/vs/workbench/browser/web.factory.ts | 24 +- src/vs/workbench/browser/web.main.ts | 100 +- src/vs/workbench/browser/window.ts | 26 +- .../browser/workbench.contribution.ts | 51 +- src/vs/workbench/browser/workbench.ts | 15 +- src/vs/workbench/common/actions.ts | 2 +- src/vs/workbench/common/configuration.ts | 91 - src/vs/workbench/common/contextkeys.ts | 20 +- src/vs/workbench/common/contributions.ts | 4 +- .../vs/workbench/common/dnd.ts | 7 +- src/vs/workbench/common/editor.ts | 87 +- .../common/editor/editorGroupModel.ts | 4 +- src/vs/workbench/common/editor/editorInput.ts | 45 +- .../common/editor/sideBySideEditorInput.ts | 10 +- .../common/editor/textResourceEditorInput.ts | 4 +- src/vs/workbench/common/memento.ts | 84 +- src/vs/workbench/common/theme.ts | 6 +- src/vs/workbench/common/views.ts | 6 +- .../browser/audioCueDebuggerContribution.ts | 2 +- .../audioCueLineFeatureContribution.ts | 35 +- .../audioCues/browser/audioCueService.ts | 12 +- .../contrib/audioCues/browser/observable.ts | 614 ++ ...ketPairColorizer2Telemetry.contribution.ts | 55 - .../contrib/bulkEdit/browser/bulkCellEdits.ts | 28 +- .../bulkEdit/browser/bulkEditService.ts | 12 +- .../contrib/bulkEdit/browser/bulkFileEdits.ts | 2 +- .../contrib/bulkEdit/browser/bulkTextEdits.ts | 60 +- .../contrib/bulkEdit/browser/conflicts.ts | 4 +- .../browser/preview/bulkEdit.contribution.ts | 17 +- .../bulkEdit/browser/preview/bulkEditPane.ts | 12 +- .../browser/preview/bulkEditPreview.ts | 14 +- .../bulkEdit/browser/preview/bulkEditTree.ts | 34 +- .../browser/callHierarchy.contribution.ts | 4 +- .../browser/callHierarchyPeek.ts | 12 +- .../browser/callHierarchyTree.ts | 3 +- .../browser/accessibility/accessibility.ts | 4 +- .../browser/editorSettingsMigration.ts | 75 +- .../browser/find/simpleFindWidget.css | 1 + .../browser/find/simpleFindWidget.ts | 31 +- .../inspectEditorTokens.ts | 45 +- .../languageConfigurationExtensionPoint.ts | 22 +- .../browser/outline/documentSymbolsOutline.ts | 19 +- .../quickaccess/gotoLineQuickAccess.ts | 25 +- .../quickaccess/gotoSymbolQuickAccess.ts | 32 +- .../codeEditor/browser/saveParticipants.ts | 11 +- .../suggestEnabledInput.ts | 48 +- .../codeEditor/browser/toggleMinimap.ts | 2 +- .../browser/untitledTextEditorHint.ts | 97 +- .../electron-sandbox/selectionClipboard.ts | 8 +- .../test/browser/saveParticipant.test.ts | 8 +- .../comments/browser/commentFormActions.ts | 10 +- .../comments/browser/commentGlyphWidget.ts | 16 +- .../contrib/comments/browser/commentNode.ts | 55 +- .../contrib/comments/browser/commentReply.ts | 41 +- .../comments/browser/commentService.ts | 41 +- .../comments/browser/commentThreadBody.ts | 26 +- .../comments/browser/commentThreadHeader.ts | 2 +- .../browser/commentThreadRangeDecorator.ts | 63 +- .../comments/browser/commentThreadWidget.ts | 13 +- .../browser/commentThreadZoneWidget.ts | 30 +- .../browser/commentsEditorContribution.ts | 219 +- .../comments/browser/commentsTreeViewer.ts | 23 +- .../contrib/comments/browser/commentsView.ts | 10 +- .../contrib/comments/browser/media/review.css | 9 +- .../comments/browser/reactionsAction.ts | 10 +- .../comments/browser/simpleCommentEditor.ts | 4 +- .../contrib/comments/common/commentModel.ts | 2 +- .../configurationExportHelper.ts | 8 +- .../customEditor/browser/customEditorInput.ts | 26 +- .../browser/customEditorInputFactory.ts | 26 +- .../customEditor/browser/customEditors.ts | 25 +- .../common/contributedCustomEditors.ts | 4 +- .../customEditor/common/extensionPoint.ts | 23 +- .../contrib/debug/browser/baseDebugView.ts | 30 +- .../browser/breakpointEditorContribution.ts | 153 +- .../contrib/debug/browser/breakpointWidget.ts | 2 +- .../contrib/debug/browser/breakpointsView.ts | 177 +- .../browser/callStackEditorContribution.ts | 6 +- .../contrib/debug/browser/callStackView.ts | 13 +- .../debug/browser/debug.contribution.ts | 57 +- .../debug/browser/debugAdapterManager.ts | 95 +- .../contrib/debug/browser/debugCommands.ts | 378 +- .../browser/debugConfigurationManager.ts | 41 +- .../debug/browser/debugConsoleQuickAccess.ts | 68 - .../debug/browser/debugEditorActions.ts | 83 +- .../debug/browser/debugEditorContribution.ts | 11 +- .../contrib/debug/browser/debugHover.ts | 10 +- .../contrib/debug/browser/debugIcons.ts | 1 - .../contrib/debug/browser/debugQuickAccess.ts | 8 +- .../contrib/debug/browser/debugService.ts | 29 +- .../contrib/debug/browser/debugSession.ts | 17 +- .../debug/browser/debugSessionPicker.ts | 124 - .../contrib/debug/browser/debugStatus.ts | 4 +- .../contrib/debug/browser/debugTaskRunner.ts | 14 +- .../contrib/debug/browser/debugToolBar.ts | 18 +- .../contrib/debug/browser/debugViewlet.ts | 2 +- .../contrib/debug/browser/disassemblyView.ts | 49 +- .../browser/extensionHostDebugService.ts | 6 +- .../contrib/debug/browser/linkDetector.ts | 21 +- .../debug/browser/loadedScriptsView.ts | 5 +- .../browser/media/debug.contribution.css | 22 +- .../debug/browser/media/debugViewlet.css | 13 +- .../debug/browser/media/exceptionWidget.css | 2 - .../contrib/debug/browser/media/repl.css | 12 +- .../workbench/contrib/debug/browser/repl.ts | 7 +- .../contrib/debug/browser/replViewer.ts | 1 - .../contrib/debug/browser/variablesView.ts | 5 +- .../debug/browser/watchExpressionsView.ts | 46 +- .../contrib/debug/browser/welcomeView.ts | 2 +- .../debug/common/abstractDebugAdapter.ts | 8 +- .../workbench/contrib/debug/common/debug.ts | 38 +- .../debug/common/debugContentProvider.ts | 4 +- .../contrib/debug/common/debugModel.ts | 46 +- .../contrib/debug/common/debugProtocol.d.ts | 755 +- .../contrib/debug/common/debugSchemas.ts | 5 - .../contrib/debug/common/debugTelemetry.ts | 2 - .../contrib/debug/common/debugUtils.ts | 4 +- .../contrib/debug/common/debugViewModel.ts | 2 +- .../contrib/debug/common/debugger.ts | 16 +- .../debug/common/loadedScriptsPicker.ts | 108 - .../contrib/debug/node/debugAdapter.ts | 4 +- .../workbench/contrib/debug/node/terminals.ts | 22 +- .../debug/test/browser/baseDebugView.test.ts | 2 +- .../debug/test/browser/breakpoints.test.ts | 23 +- .../contrib/debug/test/browser/mockDebug.ts | 4 - .../test/node/streamDebugAdapter.test.ts | 10 +- .../contrib/debug/test/node/terminals.test.ts | 118 - ...eprecatedExtensionMigrator.contribution.ts | 103 - .../browser/dropIntoEditor.contibution.ts | 151 + .../browser/editSessions.contribution.ts | 601 -- .../browser/editSessionsContentProvider.ts | 34 - .../editSessions/browser/editSessionsViews.ts | 188 - .../browser/editSessionsWorkbenchService.ts | 388 - .../editSessions/common/editSessions.ts | 81 - .../common/editSessionsLogService.ts | 50 - .../test/browser/editSessions.test.ts | 151 - .../contrib/emmet/browser/emmetActions.ts | 6 +- .../emmet/test/browser/emmetAction.test.ts | 2 +- .../experiments/browser/experimentalPrompt.ts | 4 +- .../experiments/common/experimentService.ts | 46 +- .../experimentService.test.ts | 23 +- .../abstractRuntimeExtensionsEditor.ts | 24 +- .../dynamicWorkspaceRecommendations.ts | 6 +- .../extensions/browser/extensionEditor.ts | 219 +- ...ensionRecommendationNotificationService.ts | 16 +- .../extensionRecommendationsService.ts | 7 +- .../browser/extensions.contribution.ts | 61 +- .../extensions/browser/extensionsActions.ts | 412 +- .../extensions/browser/extensionsCleaner.ts | 19 + .../extensions/browser/extensionsIcons.ts | 1 - .../extensions/browser/extensionsList.ts | 43 +- .../extensions/browser/extensionsViewer.ts | 6 +- .../extensions/browser/extensionsViewlet.ts | 61 +- .../extensions/browser/extensionsViews.ts | 80 +- .../extensions/browser/extensionsWidgets.ts | 199 +- .../browser/extensionsWorkbenchService.ts | 192 +- .../browser/fileBasedRecommendations.ts | 34 +- .../extensions/browser/media/extension.css | 26 +- .../browser/media/extensionActions.css | 2 - .../browser/media/extensionEditor.css | 60 +- .../browser/media/extensionsWidgets.css | 5 + .../extensions/common/extensionQuery.ts | 2 +- .../contrib/extensions/common/extensions.ts | 16 +- .../extensionProfileService.ts | 4 +- .../extensionsAutoProfiler.ts | 24 +- .../electron-sandbox/remoteExtensionsInit.ts | 8 +- .../reportExtensionIssueAction.ts | 6 +- .../runtimeExtensionsEditor.ts | 6 +- .../test/common/extensionQuery.test.ts | 2 +- .../extensionRecommendationsService.test.ts | 37 +- .../extensionsActions.test.ts | 124 +- .../electron-browser/extensionsViews.test.ts | 13 +- .../extensionsWorkbenchService.test.ts | 52 +- .../externalTerminal.contribution.ts | 2 +- .../common/contributedOpeners.ts | 2 +- .../files/browser/editors/textFileEditor.ts | 63 +- .../editors/textFileSaveErrorHandler.ts | 6 +- .../contrib/files/browser/explorerService.ts | 8 +- .../contrib/files/browser/explorerViewlet.ts | 8 +- .../contrib/files/browser/fileActions.ts | 24 +- .../contrib/files/browser/fileCommands.ts | 46 +- .../contrib/files/browser/fileConstants.ts | 1 - .../contrib/files/browser/fileImportExport.ts | 8 +- .../files/browser/files.contribution.ts | 18 +- .../workbench/contrib/files/browser/files.ts | 4 +- .../views/explorerDecorationsProvider.ts | 4 +- .../files/browser/views/explorerView.ts | 58 +- .../files/browser/views/explorerViewer.ts | 105 +- .../files/browser/views/openEditorsView.ts | 13 +- .../contrib/files/common/explorerModel.ts | 18 +- .../workbench/contrib/files/common/files.ts | 3 - .../test/browser/fileEditorInput.test.ts | 4 +- .../format/browser/formatActionsMultiple.ts | 27 +- .../format/browser/formatActionsNone.ts | 5 +- .../contrib/format/browser/formatModified.ts | 2 +- .../browser/inlayHintsAccessibilty.ts | 14 +- .../browser/interactive.contribution.ts | 100 +- .../interactive/browser/interactiveCommon.ts | 5 - .../interactive/browser/interactiveEditor.ts | 147 +- .../browser/interactiveEditorInput.ts | 129 +- .../browser/languageDetection.contribution.ts | 8 +- .../browser/languageStatus.contribution.ts | 26 +- .../contrib/list/browser/list.contribution.ts | 12 +- .../browser/localHistoryCommands.ts | 18 +- .../localization/browser/localeService.ts | 64 - .../browser/localization.contribution.ts | 16 - .../browser/localizationsActions.ts | 93 - .../contrib/localization/common/locale.ts | 15 - .../electron-sandbox/localeService.ts | 147 - .../browser/localizations.contribution.ts} | 42 +- .../browser/localizationsActions.ts | 87 + .../browser}/minimalTranslations.ts | 0 .../contrib/logs/common/logConstants.ts | 1 - .../contrib/logs/common/logs.contribution.ts | 1 - .../contrib/markers/browser/constants.ts | 31 + .../markers/browser/markers.contribution.ts | 177 +- .../contrib/markers/browser/markers.ts | 29 +- .../markers/browser/markersFileDecorations.ts | 4 +- .../contrib/markers/browser/markersModel.ts | 20 +- .../contrib/markers/browser/markersTable.ts | 562 -- .../markers/browser/markersTreeViewer.ts | 51 +- .../contrib/markers/browser/markersView.ts | 648 +- .../markers/browser/markersViewActions.ts | 4 +- .../contrib/markers/browser/media/markers.css | 80 - .../contrib/markers/browser/messages.ts | 1 - .../contrib/markers/common/markers.ts | 39 - .../markers/test/browser/markersModel.test.ts | 6 +- .../mergeEditor/browser/commands/commands.ts | 449 - .../browser/commands/devCommands.ts | 166 - .../browser/mergeEditor.contribution.ts | 64 - .../mergeEditor/browser/mergeEditorInput.ts | 278 - .../browser/mergeEditorSerializer.ts | 53 - .../mergeEditor/browser/model/diffComputer.ts | 166 - .../mergeEditor/browser/model/editing.ts | 70 - .../mergeEditor/browser/model/lineRange.ts | 114 - .../mergeEditor/browser/model/mapping.ts | 268 - .../browser/model/mergeEditorModel.ts | 351 - .../browser/model/modifiedBaseRange.ts | 315 - .../browser/model/textModelDiffs.ts | 216 - .../contrib/mergeEditor/browser/utils.ts | 160 - .../mergeEditor/browser/view/colors.ts | 56 - .../mergeEditor/browser/view/editorGutter.ts | 146 - .../browser/view/editors/codeEditorView.ts | 115 - .../view/editors/inputCodeEditorView.ts | 378 - .../view/editors/resultCodeEditorView.ts | 144 - .../browser/view/media/mergeEditor.css | 123 - .../mergeEditor/browser/view/mergeEditor.ts | 655 -- .../mergeEditor/browser/view/viewModel.ts | 159 - .../contrib/mergeEditor/common/mergeEditor.ts | 14 - .../mergeEditor/test/browser/model.test.ts | 367 - .../contrib/cellCommands/cellCommands.ts | 90 +- .../executionStatusBarItemController.ts | 53 +- .../cellStatusBar/statusBarProviders.ts | 46 +- .../contrib/clipboard/notebookClipboard.ts | 8 +- .../editorStatusBar/editorStatusBar.ts | 296 +- .../browser/contrib/find/notebookFind.ts | 48 +- .../find/notebookFindReplaceWidget.css | 7 +- .../contrib/find/notebookFindReplaceWidget.ts | 92 +- .../contrib/find/notebookFindWidget.ts | 4 +- .../browser/contrib/format/formatting.ts | 2 +- .../gettingStarted/notebookGettingStarted.ts | 9 +- .../browser/contrib/navigation/arrow.ts | 89 +- .../contrib/outline/notebookOutline.ts | 8 +- .../browser/contrib/troubleshoot/layout.ts | 82 +- .../viewportCustomMarkdown.ts | 2 +- .../notebook/browser/controller/apiActions.ts | 6 +- .../browser/controller/cellOperations.ts | 2 +- .../browser/controller/coreActions.ts | 13 +- .../browser/controller/editActions.ts | 44 +- .../browser/controller/executeActions.ts | 101 +- .../browser/controller/insertCellActions.ts | 14 +- .../browser/controller/layoutActions.ts | 20 +- .../notebook/browser/diff/diffComponents.ts | 6 +- .../browser/diff/notebookDiffEditorBrowser.ts | 4 +- .../browser/diff/notebookTextDiffEditor.ts | 9 +- .../browser/diff/notebookTextDiffList.ts | 23 +- .../cell-resize-above-viewport.drawio.svg | 406 +- .../notebook/browser/docs/notebook.layout.md | 9 +- .../notebook/browser/extensionPoint.ts | 213 +- .../browser/media/notebookToolbar.css | 4 - .../notebook/browser/notebook.contribution.ts | 5 +- .../notebook/browser/notebookBrowser.ts | 51 +- .../notebook/browser/notebookEditor.ts | 47 +- .../notebook/browser/notebookEditorService.ts | 5 + .../browser/notebookEditorServiceImpl.ts | 19 + .../notebook/browser/notebookEditorWidget.ts | 369 +- .../browser/notebookExecutionServiceImpl.ts | 90 +- .../notebookExecutionStateServiceImpl.ts | 51 +- .../browser/notebookKernelServiceImpl.ts | 109 +- .../notebook/browser/notebookServiceImpl.ts | 63 +- .../services/notebookKeymapServiceImpl.ts | 2 +- .../browser/view/cellParts/cellActionView.ts | 22 +- .../view/cellParts/cellDragRenderer.ts | 5 +- .../browser/view/cellParts/cellExecution.ts | 25 +- .../browser/view/cellParts/cellOutput.ts | 8 +- .../browser/view/cellParts/cellToolbars.ts | 51 +- .../browser/view/cellParts/codeCell.ts | 3 +- .../browser/view/cellParts/foldedCellHint.ts | 2 +- .../browser/view/cellParts/markdownCell.ts | 9 +- .../notebook/browser/view/notebookCellList.ts | 93 +- .../browser/view/notebookRenderingCommon.ts | 3 +- .../view/renderers/backLayerWebView.ts | 86 +- .../browser/view/renderers/cellRenderer.ts | 5 +- .../browser/view/renderers/webviewMessages.ts | 12 +- .../browser/view/renderers/webviewPreloads.ts | 160 +- .../browser/viewModel/baseCellViewModel.ts | 54 +- .../viewModel/notebookViewModelImpl.ts | 9 +- .../viewParts/notebookEditorDecorations.ts | 205 + .../viewParts/notebookEditorToolbar.ts | 10 +- .../notebookEditorWidgetContextKeys.ts | 24 +- .../viewParts/notebookKernelActionViewItem.ts | 66 +- .../viewParts/notebookTopCellToolbar.ts | 2 +- .../contrib/notebook/common/notebookCommon.ts | 18 +- .../notebook/common/notebookContextKeys.ts | 3 - .../notebook/common/notebookEditorInput.ts | 6 +- .../common/notebookExecutionService.ts | 1 - .../common/notebookExecutionStateService.ts | 8 +- .../notebook/common/notebookKernelService.ts | 43 +- .../notebook/common/notebookOptions.ts | 4 +- .../notebook/common/notebookPerformance.ts | 36 +- .../common/services/notebookSimpleWorker.ts | 4 +- .../notebook/test/browser/cellDnd.test.ts | 2 +- .../browser/notebookExecutionService.test.ts | 20 +- .../notebookExecutionStateService.test.ts | 24 +- .../browser/notebookKernelService.test.ts | 15 +- .../test/browser/notebookServiceImpl.test.ts | 4 +- .../test/browser/testNotebookEditor.ts | 14 +- .../contrib/outline/browser/outlinePane.ts | 15 +- .../outline/browser/outlineViewState.ts | 2 +- .../contrib/output/browser/logViewer.ts | 5 +- .../contrib/output/browser/outputServices.ts | 8 +- .../contrib/output/browser/outputView.ts | 12 +- .../output/common/outputChannelModel.ts | 28 +- .../test/browser/outputLinkProvider.test.ts | 12 +- .../browser/performance.web.contribution.ts | 6 +- .../performance/browser/perfviewEditor.ts | 16 +- .../preferences/browser/keybindingsEditor.ts | 36 +- .../browser/keybindingsEditorContribution.ts | 20 +- .../browser/keyboardLayoutPicker.ts | 18 +- .../browser/media/settingsEditor2.css | 42 +- .../browser/media/settingsWidgets.css | 3 +- .../browser/preferences.contribution.ts | 288 +- .../browser/preferencesRenderers.ts | 55 +- .../preferences/browser/preferencesSearch.ts | 2 +- .../preferences/browser/preferencesWidgets.ts | 41 +- .../preferences/browser/settingsEditor2.ts | 133 +- .../settingsEditorSettingIndicators.ts | 333 - .../preferences/browser/settingsSearchMenu.ts | 8 +- .../preferences/browser/settingsTree.ts | 337 +- .../preferences/browser/settingsTreeModels.ts | 164 +- .../contrib/preferences/browser/tocTree.ts | 7 +- .../contrib/preferences/common/preferences.ts | 4 - .../common/preferencesContribution.ts | 58 +- .../test/common/smartSnippetInserter.test.ts | 6 +- .../profiles/common/profiles.contribution.ts} | 2 +- .../profiles/common/profilesActions.ts | 136 + .../browser/commandsQuickAccess.ts | 7 +- .../browser/quickAccess.contribution.ts | 6 +- .../quickaccess/browser/viewQuickAccess.ts | 21 +- .../browser/relauncher.contribution.ts | 27 +- .../remote/browser/explorerViewItems.ts | 4 +- .../contrib/remote/browser/remote.ts | 65 +- .../contrib/remote/browser/remoteExplorer.ts | 3 +- .../contrib/remote/browser/remoteIndicator.ts | 29 +- .../contrib/remote/browser/tunnelView.ts | 122 +- .../remote/common/remote.contribution.ts | 74 +- .../electron-sandbox/remote.contribution.ts | 25 +- .../workbench/contrib/scm/browser/activity.ts | 10 +- .../contrib/scm/browser/media/scm.css | 14 - .../contrib/scm/browser/scmViewPane.ts | 193 +- .../contrib/scm/browser/scmViewService.ts | 2 +- src/vs/workbench/contrib/scm/browser/util.ts | 2 +- src/vs/workbench/contrib/scm/common/scm.ts | 5 - .../contrib/scm/common/scmService.ts | 40 +- .../search/browser/media/searchview.css | 4 +- .../search/browser/search.contribution.ts | 70 +- .../contrib/search/browser/searchActions.ts | 314 +- .../search/browser/searchResultsView.ts | 2 +- .../contrib/search/browser/searchView.ts | 29 +- .../workbench/contrib/search/common/search.ts | 2 +- .../contrib/search/common/searchModel.ts | 148 +- .../search/test/browser/searchViewlet.test.ts | 97 +- .../search/test/common/searchModel.test.ts | 4 +- .../search/test/common/searchResult.test.ts | 3 - .../browser/searchEditor.contribution.ts | 47 +- .../searchEditor/browser/searchEditor.ts | 34 +- .../browser/searchEditorActions.ts | 4 +- .../searchEditor/browser/searchEditorInput.ts | 2 +- .../commands/abstractSnippetsActions.ts | 29 - .../browser/commands/fileTemplateSnippets.ts | 116 - .../browser/commands/surroundWithSnippet.ts | 78 - .../{commands => }/configureSnippets.ts | 45 +- .../browser/{commands => }/insertSnippet.ts | 41 +- .../browser/snippetCodeActionProvider.ts | 153 - .../browser/snippetCompletionProvider.ts | 24 +- .../contrib/snippets/browser/snippetPicker.ts | 7 +- .../snippets/browser/snippets.contribution.ts | 66 +- .../contrib/snippets/browser/snippets.ts | 33 - .../contrib/snippets/browser/snippetsFile.ts | 51 +- .../snippets/browser/snippetsService.ts | 162 +- .../snippets/browser/surroundWithSnippet.ts | 60 + .../contrib/snippets/browser/tabCompletion.ts | 2 +- .../snippets/test/browser/snippetFile.test.ts | 25 +- .../test/browser/snippetsRegistry.test.ts | 4 +- .../test/browser/snippetsRewrite.test.ts | 5 +- .../test/browser/snippetsService.test.ts | 207 +- .../surveys/browser/ces.contribution.ts | 15 +- .../browser/languageSurveys.contribution.ts | 38 +- .../surveys/browser/nps.contribution.ts | 26 +- .../tags/electron-sandbox/workspaceTags.ts | 5 +- .../electron-sandbox/workspaceTagsService.ts | 16 +- .../tasks/browser/abstractTaskService.ts | 1596 ++-- .../tasks/browser/runAutomaticTasks.ts | 113 +- .../tasks/browser/task.contribution.ts | 113 +- .../contrib/tasks/browser/taskQuickPick.ts | 194 +- .../contrib/tasks/browser/taskService.ts | 12 +- .../tasks/browser/taskTerminalStatus.ts | 72 +- .../contrib/tasks/browser/tasksQuickAccess.ts | 34 +- .../tasks/browser/terminalTaskSystem.ts | 1208 ++- .../contrib/tasks/common/jsonSchema_v1.ts | 8 +- .../contrib/tasks/common/jsonSchema_v2.ts | 67 +- .../contrib/tasks/common/problemCollectors.ts | 127 +- .../contrib/tasks/common/problemMatcher.ts | 294 +- .../contrib/tasks/common/taskConfiguration.ts | 523 +- .../tasks/common/taskDefinitionRegistry.ts | 45 +- .../contrib/tasks/common/taskService.ts | 39 +- .../contrib/tasks/common/taskSystem.ts | 55 +- .../contrib/tasks/common/taskTemplates.ts | 14 +- .../workbench/contrib/tasks/common/tasks.ts | 244 +- .../tasks/electron-sandbox/taskService.ts | 31 +- .../test/browser/taskTerminalStatus.test.ts | 140 - ...guration.test.ts => configuration.test.ts} | 449 +- .../tasks/test/common/problemMatcher.test.ts | 60 +- .../browser/telemetry.contribution.ts | 74 +- .../contrib/terminal/browser/links/links.ts | 16 +- .../links/terminalExternalLinkDetector.ts | 11 +- .../links/terminalLinkDetectorAdapter.ts | 11 +- .../browser/links/terminalLinkHelpers.ts | 4 - .../browser/links/terminalLinkManager.ts | 25 +- .../browser/links/terminalLinkOpeners.ts | 134 +- .../browser/links/terminalLinkQuickpick.ts | 21 +- .../links/terminalLocalLinkDetector.ts | 9 +- .../terminalShellIntegrationLinkDetector.ts | 70 + .../browser/links/terminalUriLinkDetector.ts | 30 +- .../browser/links/terminalWordLinkDetector.ts | 4 - .../browser/media/shellIntegration-bash.sh | 189 +- .../browser/media/shellIntegration-env.zsh | 8 +- .../browser/media/shellIntegration-login.zsh | 9 - .../media/shellIntegration-profile.zsh | 8 +- .../browser/media/shellIntegration.ps1 | 25 +- ...ntegration-rc.zsh => shellIntegration.zsh} | 44 +- .../terminal/browser/media/terminal.css | 35 +- .../contrib/terminal/browser/media/xterm.css | 11 +- .../contrib/terminal/browser/remotePty.ts | 4 +- .../terminal/browser/remoteTerminalBackend.ts | 14 - .../terminal/browser/terminal.contribution.ts | 31 +- .../contrib/terminal/browser/terminal.ts | 113 +- .../terminal/browser/terminalActions.ts | 158 +- .../terminal/browser/terminalConfigHelper.ts | 2 +- .../terminal/browser/terminalEditor.ts | 8 +- .../terminal/browser/terminalEditorInput.ts | 39 +- .../browser/terminalEditorSerializer.ts | 6 +- .../terminal/browser/terminalEditorService.ts | 11 +- .../browser/terminalEscapeSequences.ts | 111 - .../terminal/browser/terminalFindWidget.ts | 49 +- .../contrib/terminal/browser/terminalGroup.ts | 46 +- .../terminal/browser/terminalGroupService.ts | 45 +- .../contrib/terminal/browser/terminalIcon.ts | 7 +- .../terminal/browser/terminalInstance.ts | 541 +- .../browser/terminalInstanceService.ts | 6 - .../browser/terminalMainContribution.ts | 59 +- .../contrib/terminal/browser/terminalMenus.ts | 13 +- .../browser/terminalProcessManager.ts | 126 +- .../browser/terminalProfileQuickpick.ts | 5 +- .../browser/terminalProfileResolverService.ts | 23 +- .../browser/terminalProfileService.ts | 2 +- .../terminal/browser/terminalQuickAccess.ts | 22 +- .../terminal/browser/terminalService.ts | 82 +- .../terminal/browser/terminalStatusList.ts | 1 - .../terminal/browser/terminalTabbedView.ts | 4 +- .../terminal/browser/terminalTabsList.ts | 11 +- .../terminal/browser/terminalTooltip.ts | 25 +- .../browser/terminalTypeAheadAddon.ts | 1 - .../contrib/terminal/browser/terminalView.ts | 70 +- .../widgets/environmentVariableInfoWidget.ts | 2 +- .../browser/xterm/commandNavigationAddon.ts | 24 +- .../terminal/browser/xterm/decorationAddon.ts | 370 +- .../browser/xterm/navigationModeAddon.ts | 117 +- .../terminal/browser/xterm/xtermTerminal.ts | 93 +- .../terminal/common/environmentVariable.ts | 4 - .../common/environmentVariableCollection.ts | 4 +- .../common/environmentVariableShared.ts | 16 +- .../contrib/terminal/common/history.ts | 224 +- .../terminal/common/remoteTerminalChannel.ts | 4 - .../contrib/terminal/common/terminal.ts | 21 +- .../terminal/common/terminalColorRegistry.ts | 37 +- .../terminal/common/terminalConfiguration.ts | 56 +- .../terminal/common/terminalContextKey.ts | 14 - .../terminal/common/terminalStrings.ts | 8 + .../terminal/electron-sandbox/localPty.ts | 4 +- .../electron-sandbox/localTerminalBackend.ts | 10 - .../browser/links/terminalLinkManager.test.ts | 6 +- .../browser/links/terminalLinkOpeners.test.ts | 142 +- .../links/terminalLocalLinkDetector.test.ts | 3 - .../links/terminalUriLinkDetector.test.ts | 114 +- .../test/browser/terminalConfigHelper.test.ts | 4 +- .../browser/terminalProcessManager.test.ts | 2 +- .../browser/terminalProfileService.test.ts | 10 +- .../browser/xterm/decorationAddon.test.ts | 17 +- .../xterm/shellIntegrationAddon.test.ts | 2 +- .../test/browser/xterm/xtermTerminal.test.ts | 14 +- .../terminal/test/common/history.test.ts | 435 +- .../browser/explorerProjections/nodeHelper.ts | 6 +- .../contrib/testing/browser/media/testing.css | 18 - .../testing/browser/testExplorerActions.ts | 48 +- .../testing/browser/testing.contribution.ts | 1 + .../testing/browser/testingDecorations.ts | 39 +- .../testing/browser/testingExplorerFilter.ts | 22 +- .../testing/browser/testingExplorerView.ts | 50 +- .../testing/browser/testingOutputPeek.ts | 45 +- .../browser/testingProgressUiService.ts | 1 - .../contrib/testing/common/configuration.ts | 7 - .../contrib/testing/common/constants.ts | 3 +- .../common/mainThreadTestCollection.ts | 2 +- .../testing/common/testExplorerFilterState.ts | 2 +- .../contrib/testing/common/testId.ts | 2 +- .../testing/common/testItemCollection.ts | 24 +- .../testing/common/testingContextKeys.ts | 14 +- .../testing/test/browser/testObjectTree.ts | 2 +- .../themes/browser/themes.contribution.ts | 85 +- .../browser/themes.test.contribution.ts | 84 +- .../colorRegistry.releaseTest.ts | 42 +- .../contrib/timeline/browser/timelinePane.ts | 5 +- .../browser/typeHierarchy.contribution.ts | 4 +- .../browser/typeHierarchyPeek.ts | 12 +- .../browser/typeHierarchyTree.ts | 2 +- .../update/browser/releaseNotesEditor.ts | 22 +- .../update/browser/update.contribution.ts | 51 +- .../contrib/update/browser/update.ts | 24 +- .../contrib/url/browser/trustedDomains.ts | 6 +- .../trustedDomainsFileSystemProvider.ts | 6 +- .../url/browser/trustedDomainsValidator.ts | 8 +- .../browser/userDataProfile.contribution.ts | 13 - .../browser/userDataProfile.ts | 179 - .../common/userDataProfileActions.ts | 451 - .../userDataSync/browser/userDataSync.ts | 211 +- .../browser/userDataSyncTrigger.ts | 8 +- .../contrib/watermark/browser/watermark.ts | 8 +- .../contrib/webview/browser/overlayWebview.ts | 55 +- .../webview/browser/pre/index-no-csp.html | 1171 +-- .../contrib/webview/browser/pre/index.html | 1172 +-- .../contrib/webview/browser/pre/main.js | 1133 +++ .../webview/browser/resourceLoading.ts | 2 +- .../contrib/webview/browser/themeing.ts | 6 +- .../webview/browser/webview.contribution.ts | 9 - .../contrib/webview/browser/webview.ts | 26 +- .../contrib/webview/browser/webviewElement.ts | 92 +- .../contrib/webview/browser/webviewService.ts | 22 +- .../electron-sandbox/webviewElement.ts | 19 +- .../electron-sandbox/webviewService.ts | 12 +- .../webviewPanel/browser/webviewEditor.ts | 17 +- .../browser/webviewEditorInput.ts | 22 +- .../browser/webviewEditorInputSerializer.ts | 18 +- .../browser/webviewWorkbenchService.ts | 89 +- .../webviewView/browser/webviewViewPane.ts | 27 +- .../browser/telemetryOptOut.ts | 4 +- .../browser/welcomeBanner.contribution.ts | 4 +- .../browser/gettingStarted.contribution.ts | 29 +- .../browser/gettingStarted.ts | 34 +- .../browser/gettingStartedList.ts | 4 +- .../browser/gettingStartedService.ts | 53 +- .../browser/media/gettingStarted.css | 7 +- .../browser/startupPage.ts | 8 +- .../welcomeOverlay/browser/welcomeOverlay.ts | 2 +- .../common/newFile.contribution.ts | 23 +- .../browser/walkThroughPart.ts | 10 +- .../browser/media/workspaceTrustEditor.css | 3 +- .../electron-sandbox/actions/windowActions.ts | 2 +- .../electron-sandbox/desktop.contribution.ts | 22 +- .../electron-sandbox/desktop.main.ts | 71 +- .../parts/titlebar/menubarControl.ts | 8 +- .../parts/titlebar/titlebarPart.ts | 58 +- src/vs/workbench/electron-sandbox/window.ts | 68 +- .../electron-sandbox/accessibilityService.ts | 1 - .../actions/common/menusExtensionPoint.ts | 104 +- .../assignment/common/assignmentService.ts | 3 +- .../browser/authenticationService.ts | 14 +- .../electron-sandbox/clipboardService.ts | 6 +- .../test/common/commandService.test.ts | 28 +- .../configuration/browser/configuration.ts | 78 +- .../browser/configurationService.ts | 213 +- .../configuration/common/configuration.ts | 16 +- .../common/configurationEditingService.ts | 39 +- .../common/configurationModels.ts | 4 +- .../common/jsonEditingService.ts | 2 +- .../configurationEditingService.test.ts | 72 +- .../test/browser/configurationService.test.ts | 384 +- .../test/common/configurationModels.test.ts | 8 +- .../baseConfigurationResolverService.ts | 35 +- .../common/variableResolver.ts | 6 +- .../configurationResolverService.test.ts | 43 +- .../electron-sandbox/contextmenuService.ts | 14 +- .../decorations/browser/decorationsService.ts | 19 +- .../test/browser/decorationsService.test.ts | 201 +- .../browser/abstractFileDialogService.ts | 7 +- .../dialogs/browser/fileDialogService.ts | 2 +- .../dialogs/browser/simpleFileDialog.ts | 6 +- .../editor/browser/codeEditorService.ts | 9 +- .../editor/browser/editorResolverService.ts | 88 +- .../services/editor/browser/editorService.ts | 62 +- .../editor/common/editorGroupFinder.ts | 4 +- .../editor/common/editorGroupsService.ts | 7 +- .../editor/common/editorResolverService.ts | 21 +- .../test/browser/editorGroupsService.test.ts | 10 +- .../browser/editorResolverService.test.ts | 144 +- .../editor/test/browser/editorService.test.ts | 329 +- .../environment/browser/environmentService.ts | 40 +- .../environment/common/environmentService.ts | 1 - .../electron-sandbox/environmentService.ts | 3 - .../builtinExtensionsScannerService.ts | 68 +- .../browser/extensionBisect.ts | 10 +- .../browser/extensionEnablementService.ts | 102 +- .../browser/webExtensionsScannerService.ts | 214 +- .../common/extensionManagement.ts | 27 +- .../extensionManagementServerService.ts | 7 +- .../common/extensionManagementService.ts | 57 +- .../common/webExtensionManagementService.ts | 88 +- .../extensionManagementServerService.ts | 19 +- .../extensionManagementService.ts | 10 +- .../nativeExtensionManagementService.ts | 85 - .../remoteExtensionManagementService.ts | 31 +- .../extensionEnablementService.test.ts | 65 +- .../extensionIgnoredRecommendationsService.ts | 6 +- .../common/extensionResourceLoader.ts | 5 +- .../extensions/browser/extensionService.ts | 35 +- .../extensions/browser/extensionUrlHandler.ts | 8 +- .../browser/webWorkerExtensionHost.ts | 25 +- .../common/abstractExtensionService.ts | 145 +- .../common/extensionDescriptionRegistry.ts | 49 +- .../extensions/common/extensionDevOptions.ts | 12 +- .../extensions/common/extensionHostEnv.ts | 93 - .../extensions/common/extensionHostManager.ts | 69 +- .../common/extensionHostProtocol.ts | 11 +- .../extensions/common/extensionHostProxy.ts | 1 + .../common/extensionStorageMigration.ts | 6 +- .../services/extensions/common/extensions.ts | 4 +- .../common/extensionsApiProposals.ts | 18 +- .../extensions/common/extensionsRegistry.ts | 22 +- .../extensions/common/extensionsUtil.ts | 13 +- .../services/extensions/common/lazyPromise.ts | 14 +- .../extensions/common/proxyIdentifier.ts | 3 +- .../extensions/common/remoteExtensionHost.ts | 17 +- .../services/extensions/common/rpcProtocol.ts | 70 +- .../extensionService.ts} | 102 +- .../localProcessExtensionHost.ts | 629 +- .../cachedExtensionScanner.ts | 16 +- .../electron-sandbox/extensionHostProfiler.ts | 26 +- .../nativeLocalProcessExtensionHost.ts | 123 - .../sandboxExtensionService.ts | 22 - .../test/browser/extensionService.test.ts | 114 +- .../browser/extensionStorageMigration.test.ts | 28 +- .../extensionDescriptionRegistry.test.ts | 40 - .../test/common/rpcProtocol.test.ts | 22 +- .../worker/webWorkerExtensionHostIframe.html | 9 +- .../history/browser/historyService.ts | 8 +- .../test/browser/historyService.test.ts | 2 +- .../host/browser/browserHostService.ts | 34 +- .../services/hover/browser/hoverService.ts | 6 +- .../services/hover/browser/hoverWidget.ts | 20 +- .../electron-sandbox/integrityService.ts | 4 +- .../issue/electron-sandbox/issueService.ts | 13 +- .../keybinding/browser/keybindingService.ts | 68 +- .../browser/keyboardLayoutService.ts | 26 +- .../keybinding/common/keybindingEditing.ts | 19 +- .../keybinding/common/keybindingIO.ts | 6 +- .../services/keybinding/common/keymapInfo.ts | 34 +- .../common/macLinuxKeyboardMapper.ts | 35 +- .../common/windowsKeyboardMapper.ts | 8 +- .../browser/browserKeyboardMapper.test.ts | 10 +- .../test/browser/keybindingEditing.test.ts | 22 +- .../test/browser/keybindingIO.test.ts | 38 +- .../keyboardMapperTestUtils.ts | 14 +- .../{node => electron-browser}/linux_de_ch.js | 0 .../linux_de_ch.txt | 0 .../{node => electron-browser}/linux_en_uk.js | 0 .../linux_en_uk.txt | 0 .../{node => electron-browser}/linux_en_us.js | 0 .../linux_en_us.txt | 0 .../{node => electron-browser}/linux_ru.js | 0 .../{node => electron-browser}/linux_ru.txt | 0 .../macLinuxFallbackKeyboardMapper.test.ts | 6 +- .../macLinuxKeyboardMapper.test.ts | 8 +- .../{node => electron-browser}/mac_de_ch.js | 0 .../{node => electron-browser}/mac_de_ch.txt | 0 .../{node => electron-browser}/mac_en_us.js | 0 .../{node => electron-browser}/mac_en_us.txt | 0 .../{node => electron-browser}/mac_zh_hant.js | 0 .../mac_zh_hant.txt | 0 .../mac_zh_hant2.js | 0 .../mac_zh_hant2.txt | 0 .../{node => electron-browser}/win_de_ch.js | 0 .../{node => electron-browser}/win_de_ch.txt | 0 .../{node => electron-browser}/win_en_us.js | 0 .../{node => electron-browser}/win_en_us.txt | 0 .../{node => electron-browser}/win_por_ptb.js | 0 .../win_por_ptb.txt | 0 .../test/{node => electron-browser}/win_ru.js | 0 .../{node => electron-browser}/win_ru.txt | 0 .../windowsKeyboardMapper.test.ts | 2 +- .../services/label/common/labelService.ts | 73 +- .../services/label/test/browser/label.test.ts | 58 +- .../label/test/common/mockLabelService.ts | 41 - .../label/test/electron-browser/label.test.ts | 6 +- .../language/common/languageService.ts | 6 +- .../languageDetectionWorkerServiceImpl.ts | 18 +- .../common/languageDetectionWorkerService.ts | 23 +- .../electron-sandbox/localizationsService.ts} | 4 +- .../common/notificationService.ts | 67 +- .../outline/browser/outlineService.ts | 4 +- .../output/common/delayedLogChannel.ts | 33 - .../preferences/browser/preferencesService.ts | 29 +- .../preferences/common/preferences.ts | 3 +- .../preferences/common/preferencesModels.ts | 32 +- .../browser/keybindingsEditorModel.test.ts | 2 +- .../common/extensionsProfile.ts | 2 +- .../common/globalStateProfile.ts | 8 +- .../services/profiles/common/profile.ts | 44 + .../common/profileService.ts} | 49 +- .../common/profileStorageRegistry.ts} | 0 .../common/settingsProfile.ts | 13 +- .../progress/browser/progressService.ts | 12 +- .../test/browser/progressIndicator.test.ts | 14 +- .../common/abstractRemoteAgentService.ts | 38 +- .../common/remoteAgentEnvironmentChannel.ts | 4 - .../remote/common/remoteAgentService.ts | 8 - .../remote/common/remoteExplorerService.ts | 14 +- .../request/browser/requestService.ts | 2 +- .../services/search/common/ignoreFile.ts | 21 +- .../services/search/common/searchExtTypes.ts | 2 +- .../services/search/common/searchService.ts | 17 +- .../services/search/node/fileSearch.ts | 7 +- .../services/search/node/rawSearchService.ts | 4 +- .../search/test/common/ignoreFile.test.ts | 12 +- .../search/test/common/replace.test.ts | 8 +- .../services/search/worker/localFileSearch.ts | 2 +- .../services/statusbar/browser/statusbar.ts | 5 +- .../electron-sandbox/storageService.ts | 30 - .../telemetry/browser/telemetryService.ts | 40 +- .../browser/workbenchCommonProperties.ts | 18 +- .../electron-sandbox/telemetryService.ts | 5 +- .../workbenchCommonProperties.ts | 8 +- .../test/browser/commonProperties.test.ts | 6 +- .../electron-browser/commonProperties.test.ts | 10 +- .../browser/abstractTextMateService.ts | 23 +- .../textMate/browser/nativeTextMateService.ts | 2 +- .../textMate/browser/textMateWorker.ts | 6 +- .../textMate/common/TMGrammarFactory.ts | 6 +- .../services/textMate/common/TMHelper.ts | 16 +- .../textMate/common/TMScopeRegistry.ts | 2 +- .../textMate/common/TMTokenization.ts | 11 +- .../textfile/common/textEditorService.ts | 19 +- .../textfile/common/textFileEditorModel.ts | 2 +- .../browser/browserTextFileService.io.test.ts | 2 +- .../test/browser/textEditorService.test.ts | 2 +- .../test/browser/textFileEditorModel.test.ts | 10 +- .../textFileEditorModelManager.test.ts | 10 +- .../test/browser/textFileService.test.ts | 6 +- .../test/common/textFileService.io.test.ts | 4 +- .../common/textModelResolverService.ts | 41 +- .../browser/textModelResolverService.test.ts | 18 +- .../themes/browser/fileIconThemeData.ts | 4 +- .../themes/browser/productIconThemeData.ts | 41 +- .../themes/browser/workbenchThemeService.ts | 23 +- .../themes/common/colorExtensionPoint.ts | 4 +- .../services/themes/common/colorThemeData.ts | 94 +- .../themes/common/colorThemeSchema.ts | 6 +- .../themes/common/fileIconThemeSchema.ts | 2 +- .../themes/common/iconExtensionPoint.ts | 2 +- .../services/themes/common/plistParser.ts | 28 +- .../themes/common/productIconThemeSchema.ts | 5 +- .../themes/common/textMateScopeMatcher.ts | 4 +- .../themes/common/themeCompatibility.ts | 12 +- .../themes/common/themeConfiguration.ts | 8 +- .../themes/common/themeExtensionPoints.ts | 6 +- .../tokenClassificationExtensionPoint.ts | 4 +- .../nativeHostColorSchemeService.ts | 4 +- .../tokenStyleResolving.test.ts | 4 +- .../services/timer/browser/timerService.ts | 15 +- .../timer/electron-sandbox/timerService.ts | 4 +- .../services/title/common/titleService.ts | 10 - .../services/tunnel/browser/tunnelService.ts | 2 +- .../tunnel/electron-sandbox/tunnelService.ts | 2 +- .../common/untitledTextEditorModel.ts | 2 +- .../test/browser/untitledTextEditor.test.ts | 2 +- .../services/update/browser/updateService.ts | 4 - .../services/userData/browser/userDataInit.ts | 17 +- .../browser/userDataProfileManagement.ts | 114 - .../userDataProfile/common/userDataProfile.ts | 80 - .../common/userDataProfileService.ts | 66 - .../browser/userDataSyncWorkbenchService.ts | 35 +- .../views/browser/treeViewsService.ts | 4 +- .../views/browser/viewDescriptorService.ts | 20 +- .../views/common/viewContainerModel.ts | 12 +- .../test/browser/viewContainerModel.test.ts | 36 +- .../browser/viewDescriptorService.test.ts | 4 +- .../common/abstractFileWorkingCopyManager.ts | 2 +- .../common/fileWorkingCopyManager.ts | 2 +- .../common/storedFileWorkingCopy.ts | 2 +- .../common/storedFileWorkingCopyManager.ts | 2 +- .../common/untitledFileWorkingCopyManager.ts | 2 +- .../common/workingCopyHistoryTracker.ts | 3 +- .../test/browser/resourceWorkingCopy.test.ts | 27 +- .../browser/storedFileWorkingCopy.test.ts | 224 +- .../storedFileWorkingCopyManager.test.ts | 4 +- .../browser/untitledFileWorkingCopy.test.ts | 2 +- .../browser/workingCopyBackupTracker.test.ts | 2 +- .../browser/workingCopyEditorService.test.ts | 2 +- .../browser/workingCopyFileService.test.ts | 20 +- .../workingCopyBackupService.test.ts | 50 +- .../workingCopyHistoryService.test.ts | 24 +- .../workingCopyHistoryTracker.test.ts | 68 +- .../abstractWorkspaceEditingService.ts | 49 +- .../browser/workspaceEditingService.ts | 12 +- .../workspaces/browser/workspacesService.ts | 8 +- .../workspaces/common/workspaceEditing.ts | 10 +- .../workspaces/common/workspaceTrust.ts | 35 +- .../workspaceEditingService.ts | 14 +- .../test/common/workspaceTrust.test.ts | 2 +- .../workbench/test/browser/codeeditor.test.ts | 10 +- src/vs/workbench/test/browser/part.test.ts | 18 +- .../parts/editor/breadcrumbModel.test.ts | 18 +- .../parts/editor/diffEditorInput.test.ts | 4 +- .../test/browser/parts/editor/editor.test.ts | 179 +- .../parts/editor/editorDiffModel.test.ts | 12 +- .../parts/editor/editorGroupModel.test.ts | 24 +- .../browser/parts/editor/editorInput.test.ts | 7 +- .../browser/parts/editor/editorModel.test.ts | 2 +- .../editor/sideBySideEditorInput.test.ts | 4 +- src/vs/workbench/test/browser/viewlet.test.ts | 6 +- .../test/browser/workbenchTestServices.ts | 159 +- src/vs/workbench/test/common/memento.test.ts | 128 +- .../test/common/notifications.test.ts | 40 +- .../electron-browser/workbenchTestServices.ts | 36 +- src/vs/workbench/workbench.common.main.ts | 34 +- src/vs/workbench/workbench.desktop.main.ts | 171 +- .../workbench.desktop.sandbox.main.ts | 38 + src/vs/workbench/workbench.sandbox.main.ts | 163 + src/vs/workbench/workbench.web.main.ts | 15 +- src/vscode-dts/vscode.d.ts | 516 +- .../vscode.proposed.contribEditSessions.d.ts | 6 - .../vscode.proposed.contribShareMenu.d.ts | 6 - .../vscode.proposed.contribViewSize.d.ts | 17 - ...vscode.proposed.contribWebviewContext.d.ts | 6 - .../vscode.proposed.documentPaste.d.ts | 75 - .../vscode.proposed.inlineCompletions.d.ts | 174 + ...e.proposed.inlineCompletionsAdditions.d.ts | 21 - .../vscode.proposed.inlineCompletionsNew.d.ts | 22 +- .../vscode.proposed.inputBoxSeverity.d.ts | 50 + .../vscode.proposed.interactiveWindow.d.ts | 25 - ...code.proposed.notebookContentProvider.d.ts | 10 +- .../vscode.proposed.notebookEditor.d.ts | 103 +- ...proposed.notebookEditorDecorationType.d.ts | 28 + .../vscode.proposed.notebookEditorEdit.d.ts | 39 +- ...code.proposed.notebookProxyController.d.ts | 56 + ...vscode.proposed.notebookWorkspaceEdit.d.ts | 85 - .../vscode.proposed.scmActionButton.d.ts | 2 - .../vscode.proposed.snippetWorkspaceEdit.d.ts | 15 - .../vscode.proposed.tabInputTextMerge.d.ts | 25 - .../vscode.proposed.terminalExitReason.d.ts | 47 - ...code.proposed.terminalNameChangeEvent.d.ts | 30 + .../vscode.proposed.testCoverage.d.ts | 2 +- .../vscode.proposed.textEditorDrop.d.ts | 47 + .../vscode.proposed.textSearchProvider.d.ts | 2 +- test/automation/src/application.ts | 6 +- test/automation/src/code.ts | 12 +- test/automation/src/editor.ts | 3 - test/automation/src/electron.ts | 10 +- test/automation/src/extensions.ts | 2 +- test/automation/src/index.ts | 1 - test/automation/src/playwrightBrowser.ts | 2 +- test/automation/src/problems.ts | 4 +- test/automation/src/settings.ts | 33 +- test/automation/src/task.ts | 86 - test/automation/src/terminal.ts | 73 +- test/automation/src/workbench.ts | 7 +- test/integration/browser/src/index.ts | 4 +- test/smoke/package.json | 2 +- test/smoke/src/areas/search/search.test.ts | 4 +- .../src/areas/statusbar/statusbar.test.ts | 4 +- .../src/areas/task/task-quick-pick.test.ts | 71 - test/smoke/src/areas/task/task.test.ts | 22 - .../areas/terminal/terminal-editors.test.ts | 16 +- .../src/areas/terminal/terminal-helpers.ts | 23 - .../src/areas/terminal/terminal-input.test.ts | 12 +- .../terminal/terminal-persistence.test.ts | 45 +- .../areas/terminal/terminal-profiles.test.ts | 21 +- .../terminal-shellIntegration.test.ts | 144 +- .../areas/terminal/terminal-splitCwd.test.ts | 14 +- .../src/areas/terminal/terminal-tabs.test.ts | 16 +- .../smoke/src/areas/terminal/terminal.test.ts | 12 +- .../src/areas/workbench/data-loss.test.ts | 19 +- .../src/areas/workbench/localization.test.ts | 1 + test/smoke/src/main.ts | 148 +- test/smoke/src/utils.ts | 8 +- test/smoke/yarn.lock | 8 +- test/unit/browser/index.js | 25 +- test/unit/coverage.js | 4 +- test/unit/electron/renderer.js | 60 +- test/unit/node/index.js | 8 +- test/unit/reporter.js | 2 +- yarn.lock | 1721 ++-- 2389 files changed, 42588 insertions(+), 92170 deletions(-) delete mode 100644 .github/workflows/bad-tag.yml delete mode 100644 .github/workflows/basic.yml delete mode 100644 .github/workflows/pr-chat.yml delete mode 100644 .nvmrc delete mode 100644 build/.gitignore delete mode 100644 build/azure-pipelines/linux/product-build-linux-client-test.yml delete mode 100644 build/azure-pipelines/product-build-pr-cache.yml delete mode 100644 build/azure-pipelines/product-build-pr.yml delete mode 100644 build/azure-pipelines/win32/product-build-win32-test.yml delete mode 100644 build/lib/policies.js delete mode 100644 build/lib/policies.ts delete mode 100644 build/lib/tsb/builder.js delete mode 100644 build/lib/tsb/builder.ts delete mode 100644 build/lib/tsb/index.js delete mode 100644 build/lib/tsb/index.ts delete mode 100644 build/lib/tsb/transpiler.js delete mode 100644 build/lib/tsb/transpiler.ts delete mode 100644 build/lib/tsb/utils.js delete mode 100644 build/lib/tsb/utils.ts create mode 100644 build/lib/typings/gulp-tsb.d.ts create mode 100644 build/lib/watch/.gitignore create mode 100644 build/lib/watch/package.json create mode 100644 build/lib/watch/yarn.lock delete mode 100644 build/linux/debian/dep-lists.js delete mode 100644 build/linux/debian/dep-lists.ts delete mode 100644 build/linux/debian/dependencies-generator.js delete mode 100644 build/linux/debian/dependencies-generator.ts delete mode 100644 build/linux/debian/install-sysroot.js delete mode 100644 build/linux/debian/install-sysroot.ts delete mode 100644 build/linux/debian/sysroots.js delete mode 100644 build/linux/debian/sysroots.ts delete mode 100644 build/linux/debian/types.js delete mode 100644 build/npm/setupBuildYarnrc.js delete mode 100644 build/package-lock.json delete mode 100644 extensions/configuration-editing/schemas/devContainer.codespaces.schema.json delete mode 100644 extensions/configuration-editing/schemas/devContainer.vscode.schema.json delete mode 100644 extensions/configuration-editing/src/test/completion.test.ts delete mode 100644 extensions/css-language-features/server/src/utils/validation.ts delete mode 100755 extensions/git/src/git-editor-empty.sh delete mode 100644 extensions/git/src/git-editor-main.ts delete mode 100755 extensions/git/src/git-editor.sh delete mode 100644 extensions/git/src/gitEditor.ts delete mode 100644 extensions/git/src/postCommitCommands.ts delete mode 100644 extensions/github/src/links.ts delete mode 100644 extensions/html-language-features/client/src/languageParticipants.ts delete mode 100644 extensions/html-language-features/server/src/utils/validation.ts delete mode 100644 extensions/ipynb/esbuild.js delete mode 100644 extensions/ipynb/src/cellAttachmentRenderer.ts delete mode 100644 extensions/json-language-features/server/src/utils/validation.ts delete mode 100644 extensions/markdown-language-features/server/.npmignore delete mode 100644 extensions/markdown-language-features/server/.vscode/launch.json delete mode 100644 extensions/markdown-language-features/server/.vscode/settings.json delete mode 100644 extensions/markdown-language-features/server/.vscode/tasks.json delete mode 100644 extensions/markdown-language-features/server/README.md delete mode 100644 extensions/markdown-language-features/server/extension-browser.webpack.config.js delete mode 100644 extensions/markdown-language-features/server/extension.webpack.config.js delete mode 100644 extensions/markdown-language-features/server/package.json delete mode 100644 extensions/markdown-language-features/server/src/browser/main.ts delete mode 100644 extensions/markdown-language-features/server/src/config.ts delete mode 100644 extensions/markdown-language-features/server/src/configuration.ts delete mode 100644 extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts delete mode 100644 extensions/markdown-language-features/server/src/logging.ts delete mode 100644 extensions/markdown-language-features/server/src/node/main.ts delete mode 100644 extensions/markdown-language-features/server/src/protocol.ts delete mode 100644 extensions/markdown-language-features/server/src/server.ts delete mode 100644 extensions/markdown-language-features/server/src/util/arrays.ts delete mode 100644 extensions/markdown-language-features/server/src/util/dispose.ts delete mode 100644 extensions/markdown-language-features/server/src/util/file.ts delete mode 100644 extensions/markdown-language-features/server/src/util/limiter.ts delete mode 100644 extensions/markdown-language-features/server/src/util/resourceMap.ts delete mode 100644 extensions/markdown-language-features/server/src/util/schemes.ts delete mode 100644 extensions/markdown-language-features/server/src/workspace.ts delete mode 100644 extensions/markdown-language-features/server/tsconfig.json delete mode 100644 extensions/markdown-language-features/server/yarn.lock delete mode 100644 extensions/markdown-language-features/src/client.ts delete mode 100644 extensions/markdown-language-features/src/extension.browser.ts delete mode 100644 extensions/markdown-language-features/src/extension.shared.ts delete mode 100644 extensions/markdown-language-features/src/languageFeatures/copyPaste.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/definitionProvider.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/documentSymbolProvider.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/foldingProvider.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/pathCompletions.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/references.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/rename.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/smartSelect.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts create mode 100644 extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts rename extensions/markdown-language-features/src/{logging.ts => logger.ts} (59%) rename extensions/markdown-language-features/src/preview/{documentRenderer.ts => previewContentProvider.ts} (91%) delete mode 100644 extensions/markdown-language-features/src/protocol.ts create mode 100644 extensions/markdown-language-features/src/test/definitionProvider.test.ts create mode 100644 extensions/markdown-language-features/src/test/diagnostic.test.ts create mode 100644 extensions/markdown-language-features/src/test/documentLinkProvider.test.ts create mode 100644 extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts create mode 100644 extensions/markdown-language-features/src/test/fileReferences.test.ts create mode 100644 extensions/markdown-language-features/src/test/foldingProvider.test.ts delete mode 100644 extensions/markdown-language-features/src/test/nulLogging.ts create mode 100644 extensions/markdown-language-features/src/test/pathCompletion.test.ts create mode 100644 extensions/markdown-language-features/src/test/references.test.ts create mode 100644 extensions/markdown-language-features/src/test/rename.test.ts create mode 100644 extensions/markdown-language-features/src/test/smartSelect.test.ts create mode 100644 extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts create mode 100644 extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts delete mode 100644 extensions/markdown-language-features/src/types/textDocument.ts delete mode 100644 extensions/markdown-language-features/src/util/cancellation.ts delete mode 100644 extensions/markdown-language-features/src/util/dom.ts delete mode 100644 extensions/markdown-language-features/src/util/resourceMap.ts delete mode 100644 extensions/markdown-language-features/src/util/workspaceCache.ts rename extensions/markdown-language-features/src/{workspace.ts => workspaceContents.ts} (57%) delete mode 100644 extensions/typescript-language-features/src/experimentationService.ts delete mode 100644 extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts create mode 100644 resources/win32/policies/Code.admx create mode 100644 resources/win32/policies/en-US/Code.adml delete mode 100644 src/sql/base/browser/globalPointerMoveMonitor.ts delete mode 100644 src/vs/base/browser/broadcast.ts delete mode 100644 src/vs/base/browser/deviceAccess.ts delete mode 100644 src/vs/base/common/dataTransfer.ts delete mode 100644 src/vs/base/common/observable.ts delete mode 100644 src/vs/base/common/observableImpl/autorun.ts delete mode 100644 src/vs/base/common/observableImpl/base.ts delete mode 100644 src/vs/base/common/observableImpl/derived.ts delete mode 100644 src/vs/base/common/observableImpl/logging.ts delete mode 100644 src/vs/base/common/observableImpl/utils.ts delete mode 100644 src/vs/base/test/browser/ui/list/listWidget.test.ts delete mode 100644 src/vs/base/test/common/observable.test.ts delete mode 100644 src/vs/base/test/node/css.build.test.ts create mode 100644 src/vs/code/electron-browser/workbench/workbench.html create mode 100644 src/vs/code/electron-browser/workbench/workbench.js delete mode 100644 src/vs/css.build.ts rename src/{vscode-dts/vscode.proposed.notebookKernelSource.d.ts => vs/css.d.ts} (92%) delete mode 100644 src/vs/css.ts delete mode 100644 src/vs/editor/browser/dnd.ts delete mode 100644 src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css delete mode 100644 src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts delete mode 100644 src/vs/editor/common/encodedTokenAttributes.ts delete mode 100644 src/vs/editor/common/viewLayout/linePart.ts delete mode 100644 src/vs/editor/contrib/codeAction/browser/codeActionWidgetContribution.ts delete mode 100644 src/vs/editor/contrib/codeAction/browser/media/action.css delete mode 100644 src/vs/editor/contrib/copyPaste/browser/copyPasteContribution.ts delete mode 100644 src/vs/editor/contrib/copyPaste/browser/copyPasteController.ts delete mode 100644 src/vs/editor/contrib/dropIntoEditor/browser/dropIntoEditorContribution.ts create mode 100644 src/vs/editor/contrib/folding/browser/intializingRangeProvider.ts delete mode 100644 src/vs/editor/contrib/hover/test/browser/contentHover.test.ts delete mode 100644 src/vs/editor/contrib/readOnlyMessage/browser/contribution.ts delete mode 100644 src/vs/editor/contrib/stickyScroll/browser/stickyScroll.ts rename src/vs/{base/browser/ui/resizable => editor/contrib/suggest/browser}/resizable.ts (100%) delete mode 100644 src/vs/loader.d.ts delete mode 100644 src/vs/nls.build.ts delete mode 100644 src/vs/nls.ts delete mode 100644 src/vs/platform/actions/common/actions.contribution.ts delete mode 100644 src/vs/platform/actions/common/menuResetAction.ts delete mode 100644 src/vs/platform/configuration/common/configurations.ts delete mode 100644 src/vs/platform/configuration/test/common/policyConfiguration.test.ts rename build/linux/debian/types.ts => src/vs/platform/contextview/browser/contextMenuHandler.css (86%) delete mode 100644 src/vs/platform/dnd/browser/dnd.ts delete mode 100644 src/vs/platform/extensionManagement/common/extensionsProfileScannerService.ts delete mode 100644 src/vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit.ts delete mode 100644 src/vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit.ts delete mode 100644 src/vs/platform/extensions/electron-main/extensionHostStarter.ts create mode 100644 src/vs/platform/extensions/electron-main/workerMainProcessExtensionHostStarter.ts create mode 100644 src/vs/platform/extensions/node/extensionHostStarterWorker.ts create mode 100644 src/vs/platform/extensions/node/extensionHostStarterWorkerMain.ts rename src/vs/platform/files/test/browser/{indexedDBFileService.integrationTest.ts => indexedDBFileService.test.ts} (87%) delete mode 100644 src/vs/platform/languagePacks/browser/languagePacks.ts delete mode 100644 src/vs/platform/languagePacks/common/languagePacks.ts rename src/vs/platform/{languagePacks => localizations}/common/localizedStrings.ts (100%) rename src/vs/platform/{languagePacks/node/languagePacks.ts => localizations/node/localizations.ts} (76%) delete mode 100644 src/vs/platform/policy/common/filePolicyService.ts delete mode 100644 src/vs/platform/policy/common/policy.ts delete mode 100644 src/vs/platform/policy/common/policyIpc.ts delete mode 100644 src/vs/platform/policy/node/nativePolicyService.ts delete mode 100644 src/vs/platform/remote/test/common/remoteHosts.test.ts delete mode 100644 src/vs/platform/request/electron-browser/sharedProcessRequestService.ts delete mode 100644 src/vs/platform/state/node/state.ts delete mode 100644 src/vs/platform/state/node/stateService.ts rename src/vs/{workbench/services => platform}/storage/browser/storageService.ts (54%) rename src/vs/{workbench/services => platform}/storage/test/browser/storageService.test.ts (78%) delete mode 100644 src/vs/platform/terminal/common/terminalStrings.ts delete mode 100644 src/vs/platform/terminal/test/common/terminalEnvironment.test.ts delete mode 100644 src/vs/platform/userDataProfile/browser/userDataProfile.ts delete mode 100644 src/vs/platform/userDataProfile/common/userDataProfile.ts delete mode 100644 src/vs/platform/userDataProfile/electron-main/userDataProfile.ts delete mode 100644 src/vs/platform/userDataProfile/electron-sandbox/userDataProfile.ts delete mode 100644 src/vs/platform/userDataProfile/node/userDataProfile.ts delete mode 100644 src/vs/platform/userDataProfile/test/common/userDataProfileService.test.ts delete mode 100644 src/vs/platform/userDataProfile/test/electron-main/userDataProfileMainService.test.ts create mode 100644 src/vs/workbench/api/browser/mainThreadNotebookProxyKernels.ts delete mode 100644 src/vs/workbench/api/common/extHostConsoleForwarder.ts create mode 100644 src/vs/workbench/api/common/extHostNotebookProxyKernels.ts create mode 100644 src/vs/workbench/api/common/shared/dataTransfer.ts delete mode 100644 src/vs/workbench/api/common/shared/dataTransferCache.ts delete mode 100644 src/vs/workbench/api/node/extHostConsoleForwarder.ts delete mode 100644 src/vs/workbench/api/worker/extHostConsoleForwarder.ts delete mode 100644 src/vs/workbench/browser/parts/editor/textCodeEditor.ts delete mode 100644 src/vs/workbench/browser/parts/titlebar/commandCenterControl.ts delete mode 100644 src/vs/workbench/browser/parts/titlebar/windowTitle.ts rename extensions/markdown-language-features/src/util/string.ts => src/vs/workbench/common/dnd.ts (71%) create mode 100644 src/vs/workbench/contrib/audioCues/browser/observable.ts delete mode 100644 src/vs/workbench/contrib/bracketPairColorizer2Telemetry/browser/bracketPairColorizer2Telemetry.contribution.ts delete mode 100644 src/vs/workbench/contrib/debug/browser/debugConsoleQuickAccess.ts delete mode 100644 src/vs/workbench/contrib/debug/browser/debugSessionPicker.ts delete mode 100644 src/vs/workbench/contrib/debug/common/loadedScriptsPicker.ts delete mode 100644 src/vs/workbench/contrib/debug/test/node/terminals.test.ts delete mode 100644 src/vs/workbench/contrib/deprecatedExtensionMigrator/browser/deprecatedExtensionMigrator.contribution.ts create mode 100644 src/vs/workbench/contrib/dropIntoEditor/browser/dropIntoEditor.contibution.ts delete mode 100644 src/vs/workbench/contrib/editSessions/browser/editSessions.contribution.ts delete mode 100644 src/vs/workbench/contrib/editSessions/browser/editSessionsContentProvider.ts delete mode 100644 src/vs/workbench/contrib/editSessions/browser/editSessionsViews.ts delete mode 100644 src/vs/workbench/contrib/editSessions/browser/editSessionsWorkbenchService.ts delete mode 100644 src/vs/workbench/contrib/editSessions/common/editSessions.ts delete mode 100644 src/vs/workbench/contrib/editSessions/common/editSessionsLogService.ts delete mode 100644 src/vs/workbench/contrib/editSessions/test/browser/editSessions.test.ts create mode 100644 src/vs/workbench/contrib/extensions/browser/extensionsCleaner.ts delete mode 100644 src/vs/workbench/contrib/localization/browser/localeService.ts delete mode 100644 src/vs/workbench/contrib/localization/browser/localization.contribution.ts delete mode 100644 src/vs/workbench/contrib/localization/browser/localizationsActions.ts delete mode 100644 src/vs/workbench/contrib/localization/common/locale.ts delete mode 100644 src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts rename src/vs/workbench/contrib/{localization/electron-sandbox/localization.contribution.ts => localizations/browser/localizations.contribution.ts} (89%) create mode 100644 src/vs/workbench/contrib/localizations/browser/localizationsActions.ts rename src/vs/workbench/contrib/{localization/electron-sandbox => localizations/browser}/minimalTranslations.ts (100%) create mode 100644 src/vs/workbench/contrib/markers/browser/constants.ts delete mode 100644 src/vs/workbench/contrib/markers/browser/markersTable.ts delete mode 100644 src/vs/workbench/contrib/markers/common/markers.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/commands/commands.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/mergeEditorInput.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/mergeEditorSerializer.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/diffComputer.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/editing.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/lineRange.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/mapping.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/mergeEditorModel.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/modifiedBaseRange.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/model/textModelDiffs.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/utils.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/colors.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/media/mergeEditor.css delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/common/mergeEditor.ts delete mode 100644 src/vs/workbench/contrib/mergeEditor/test/browser/model.test.ts create mode 100644 src/vs/workbench/contrib/notebook/browser/viewParts/notebookEditorDecorations.ts delete mode 100644 src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts rename src/{vscode-dts/vscode.proposed.contribMergeEditorToolbar.d.ts => vs/workbench/contrib/profiles/common/profiles.contribution.ts} (83%) create mode 100644 src/vs/workbench/contrib/profiles/common/profilesActions.ts delete mode 100644 src/vs/workbench/contrib/snippets/browser/commands/abstractSnippetsActions.ts delete mode 100644 src/vs/workbench/contrib/snippets/browser/commands/fileTemplateSnippets.ts delete mode 100644 src/vs/workbench/contrib/snippets/browser/commands/surroundWithSnippet.ts rename src/vs/workbench/contrib/snippets/browser/{commands => }/configureSnippets.ts (89%) rename src/vs/workbench/contrib/snippets/browser/{commands => }/insertSnippet.ts (83%) delete mode 100644 src/vs/workbench/contrib/snippets/browser/snippetCodeActionProvider.ts delete mode 100644 src/vs/workbench/contrib/snippets/browser/snippets.ts create mode 100644 src/vs/workbench/contrib/snippets/browser/surroundWithSnippet.ts delete mode 100644 src/vs/workbench/contrib/tasks/test/browser/taskTerminalStatus.test.ts rename src/vs/workbench/contrib/tasks/test/common/{taskConfiguration.test.ts => configuration.test.ts} (73%) create mode 100644 src/vs/workbench/contrib/terminal/browser/links/terminalShellIntegrationLinkDetector.ts delete mode 100644 src/vs/workbench/contrib/terminal/browser/media/shellIntegration-login.zsh rename src/vs/workbench/contrib/terminal/browser/media/{shellIntegration-rc.zsh => shellIntegration.zsh} (74%) delete mode 100644 src/vs/workbench/contrib/terminal/browser/terminalEscapeSequences.ts delete mode 100644 src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.ts delete mode 100644 src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.ts delete mode 100644 src/vs/workbench/contrib/userDataProfile/common/userDataProfileActions.ts create mode 100644 src/vs/workbench/contrib/webview/browser/pre/main.js delete mode 100644 src/vs/workbench/services/extensionManagement/electron-sandbox/nativeExtensionManagementService.ts delete mode 100644 src/vs/workbench/services/extensions/common/extensionHostEnv.ts rename src/vs/workbench/services/extensions/{electron-sandbox/electronExtensionService.ts => electron-browser/extensionService.ts} (88%) rename src/vs/workbench/services/extensions/{electron-sandbox => electron-browser}/localProcessExtensionHost.ts (53%) delete mode 100644 src/vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost.ts delete mode 100644 src/vs/workbench/services/extensions/electron-sandbox/sandboxExtensionService.ts delete mode 100644 src/vs/workbench/services/extensions/test/common/extensionDescriptionRegistry.test.ts rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/keyboardMapperTestUtils.ts (85%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_de_ch.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_de_ch.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_en_uk.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_en_uk.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_en_us.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_en_us.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_ru.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/linux_ru.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/macLinuxFallbackKeyboardMapper.test.ts (97%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/macLinuxKeyboardMapper.test.ts (99%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_de_ch.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_de_ch.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_en_us.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_en_us.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_zh_hant.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_zh_hant.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_zh_hant2.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/mac_zh_hant2.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_de_ch.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_de_ch.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_en_us.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_en_us.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_por_ptb.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_por_ptb.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_ru.js (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/win_ru.txt (100%) rename src/vs/workbench/services/keybinding/test/{node => electron-browser}/windowsKeyboardMapper.test.ts (99%) delete mode 100644 src/vs/workbench/services/label/test/common/mockLabelService.ts rename src/vs/workbench/services/{localization/electron-sandbox/languagePackService.ts => localizations/electron-sandbox/localizationsService.ts} (68%) delete mode 100644 src/vs/workbench/services/output/common/delayedLogChannel.ts rename src/vs/workbench/services/{userDataProfile => profiles}/common/extensionsProfile.ts (98%) rename src/vs/workbench/services/{userDataProfile => profiles}/common/globalStateProfile.ts (89%) create mode 100644 src/vs/workbench/services/profiles/common/profile.ts rename src/vs/workbench/services/{userDataProfile/common/userDataProfileImportExportService.ts => profiles/common/profileService.ts} (51%) rename src/vs/workbench/services/{userDataProfile/common/userDataProfileStorageRegistry.ts => profiles/common/profileStorageRegistry.ts} (100%) rename src/vs/workbench/services/{userDataProfile => profiles}/common/settingsProfile.ts (81%) delete mode 100644 src/vs/workbench/services/storage/electron-sandbox/storageService.ts delete mode 100644 src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.ts delete mode 100644 src/vs/workbench/services/userDataProfile/common/userDataProfile.ts delete mode 100644 src/vs/workbench/services/userDataProfile/common/userDataProfileService.ts create mode 100644 src/vs/workbench/workbench.desktop.sandbox.main.ts create mode 100644 src/vs/workbench/workbench.sandbox.main.ts delete mode 100644 src/vscode-dts/vscode.proposed.contribEditSessions.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.contribShareMenu.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.contribViewSize.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.contribWebviewContext.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.documentPaste.d.ts create mode 100644 src/vscode-dts/vscode.proposed.inlineCompletions.d.ts create mode 100644 src/vscode-dts/vscode.proposed.inputBoxSeverity.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.interactiveWindow.d.ts create mode 100644 src/vscode-dts/vscode.proposed.notebookEditorDecorationType.d.ts create mode 100644 src/vscode-dts/vscode.proposed.notebookProxyController.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.notebookWorkspaceEdit.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.snippetWorkspaceEdit.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts delete mode 100644 src/vscode-dts/vscode.proposed.terminalExitReason.d.ts create mode 100644 src/vscode-dts/vscode.proposed.terminalNameChangeEvent.d.ts create mode 100644 src/vscode-dts/vscode.proposed.textEditorDrop.d.ts delete mode 100644 test/automation/src/task.ts delete mode 100644 test/smoke/src/areas/task/task-quick-pick.test.ts delete mode 100644 test/smoke/src/areas/task/task.test.ts delete mode 100644 test/smoke/src/areas/terminal/terminal-helpers.ts diff --git a/.eslintrc.json b/.eslintrc.json index 481e18997c..48b1a9d982 100755 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -770,7 +770,6 @@ "chart.js", "plotly.js", "angular2-grid", - "kburtram-query-plan", "html-to-image", "turndown", "gridstack", @@ -1147,7 +1146,6 @@ "extensions/azuremonitor/src/prompts/**", "extensions/azuremonitor/src/typings/findRemove.d.ts", "extensions/kusto/src/prompts/**", - "extensions/mssql/src/hdfs/webhdfs.ts", "extensions/mssql/src/prompts/**", "extensions/mssql/src/typings/bufferStreamReader.d.ts", "extensions/mssql/src/typings/findRemove.d.ts", diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a8f9a23b95..f041acf3c8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -5,3 +5,5 @@ * Ensure that the code is up-to-date with the `main` branch. * Include a description of the proposed changes and how to test them. --> + +This PR fixes # diff --git a/.github/workflows/bad-tag.yml b/.github/workflows/bad-tag.yml deleted file mode 100644 index e996639dfb..0000000000 --- a/.github/workflows/bad-tag.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Bad Tag -on: - create - -jobs: - main: - runs-on: ubuntu-latest - if: github.event.ref == '1.999.0' - steps: - - name: Checkout Actions - uses: actions/checkout@v2 - with: - repository: "microsoft/vscode-github-triage-actions" - ref: stable - path: ./actions - - name: Install Actions - run: npm install --production --prefix ./actions - - name: Run Bad Tag - uses: ./actions/tag-alert - with: - token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}} - tag-name: '1.999.0' diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml deleted file mode 100644 index 308d839235..0000000000 --- a/.github/workflows/basic.yml +++ /dev/null @@ -1,177 +0,0 @@ -name: Basic checks - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - main: - if: github.ref != 'refs/heads/main' - name: Compilation, Unit and Integration Tests - runs-on: ubuntu-latest - timeout-minutes: 40 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v3 - - # TODO: rename azure-pipelines/linux/xvfb.init to github-actions - - name: Setup Build Environment - run: | - sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb - sudo chmod +x /etc/init.d/xvfb - sudo update-rc.d xvfb defaults - sudo service xvfb start - - - uses: actions/setup-node@v3 - with: - node-version: 16 - - - name: Compute node modules cache key - id: nodeModulesCacheKey - run: echo "::set-output name=value::$(node build/azure-pipelines/common/computeNodeModulesCacheKey.js)" - - name: Cache node modules - id: cacheNodeModules - uses: actions/cache@v3 - with: - path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- - - name: Get yarn cache directory path - id: yarnCacheDirPath - if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: Cache yarn directory - if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} - uses: actions/cache@v3 - with: - path: ${{ steps.yarnCacheDirPath.outputs.dir }} - key: ${{ runner.os }}-yarnCacheDir-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-yarnCacheDir- - - name: Execute yarn - if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} - env: - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - ELECTRON_SKIP_BINARY_DOWNLOAD: 1 - run: yarn --frozen-lockfile --network-timeout 180000 - - - name: Compile and Download - run: yarn npm-run-all --max_old_space_size=4095 -lp compile "electron x64" - - - name: Run Unit Tests - id: electron-unit-tests - run: DISPLAY=:10 ./scripts/test.sh - - - name: Run Integration Tests (Electron) - id: electron-integration-tests - run: DISPLAY=:10 ./scripts/test-integration.sh - -# {{SQL CARBON TODO}} Bring back "Hygiene and Layering" and "Warm up node modules cache" -# hygiene: -# if: github.ref != 'refs/heads/main' -# name: Hygiene and Layering -# runs-on: ubuntu-latest -# timeout-minutes: 40 -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# steps: -# - uses: actions/checkout@v3 - -# - uses: actions/setup-node@v3 -# with: -# node-version: 16 - -# - name: Compute node modules cache key -# id: nodeModulesCacheKey -# run: echo "::set-output name=value::$(node build/azure-pipelines/common/computeNodeModulesCacheKey.js)" -# - name: Cache node modules -# id: cacheNodeModules -# uses: actions/cache@v3 -# with: -# path: "**/node_modules" -# key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} -# restore-keys: ${{ runner.os }}-cacheNodeModules23- -# - name: Get yarn cache directory path -# id: yarnCacheDirPath -# if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} -# run: echo "::set-output name=dir::$(yarn cache dir)" -# - name: Cache yarn directory -# if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} -# uses: actions/cache@v3 -# with: -# path: ${{ steps.yarnCacheDirPath.outputs.dir }} -# key: ${{ runner.os }}-yarnCacheDir-${{ steps.nodeModulesCacheKey.outputs.value }} -# restore-keys: ${{ runner.os }}-yarnCacheDir- -# - name: Execute yarn -# if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} -# env: -# PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 -# ELECTRON_SKIP_BINARY_DOWNLOAD: 1 -# run: yarn --frozen-lockfile --network-timeout 180000 - -# - name: Run Hygiene Checks -# run: yarn gulp hygiene - -# - name: Run Valid Layers Checks -# run: yarn valid-layers-check - -# - name: Compile /build/ -# run: yarn --cwd build compile - -# - name: Check clean git state -# run: ./.github/workflows/check-clean-git-state.sh - -# - name: Run eslint -# run: yarn eslint - -# - name: Run vscode-dts Compile Checks -# run: yarn vscode-dts-compile-check - -# - name: Run Trusted Types Checks -# run: yarn tsec-compile-check - -# warm-cache: -# name: Warm up node modules cache -# if: github.ref == 'refs/heads/main' -# runs-on: ubuntu-latest -# timeout-minutes: 40 -# env: -# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -# steps: -# - uses: actions/checkout@v3 - -# - uses: actions/setup-node@v3 -# with: -# node-version: 16 - -# - name: Compute node modules cache key -# id: nodeModulesCacheKey -# run: echo "::set-output name=value::$(node build/azure-pipelines/common/computeNodeModulesCacheKey.js)" -# - name: Cache node modules -# id: cacheNodeModules -# uses: actions/cache@v3 -# with: -# path: "**/node_modules" -# key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} -# restore-keys: ${{ runner.os }}-cacheNodeModules23- -# - name: Get yarn cache directory path -# id: yarnCacheDirPath -# if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} -# run: echo "::set-output name=dir::$(yarn cache dir)" -# - name: Cache yarn directory -# if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} -# uses: actions/cache@v3 -# with: -# path: ${{ steps.yarnCacheDirPath.outputs.dir }} -# key: ${{ runner.os }}-yarnCacheDir-${{ steps.nodeModulesCacheKey.outputs.value }} -# restore-keys: ${{ runner.os }}-yarnCacheDir- -# - name: Execute yarn -# if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} -# env: -# PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 -# ELECTRON_SKIP_BINARY_DOWNLOAD: 1 -# run: yarn --frozen-lockfile --network-timeout 180000 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f82bb50654..3a95a2ef83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,29 +1,27 @@ name: CI -on: workflow_dispatch - -# on: -# push: -# branches: -# - main -# - release/* -# pull_request: -# branches: -# - main -# - release/* +on: + push: + branches: + - main + - release/* + pull_request: + branches: + - main + - release/* jobs: windows: name: Windows - runs-on: windows-2022 - timeout-minutes: 60 + runs-on: windows-2019 + timeout-minutes: 30 env: CHILD_CONCURRENCY: "1" GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v2 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v2 with: node-version: 16 @@ -250,8 +248,8 @@ jobs: uses: actions/cache@v2 with: path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- + key: ${{ runner.os }}-cacheNodeModules14-${{ steps.nodeModulesCacheKey.outputs.value }} + restore-keys: ${{ runner.os }}-cacheNodeModules14- - name: Get yarn cache directory path id: yarnCacheDirPath if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} @@ -275,98 +273,24 @@ jobs: ELECTRON_SKIP_BINARY_DOWNLOAD: 1 run: yarn --frozen-lockfile --network-timeout 180000 - - name: Compile and Download - run: yarn npm-run-all --max_old_space_size=4095 -lp compile "electron x64" playwright-install download-builtin-extensions - - - name: Compile Integration Tests - run: yarn --cwd test/integration/browser compile - - # This is required for keytar unittests, otherwise we hit - # https://github.com/atom/node-keytar/issues/76 - - name: Create temporary keychain - run: | - security create-keychain -p pwd $RUNNER_TEMP/buildagent.keychain - security default-keychain -s $RUNNER_TEMP/buildagent.keychain - security unlock-keychain -p pwd $RUNNER_TEMP/buildagent.keychain - - - name: Run Unit Tests (Electron) - run: DISPLAY=:10 ./scripts/test.sh - - - name: Run Unit Tests (node.js) - run: yarn test-node - - - name: Run Unit Tests (Browser, Chromium) - run: DISPLAY=:10 yarn test-browser-no-install --browser chromium - - - name: Run Integration Tests (Electron) - run: DISPLAY=:10 ./scripts/test-integration.sh - - - name: Run Integration Tests (Browser, Webkit) - run: DISPLAY=:10 ./scripts/test-web-integration.sh --browser webkit - - - name: Run Integration Tests (Remote) - timeout-minutes: 15 - run: DISPLAY=:10 ./scripts/test-remote-integration.sh - - hygiene: - name: Hygiene and Layering - runs-on: ubuntu-latest - timeout-minutes: 40 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v3 - - - uses: actions/setup-node@v3 - with: - node-version: 16 - - - name: Compute node modules cache key - id: nodeModulesCacheKey - run: echo "::set-output name=value::$(node build/azure-pipelines/common/computeNodeModulesCacheKey.js)" - - name: Cache node modules - id: cacheNodeModules - uses: actions/cache@v2 - with: - path: "**/node_modules" - key: ${{ runner.os }}-cacheNodeModules23-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-cacheNodeModules23- - - name: Get yarn cache directory path - id: yarnCacheDirPath - if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} - run: echo "::set-output name=dir::$(yarn cache dir)" - - name: Cache yarn directory - if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} - uses: actions/cache@v2 - with: - path: ${{ steps.yarnCacheDirPath.outputs.dir }} - key: ${{ runner.os }}-yarnCacheDir-${{ steps.nodeModulesCacheKey.outputs.value }} - restore-keys: ${{ runner.os }}-yarnCacheDir- - - name: Execute yarn - if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }} - env: - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - ELECTRON_SKIP_BINARY_DOWNLOAD: 1 - run: yarn --frozen-lockfile --network-timeout 180000 - - - name: Download Playwright - run: yarn playwright-install - - name: Run Hygiene Checks run: yarn gulp hygiene - name: Run Valid Layers Checks run: yarn valid-layers-check + # - name: Run Monaco Editor Checks {{SQL CARBON EDIT}} Remove Monaco checks + # run: yarn monaco-compile-check + - name: Compile /build/ run: yarn --cwd build compile - - name: Check clean git state - run: ./.github/workflows/check-clean-git-state.sh - - name: Run eslint run: yarn eslint + # {{SQL CARBON EDIT}} Don't need this + # - name: Run Monaco Editor Checks + # run: yarn monaco-compile-check # {{SQL CARBON EDIT}} Don't need this # - name: Run vscode-dts Compile Checks diff --git a/.github/workflows/pr-chat.yml b/.github/workflows/pr-chat.yml deleted file mode 100644 index da4538d5fd..0000000000 --- a/.github/workflows/pr-chat.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: PR Chat -on: - pull_request_target: - types: [opened, ready_for_review, closed] - -jobs: - main: - runs-on: ubuntu-latest - if: ${{ !github.event.pull_request.draft }} - steps: - - name: Checkout Actions - uses: actions/checkout@v2 - with: - repository: "microsoft/vscode-github-triage-actions" - ref: stable - path: ./actions - - name: Install Actions - run: npm install --production --prefix ./actions - - name: Run Code Review Chat - uses: ./actions/code-review-chat - with: - token: ${{secrets.VSCODE_ISSUE_TRIAGE_BOT_PAT}} - slack_token: ${{ secrets.SLACK_TOKEN }} - slack_user_token: ${{ secrets.SLACK_USER_TOKEN }} - slack_bot_name: "VSCodeBot" - notification_channel: codereview diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 0cf077e6b4..0000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -16.14 diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 20d53a66c6..fea1d8007a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,6 +4,6 @@ "recommendations": [ "dbaeumer.vscode-eslint", "EditorConfig.EditorConfig", - "ms-vscode.vscode-selfhost-test-provider" + "redhat.vscode-yaml" ] } diff --git a/.vscode/launch.json b/.vscode/launch.json index b852ce65ee..78e04da078 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,182 +13,14 @@ }, { "type": "node", - "timeout": 0, - "port": 5870, - "outFiles": [ - "${workspaceFolder}/out/**/*.js", - "${workspaceFolder}/extensions/*/out/**/*.js" - ] - }, - { - "type": "pwa-chrome", - "request": "attach", - "name": "Attach to Shared Process", - "timeout": 30000, - "port": 9222, - "urlFilter": "*sharedProcess.html*", - "presentation": { - "hidden": true - } - }, - { - "type": "node", - "request": "attach", - "name": "Attach to Search Process", - "port": 5876, - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ] - }, - { - "type": "node", - "request": "attach", - "name": "Attach to Pty Host Process", - "port": 5877, - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ] - }, - { - "type": "node", - "request": "attach", - "name": "Attach to CLI Process", - "port": 5874, - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ] - }, - { - "type": "node", - "request": "attach", - "name": "Attach to Main Process", - "timeout": 30000, - "port": 5875, - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "presentation": { - "hidden": true, - } - }, - { - "type": "extensionHost", "request": "launch", - "name": "VS Code Emmet Tests", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceFolder}/extensions/emmet/test-workspace", - "--extensionDevelopmentPath=${workspaceFolder}/extensions/emmet", - "--extensionTestsPath=${workspaceFolder}/extensions/emmet/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "presentation": { - "group": "5_tests", - "order": 6 - } - }, - { - "type": "extensionHost", - "request": "launch", - "name": "VS Code Configuration Editing Tests", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/extensions/configuration-editing", - "--extensionTestsPath=${workspaceFolder}/extensions/configuration-editing/out/test" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "presentation": { - "group": "5_tests", - "order": 6 - } - }, - { - "type": "extensionHost", - "request": "launch", - "name": "VS Code Git Tests", - "runtimeExecutable": "${execPath}", - "args": [ - "/tmp/my4g9l", - "--extensionDevelopmentPath=${workspaceFolder}/extensions/git", - "--extensionTestsPath=${workspaceFolder}/extensions/git/out/test" - ], - "outFiles": [ - "${workspaceFolder}/extensions/git/out/**/*.js" - ], - "presentation": { - "group": "5_tests", - "order": 6 - } - }, - { - "type": "extensionHost", - "request": "launch", - "name": "VS Code Github Tests", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceFolder}/extensions/github/testWorkspace", - "--extensionDevelopmentPath=${workspaceFolder}/extensions/github", - "--extensionTestsPath=${workspaceFolder}/extensions/github/out/test" - ], - "outFiles": [ - "${workspaceFolder}/extensions/github/out/**/*.js" - ], - "presentation": { - "group": "5_tests", - "order": 6 - } - }, - { - "type": "extensionHost", - "request": "launch", - "name": "VS Code API Tests (single folder)", - "runtimeExecutable": "${execPath}", - "args": [ - // "${workspaceFolder}", // Uncomment for running out of sources. - "${workspaceFolder}/extensions/vscode-api-tests/testWorkspace", - "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-api-tests", - "--extensionTestsPath=${workspaceFolder}/extensions/vscode-api-tests/out/singlefolder-tests", - "--disable-extensions" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "presentation": { - "group": "5_tests", - "order": 3 - } - }, - { - "type": "extensionHost", - "request": "launch", - "name": "VS Code API Tests (workspace)", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceFolder}/extensions/vscode-api-tests/testworkspace.code-workspace", - "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-api-tests", - "--extensionTestsPath=${workspaceFolder}/extensions/vscode-api-tests/out/workspace-tests" - ], - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "presentation": { - "group": "5_tests", - "order": 4 - } - }, - { - "type": "extensionHost", - "request": "launch", - "name": "VS Code Tokenizer Tests", - "runtimeExecutable": "${execPath}", - "args": [ - "${workspaceFolder}/extensions/vscode-colorize-tests/test", - "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode-colorize-tests", - "--extensionTestsPath=${workspaceFolder}/extensions/vscode-colorize-tests/out" + "name": "Launch Azure Data Studio", + "runtimeExecutable": "${workspaceFolder}/scripts/sql.sh", + "windows": { + "runtimeExecutable": "${workspaceFolder}/scripts/sql.bat", + }, + "runtimeArgs": [ + "--no-cached-data" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" @@ -221,9 +53,6 @@ "runtimeArgs": [ "--inspect=5875", "--no-cached-data", - "--crash-reporter-directory=${workspaceFolder}/.profile-oss/crashes", - // for general runtime freezes: https://github.com/microsoft/vscode/issues/127861#issuecomment-904144910 - "--disable-features=CalculateNativeWinOcclusion", ], "webRoot": "${workspaceFolder}", "cascadeTerminateToConfigurations": [ diff --git a/.vscode/notebooks/api.github-issues b/.vscode/notebooks/api.github-issues index 6ba33aa8ae..1b3790c8cc 100644 --- a/.vscode/notebooks/api.github-issues +++ b/.vscode/notebooks/api.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"July 2022\"" + "value": "$repo=repo:microsoft/vscode\n$milestone=milestone:\"May 2022\"" }, { "kind": 1, diff --git a/.vscode/notebooks/endgame.github-issues b/.vscode/notebooks/endgame.github-issues index d637ade8f2..90cc4971f4 100644 --- a/.vscode/notebooks/endgame.github-issues +++ b/.vscode/notebooks/endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-unpkg\n\n$MILESTONE=milestone:\"July 2022\"" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-unpkg\n\n$MILESTONE=milestone:\"April 2022\"" }, { "kind": 1, diff --git a/.vscode/notebooks/inbox.github-issues b/.vscode/notebooks/inbox.github-issues index 10d7fd63e5..ad451a6f91 100644 --- a/.vscode/notebooks/inbox.github-issues +++ b/.vscode/notebooks/inbox.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$inbox -label:\"info-needed\" sort:created-desc" + "value": "$inbox -label:\"needs more info\" sort:created-desc" }, { "kind": 2, diff --git a/.vscode/notebooks/my-endgame.github-issues b/.vscode/notebooks/my-endgame.github-issues index 25b9625ef3..e2356a2d8a 100644 --- a/.vscode/notebooks/my-endgame.github-issues +++ b/.vscode/notebooks/my-endgame.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal\n\n$MILESTONE=milestone:\"July 2022\"\n\n$MINE=assignee:@me" + "value": "$REPOS=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-js-debug repo:microsoft/vscode-remote-release repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remotehub repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-livepreview repo:microsoft/vscode-python repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal\n\n$MILESTONE=milestone:\"April 2022\"\n\n$MINE=assignee:@me" }, { "kind": 1, @@ -147,7 +147,7 @@ { "kind": 2, "language": "github-issues", - "value": "$REPOS $MILESTONE -$MINE is:issue is:closed author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:triage-needed -label:verification-found" + "value": "$REPOS $MILESTONE -$MINE is:issue is:closed author:@me sort:updated-asc label:bug -label:unreleased -label:verified -label:z-author-verified -label:on-testplan -label:*duplicate -label:duplicate -label:invalid -label:*as-designed -label:error-telemetry -label:verification-steps-needed -label:needs-triage -label:verification-found" }, { "kind": 1, diff --git a/.vscode/notebooks/my-work.github-issues b/.vscode/notebooks/my-work.github-issues index 84f67029d3..3325493e44 100644 --- a/.vscode/notebooks/my-work.github-issues +++ b/.vscode/notebooks/my-work.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce\n\n// current milestone name\n$milestone=milestone:\"July 2022\"" + "value": "// list of repos we work in\n$repos=repo:microsoft/vscode repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-unpkg repo:microsoft/vscode-references-view repo:microsoft/vscode-anycode repo:microsoft/vscode-hexeditor repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-livepreview repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-remote-repositories-github repo:microsoft/monaco-editor repo:microsoft/vscode-vsce\n\n// current milestone name\n$milestone=milestone:\"May 2022\"" }, { "kind": 1, @@ -114,7 +114,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos assignee:@me is:open label:\"needs more info\"" + "value": "$repos assignee:@me is:open label:\"needs more info\"", }, { "kind": 1, diff --git a/.vscode/notebooks/verification.github-issues b/.vscode/notebooks/verification.github-issues index 7015a401be..b4a61ec261 100644 --- a/.vscode/notebooks/verification.github-issues +++ b/.vscode/notebooks/verification.github-issues @@ -12,7 +12,7 @@ { "kind": 2, "language": "github-issues", - "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-jupyter repo:microsoft/vscode-python\n$milestone=milestone:\"May 2022\"" + "value": "$repos=repo:microsoft/vscode repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-dev repo:microsoft/vscode-remote-release repo:microsoft/vscode-js-debug repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-jupyter repo:microsoft/vscode-python\n$milestone=milestone:\"March 2022\"" }, { "kind": 1, diff --git a/.vscode/notebooks/vscode-dev.github-issues b/.vscode/notebooks/vscode-dev.github-issues index 9266fd7654..2178fa29d5 100644 --- a/.vscode/notebooks/vscode-dev.github-issues +++ b/.vscode/notebooks/vscode-dev.github-issues @@ -7,7 +7,7 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode-dev milestone:\"May 2022\" is:open" + "value": "repo:microsoft/vscode-dev milestone:\"December 2021\" is:open" }, { "kind": 2, @@ -32,11 +32,11 @@ { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode-remote-repositories-github milestone:\"May 2022\" is:open" + "value": "repo:microsoft/vscode-remote-repositories-github milestone:\"December 2021\" is:open" }, { "kind": 2, "language": "github-issues", - "value": "repo:microsoft/vscode-remotehub milestone:\"May 2022\" is:open" + "value": "repo:microsoft/vscode-remotehub milestone:\"December 2021\" is:open" } -] \ No newline at end of file +] diff --git a/.vscode/settings.json b/.vscode/settings.json index 718cfd2205..6e9104ae88 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -67,13 +67,6 @@ } ], "git.ignoreLimitWarning": true, - "git.branchProtection": [ - "main", - "release/*" - ], - "git.branchProtectionPrompt": "alwaysCommitToNewBranch", - "git.branchRandomName.enable": true, - "git.mergeEditor": true, "remote.extensionKind": { "msjsdiag.debugger-for-chrome": "workspace" }, diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 7f299f04c7..5e87659ab6 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -112,53 +112,47 @@ Microsoft PROSE SDK: https://microsoft.github.io/prose 23. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site) 24. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar) 25. James-Yu/LaTeX-Workshop version 8.19.1 (https://github.com/James-Yu/LaTeX-Workshop) -26. jeff-hykin/better-c-syntax version 1.13.2 (https://github.com/jeff-hykin/better-c-syntax) -27. jeff-hykin/better-cpp-syntax version 1.15.18 (https://github.com/jeff-hykin/better-cpp-syntax) -28. jeff-hykin/better-objc-syntax version 0.2.0 (https://github.com/jeff-hykin/better-objc-syntax) -29. jeff-hykin/better-objcpp-syntax version 0.1.0 (https://github.com/jeff-hykin/better-objcpp-syntax) -30. jlelong/vscode-latex-basics version 1.3.0 (https://github.com/jlelong/vscode-latex-basics) -31. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) -32. JuliaEditorSupport/atom-language-julia version 0.22.1 (https://github.com/JuliaEditorSupport/atom-language-julia) -33. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) -34. language-docker (https://github.com/moby/moby) -35. language-less version 0.34.2 (https://github.com/atom/language-less) -36. language-php version 0.48.1 (https://github.com/atom/language-php) -37. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) -38. marked version 4.0.16 (https://github.com/markedjs/marked) -39. mdn-data version 1.1.12 (https://github.com/mdn/data) -40. microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/microsoft/TypeScript-TmLanguage) -41. microsoft/vscode-JSON.tmLanguage (https://github.com/microsoft/vscode-JSON.tmLanguage) -42. microsoft/vscode-markdown-tm-grammar version 1.0.0 (https://github.com/microsoft/vscode-markdown-tm-grammar) -43. microsoft/vscode-mssql version 1.16.0 (https://github.com/microsoft/vscode-mssql) -44. mmims/language-batchfile version 0.7.6 (https://github.com/mmims/language-batchfile) -45. NVIDIA/cuda-cpp-grammar (https://github.com/NVIDIA/cuda-cpp-grammar) -46. PowerShell/EditorSyntax version 1.0.0 (https://github.com/PowerShell/EditorSyntax) -47. rust-syntax version 0.5.0 (https://github.com/dustypomerleau/rust-syntax) -48. semver version 5.5.0 (https://github.com/npm/node-semver) -49. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui) -50. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage) -51. sumneko/lua.tmbundle version 1.0.0 (https://github.com/sumneko/lua.tmbundle) -52. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle) -53. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle) -54. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle) -55. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle) -56. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle) -57. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle) -58. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle) -59. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle) -60. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle) -61. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle) -62. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle) -63. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle) -64. trond-snekvik/vscode-rst version 1.5.1 (https://github.com/trond-snekvik/vscode-rst) -65. TypeScript-TmLanguage version 0.1.8 (https://github.com/microsoft/TypeScript-TmLanguage) -66. TypeScript-TmLanguage version 1.0.0 (https://github.com/microsoft/TypeScript-TmLanguage) -67. Unicode version 12.0.0 (https://home.unicode.org/) -68. vscode-codicons version 0.0.14 (https://github.com/microsoft/vscode-codicons) -69. vscode-logfile-highlighter version 2.15.0 (https://github.com/emilast/vscode-logfile-highlighter) -70. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) -71. vscode-win32-app-container-tokens (https://github.com/microsoft/vscode-win32-app-container-tokens) -72. Web Background Synchronization (https://github.com/WICG/background-sync) +26. jeff-hykin/cpp-textmate-grammar version 1.12.11 (https://github.com/jeff-hykin/cpp-textmate-grammar) +27. jeff-hykin/cpp-textmate-grammar version 1.15.5 (https://github.com/jeff-hykin/cpp-textmate-grammar) +28. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify) +29. JuliaEditorSupport/atom-language-julia version 0.21.1 (https://github.com/JuliaEditorSupport/atom-language-julia) +30. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert) +31. language-docker (https://github.com/moby/moby) +32. language-less version 0.34.2 (https://github.com/atom/language-less) +33. language-php version 0.46.2 (https://github.com/atom/language-php) +34. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython) +35. marked version 1.1.0 (https://github.com/markedjs/marked) +36. mdn-data version 1.1.12 (https://github.com/mdn/data) +37. microsoft/TypeScript-TmLanguage version 0.0.1 (https://github.com/microsoft/TypeScript-TmLanguage) +38. microsoft/vscode-JSON.tmLanguage (https://github.com/microsoft/vscode-JSON.tmLanguage) +39. microsoft/vscode-markdown-tm-grammar version 1.0.0 (https://github.com/microsoft/vscode-markdown-tm-grammar) +40. microsoft/vscode-mssql version 1.9.0 (https://github.com/microsoft/vscode-mssql) +41. mmims/language-batchfile version 0.7.6 (https://github.com/mmims/language-batchfile) +42. NVIDIA/cuda-cpp-grammar (https://github.com/NVIDIA/cuda-cpp-grammar) +43. PowerShell/EditorSyntax version 1.0.0 (https://github.com/PowerShell/EditorSyntax) +44. rust-syntax version 0.5.0 (https://github.com/dustypomerleau/rust-syntax) +45. seti-ui version 0.1.0 (https://github.com/jesseweed/seti-ui) +46. shaders-tmLanguage version 0.1.0 (https://github.com/tgjones/shaders-tmLanguage) +47. textmate/asp.vb.net.tmbundle (https://github.com/textmate/asp.vb.net.tmbundle) +48. textmate/c.tmbundle (https://github.com/textmate/c.tmbundle) +49. textmate/diff.tmbundle (https://github.com/textmate/diff.tmbundle) +50. textmate/git.tmbundle (https://github.com/textmate/git.tmbundle) +51. textmate/groovy.tmbundle (https://github.com/textmate/groovy.tmbundle) +52. textmate/html.tmbundle (https://github.com/textmate/html.tmbundle) +53. textmate/ini.tmbundle (https://github.com/textmate/ini.tmbundle) +54. textmate/javascript.tmbundle (https://github.com/textmate/javascript.tmbundle) +55. textmate/lua.tmbundle (https://github.com/textmate/lua.tmbundle) +56. textmate/markdown.tmbundle (https://github.com/textmate/markdown.tmbundle) +57. textmate/perl.tmbundle (https://github.com/textmate/perl.tmbundle) +58. textmate/ruby.tmbundle (https://github.com/textmate/ruby.tmbundle) +59. textmate/yaml.tmbundle (https://github.com/textmate/yaml.tmbundle) +60. TypeScript-TmLanguage version 0.1.8 (https://github.com/microsoft/TypeScript-TmLanguage) +61. TypeScript-TmLanguage version 1.0.0 (https://github.com/microsoft/TypeScript-TmLanguage) +62. Unicode version 12.0.0 (https://home.unicode.org/) +63. vscode-codicons version 0.0.14 (https://github.com/microsoft/vscode-codicons) +64. vscode-logfile-highlighter version 2.11.0 (https://github.com/emilast/vscode-logfile-highlighter) +65. vscode-swift version 0.0.1 (https://github.com/owensd/vscode-swift) +66. Web Background Synchronization (https://github.com/WICG/background-sync) %% atom/language-clojure NOTICES AND INFORMATION BEGIN HERE @@ -1473,50 +1467,7 @@ END OF make-error NOTICES AND INFORMATION ========================================= The MIT License (MIT) -Copyright (c) 2014 Darin Morrison - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -========================================= -END OF freebroccolo/atom-language-swift NOTICES AND INFORMATION - -%% HTML 5.1 W3C Working Draft NOTICES AND INFORMATION BEGIN HERE -========================================= -Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). This software or document includes material copied -from or derived from HTML 5.1 W3C Working Draft (http://www.w3.org/TR/2015/WD-html51-20151008/.) - -THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT -NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF -THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY -PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. - -COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE -DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF. - -The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to this document or its contents -without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders. -========================================= -END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION - -%% Ikuyadeu/vscode-R NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT License - -Copyright (c) 2022 REditorSupport +Copyright (c) 2021 REditorSupport Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -1542,585 +1493,243 @@ END OF mark.js NOTICES AND INFORMATION ========================================= This software is released under the MIT license: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -========================================= -END OF ionide/ionide-fsgrammar NOTICES AND INFORMATION - -%% James-Yu/LaTeX-Workshop NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2016 James Yu - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================= -END OF James-Yu/LaTeX-Workshop NOTICES AND INFORMATION +END OF minimist NOTICES AND INFORMATION -%% jeff-hykin/better-c-syntax NOTICES AND INFORMATION BEGIN HERE +%% moment NOTICES AND INFORMATION BEGIN HERE ========================================= -MIT License - -Copyright (c) 2019 Jeff Hykin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -========================================= -END OF jeff-hykin/better-c-syntax NOTICES AND INFORMATION - -%% jeff-hykin/better-cpp-syntax NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT License - -Copyright (c) 2019 Jeff Hykin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -========================================= -END OF jeff-hykin/better-cpp-syntax NOTICES AND INFORMATION - -%% jeff-hykin/better-objc-syntax NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT License - -Copyright (c) 2019 Jeff Hykin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -========================================= -END OF jeff-hykin/better-objc-syntax NOTICES AND INFORMATION - -%% jeff-hykin/better-objcpp-syntax NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT License - -Copyright (c) 2019 Jeff Hykin - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -========================================= -END OF jeff-hykin/better-objcpp-syntax NOTICES AND INFORMATION - -%% jlelong/vscode-latex-basics NOTICES AND INFORMATION BEGIN HERE -========================================= -Copyright (c) vscode-latex-basics authors - -If not otherwise specified (see below), files in this repository fall under the MIT License - - -The file syntaxes/LaTeX.tmLanguage.json is based on https://github.com/textmate/latex.tmbundle/blob/master/Syntaxes/LaTeX.plist -but has been largely modified. The original file falls under the following license - -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. - -The file syntaxes/markdown-latex-combined.tmLanguage.json is generated from the Markdown grammar -included in VSCode and falls under the license described in markdown-latex-combined-license.txt. - -The file syntaxes/cpp-grammar-bailout.tmLanguage.json is generated from https://github.com/jeff-hykin/better-cpp-syntax -and falls under the license described in cpp-bailout-license.txt. -========================================= -END OF jlelong/vscode-latex-basics NOTICES AND INFORMATION - -%% js-beautify NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -========================================= -END OF js-beautify NOTICES AND INFORMATION - -%% JuliaEditorSupport/atom-language-julia NOTICES AND INFORMATION BEGIN HERE -========================================= -The atom-language-julia package is licensed under the MIT "Expat" License: - -> Copyright (c) 2015 -> -> Permission is hereby granted, free of charge, to any person obtaining -> a copy of this software and associated documentation files (the -> "Software"), to deal in the Software without restriction, including -> without limitation the rights to use, copy, modify, merge, publish, -> distribute, sublicense, and/or sell copies of the Software, and to -> permit persons to whom the Software is furnished to do so, subject to -> the following conditions: -> -> The above copyright notice and this permission notice shall be -> included in all copies or substantial portions of the Software. -> -> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -> IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -> CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -> TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -> SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -========================================= -END OF JuliaEditorSupport/atom-language-julia NOTICES AND INFORMATION - -%% Jxck/assert NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2011 Jxck - -Originally from node.js (http://nodejs.org) -Copyright Joyent, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -========================================= -END OF Jxck/assert NOTICES AND INFORMATION - -%% language-docker NOTICES AND INFORMATION BEGIN HERE -========================================= -Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2013-2018 Docker, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -========================================= -END OF language-docker NOTICES AND INFORMATION - -%% language-less NOTICES AND INFORMATION BEGIN HERE -========================================= -The MIT License (MIT) - -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: +Copyright (c) JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/textmate/less.tmbundle and distributed under the following -license, located in `LICENSE.md`: - -Copyright (c) 2010 Scott Kyle and Rasmus Andersson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. ========================================= -END OF language-less NOTICES AND INFORMATION +END OF moment NOTICES AND INFORMATION -%% language-php NOTICES AND INFORMATION BEGIN HERE + +%% mxgraph NOTICES AND INFORMATION BEGIN HERE ========================================= -The MIT License (MIT) +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -Copyright (c) 2014 GitHub Inc. +1. Definitions. -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. -This package was derived from a TextMate bundle located at -https://github.com/textmate/php.tmbundle and distributed under the following -license, located in `README.mdown`: + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. -Permission to copy, use, modify, sell and distribute this -software is granted. This software is provided "as is" without -express or implied warranty, and with no claim as to its -suitability for any purpose. + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + (e) Neither the Work nor Derivative Works may be used or form any + part of a larger work that integrates or is supposed to be + integrated with a product or service owned or marketed by an + Atlassian entity, including its successors and assignees in title. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +//SEIBERT/MEDIA GmbH, Wiesbaden, Germany is the exclusive licensee of +JGraph for software products based on this codebase within the Atlassian +ecosystem of products. ========================================= -END OF language-php NOTICES AND INFORMATION +END OF mxgraph NOTICES AND INFORMATION -%% MagicStack/MagicPython NOTICES AND INFORMATION BEGIN HERE +%% native-keymap NOTICES AND INFORMATION BEGIN HERE ========================================= -The MIT License +Copyright (c) Microsoft Corporation -Copyright (c) 2015-present MagicStack Inc. http://magic.io - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -========================================= -END OF MagicStack/MagicPython NOTICES AND INFORMATION - -%% marked NOTICES AND INFORMATION BEGIN HERE -========================================= -information - -## Contribution License Agreement - -If you contribute code to this project, you are implicitly allowing your code -to be distributed under the MIT license. You are also implicitly verifying that -all code is your original work. `` - -## Marked - -Copyright (c) 2018+, MarkedJS (https://github.com/markedjs/) -Copyright (c) 2011-2018, Christopher Jeffrey (https://github.com/chjj/) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -## Markdown - -Copyright © 2004, John Gruber -http://daringfireball.net/ All rights reserved. MIT License @@ -2349,11 +1958,23 @@ THE SOFTWARE. ========================================= END OF optimist NOTICES AND INFORMATION -%% vscode-swift NOTICES AND INFORMATION BEGIN HERE +%% primeng NOTICES AND INFORMATION BEGIN HERE ========================================= The MIT License (MIT) -Copyright (c) 2015 David Owens II +Copyright (c) 2016-2017 PrimeTek + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF primeng NOTICES AND INFORMATION + +%% process-nextick-args NOTICES AND INFORMATION BEGIN HERE +========================================= +Copyright (c) 2012-2015, Christopher Jeffrey (https://github.com/chjj/) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -2362,45 +1983,174 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. ========================================= -END OF vscode-swift NOTICES AND INFORMATION +END OF pty.js NOTICES AND INFORMATION -%% vscode-win32-app-container-tokens NOTICES AND INFORMATION BEGIN HERE +%% PyZMQ NOTICES AND INFORMATION BEGIN HERE ========================================= -MIT License +Copyright (c) 2009-2012, Brian Granger, Min Ragan-Kelley -Copyright (c) Microsoft Corporation. +All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +Neither the name of PyZMQ nor the names of its contributors may be used to +endorse or promote products derived from this software without specific prior +written permission. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ========================================= -END OF vscode-win32-app-container-tokens NOTICES AND INFORMATION +END OF pyzmq NOTICES AND INFORMATION -%% Web Background Synchronization NOTICES AND INFORMATION BEGIN HERE +%% reflect-metadata NOTICES AND INFORMATION BEGIN HERE +========================================= +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS +========================================= +END OF reflect-metadata NOTICES AND INFORMATION + +%% request NOTICES AND INFORMATION BEGIN HERE +========================================= +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS +========================================= +END OF request NOTICES AND INFORMATION + +%% rxjs NOTICES AND INFORMATION BEGIN HERE ========================================= Apache License Version 2.0, January 2004 diff --git a/build/.cachesalt b/build/.cachesalt index c0d4fa40fc..3b2a71b972 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2022-07-19T07:55:26.168Z +2022-10-06T02:27:18.022Z diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index 5a8136bb88..0000000000 --- a/build/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.yarnrc diff --git a/build/.moduleignore b/build/.moduleignore index e018f82e09..986fe2a915 100644 --- a/build/.moduleignore +++ b/build/.moduleignore @@ -139,14 +139,6 @@ vscode-encrypt/binding.gyp vscode-encrypt/README.md !vscode-encrypt/build/Release/vscode-encrypt-native.node -vscode-policy-watcher/build/** -vscode-policy-watcher/.husky/** -vscode-policy-watcher/src/** -vscode-policy-watcher/binding.gyp -vscode-policy-watcher/README.md -vscode-policy-watcher/index.d.ts -!vscode-policy-watcher/build/Release/vscode-policy-watcher.node - vscode-windows-ca-certs/**/* !vscode-windows-ca-certs/package.json !vscode-windows-ca-certs/**/*.node diff --git a/build/azure-pipelines/common/computeNodeModulesCacheKey.js b/build/azure-pipelines/common/computeNodeModulesCacheKey.js index 61bbe9e27f..ebe6d97415 100644 --- a/build/azure-pipelines/common/computeNodeModulesCacheKey.js +++ b/build/azure-pipelines/common/computeNodeModulesCacheKey.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); @@ -14,7 +14,7 @@ shasum.update(fs.readFileSync(path.join(ROOT, 'build/.cachesalt'))); shasum.update(fs.readFileSync(path.join(ROOT, '.yarnrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'remote/.yarnrc'))); // Add `package.json` and `yarn.lock` files -for (const dir of dirs) { +for (let dir of dirs) { const packageJsonPath = path.join(ROOT, dir, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); const relevantPackageJsonSections = { diff --git a/build/azure-pipelines/common/computeNodeModulesCacheKey.ts b/build/azure-pipelines/common/computeNodeModulesCacheKey.ts index 8b8869f378..8594304df7 100644 --- a/build/azure-pipelines/common/computeNodeModulesCacheKey.ts +++ b/build/azure-pipelines/common/computeNodeModulesCacheKey.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fs from 'fs'; import * as path from 'path'; import * as crypto from 'crypto'; @@ -17,7 +19,7 @@ shasum.update(fs.readFileSync(path.join(ROOT, '.yarnrc'))); shasum.update(fs.readFileSync(path.join(ROOT, 'remote/.yarnrc'))); // Add `package.json` and `yarn.lock` files -for (const dir of dirs) { +for (let dir of dirs) { const packageJsonPath = path.join(ROOT, dir, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); const relevantPackageJsonSections = { diff --git a/build/azure-pipelines/common/createAsset.js b/build/azure-pipelines/common/createAsset.js index b728d74d40..7f2821aaaf 100644 --- a/build/azure-pipelines/common/createAsset.js +++ b/build/azure-pipelines/common/createAsset.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const crypto = require("crypto"); diff --git a/build/azure-pipelines/common/createAsset.ts b/build/azure-pipelines/common/createAsset.ts index fff05be615..d0193ade67 100644 --- a/build/azure-pipelines/common/createAsset.ts +++ b/build/azure-pipelines/common/createAsset.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fs from 'fs'; import { Readable } from 'stream'; import * as crypto from 'crypto'; diff --git a/build/azure-pipelines/common/createBuild.js b/build/azure-pipelines/common/createBuild.js index dcc6f969bf..4093db2f9d 100644 --- a/build/azure-pipelines/common/createBuild.js +++ b/build/azure-pipelines/common/createBuild.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const identity_1 = require("@azure/identity"); const cosmos_1 = require("@azure/cosmos"); diff --git a/build/azure-pipelines/common/createBuild.ts b/build/azure-pipelines/common/createBuild.ts index 9663d6b3ee..46fcdf267d 100644 --- a/build/azure-pipelines/common/createBuild.ts +++ b/build/azure-pipelines/common/createBuild.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import { ClientSecretCredential } from '@azure/identity'; import { CosmosClient } from '@azure/cosmos'; import { retry } from './retry'; diff --git a/build/azure-pipelines/common/listNodeModules.js b/build/azure-pipelines/common/listNodeModules.js index 308f1882a9..5fad20ec79 100644 --- a/build/azure-pipelines/common/listNodeModules.js +++ b/build/azure-pipelines/common/listNodeModules.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const path = require("path"); diff --git a/build/azure-pipelines/common/listNodeModules.ts b/build/azure-pipelines/common/listNodeModules.ts index 1331087bb9..c96df52179 100644 --- a/build/azure-pipelines/common/listNodeModules.ts +++ b/build/azure-pipelines/common/listNodeModules.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fs from 'fs'; import * as path from 'path'; diff --git a/build/azure-pipelines/common/releaseBuild.js b/build/azure-pipelines/common/releaseBuild.js index 3d7046de9d..f631696131 100644 --- a/build/azure-pipelines/common/releaseBuild.js +++ b/build/azure-pipelines/common/releaseBuild.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const identity_1 = require("@azure/identity"); const cosmos_1 = require("@azure/cosmos"); diff --git a/build/azure-pipelines/common/releaseBuild.ts b/build/azure-pipelines/common/releaseBuild.ts index 1ea27a6964..521267f938 100644 --- a/build/azure-pipelines/common/releaseBuild.ts +++ b/build/azure-pipelines/common/releaseBuild.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import { ClientSecretCredential } from '@azure/identity'; import { CosmosClient } from '@azure/cosmos'; import { retry } from './retry'; diff --git a/build/azure-pipelines/common/retry.js b/build/azure-pipelines/common/retry.js index d2cdab9c8c..06c016281c 100644 --- a/build/azure-pipelines/common/retry.js +++ b/build/azure-pipelines/common/retry.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.retry = void 0; async function retry(fn) { diff --git a/build/azure-pipelines/common/retry.ts b/build/azure-pipelines/common/retry.ts index 1703a4f97a..2f0afd925c 100644 --- a/build/azure-pipelines/common/retry.ts +++ b/build/azure-pipelines/common/retry.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + export async function retry(fn: () => Promise): Promise { let lastError: Error | undefined; diff --git a/build/azure-pipelines/darwin/product-build-darwin-sign.yml b/build/azure-pipelines/darwin/product-build-darwin-sign.yml index 059e848c0b..f82e7a8b98 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-sign.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-sign.yml @@ -35,66 +35,25 @@ steps: git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") displayName: Merge distro - - script: | - mkdir -p .build - node build/azure-pipelines/common/computeNodeModulesCacheKey.js x64 $ENABLE_TERRAPIN > .build/yarnlockhash - displayName: Prepare yarn cache flags - - - task: Cache@2 - inputs: - key: "nodeModules | $(Agent.OS) | .build/yarnlockhash" - path: .build/node_modules_cache - cacheHitVar: NODE_MODULES_RESTORED - displayName: Restore node_modules cache - - - script: | - set -e - tar -xzf .build/node_modules_cache/cache.tgz - displayName: Extract node_modules cache - condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) - - - script: | - set -e - npm install -g node-gyp@latest - node-gyp --version - displayName: Update node-gyp - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - script: | set -e npx https://aka.ms/enablesecurefeed standAlone timeoutInMinutes: 5 retryCountOnTaskFailure: 3 - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true')) + condition: and(succeeded(), eq(variables['ENABLE_TERRAPIN'], 'true')) displayName: Switch to Terrapin packages - script: | set -e - export npm_config_arch=$(VSCODE_ARCH) - export npm_config_node_gyp=$(which node-gyp) - for i in {1..3}; do # try 3 times, for Terrapin - yarn --frozen-lockfile --check-files && break + yarn --cwd build --frozen-lockfile --check-files && break if [ $i -eq 3 ]; then echo "Yarn failed too many times" >&2 exit 1 fi echo "Yarn failed $i, trying again..." done - env: - ELECTRON_SKIP_BINARY_DOWNLOAD: 1 - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Install dependencies - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - - script: | - set -e - node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt - mkdir -p .build/node_modules_cache - tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - displayName: Create node_modules archive + displayName: Install build dependencies - download: current artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive diff --git a/build/azure-pipelines/darwin/product-build-darwin-test.yml b/build/azure-pipelines/darwin/product-build-darwin-test.yml index 1094b41ca2..e28da6547e 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-test.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-test.yml @@ -1,213 +1,270 @@ -parameters: - - name: VSCODE_QUALITY - type: string - - name: VSCODE_RUN_UNIT_TESTS - type: boolean - - name: VSCODE_RUN_INTEGRATION_TESTS - type: boolean - - name: VSCODE_RUN_SMOKE_TESTS - type: boolean - steps: + - task: NodeTool@0 + inputs: + versionSpec: "16.x" + + - task: AzureKeyVault@1 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "vscode-builds-subscription" + KeyVaultName: vscode + SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) + displayName: Download compilation output + + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output + + # Set up the credentials to retrieve distro repo and setup git persona + # to create a merge commit for when we merge distro into oss + - script: | + set -e + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF + + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling + + - script: | + set -e + git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF + echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" + git checkout FETCH_HEAD + condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) + displayName: Checkout override commit + + - script: | + set -e + git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") + displayName: Merge distro + + - script: | + mkdir -p .build + node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash + displayName: Prepare yarn cache flags + + - task: Cache@2 + inputs: + key: "nodeModules | $(Agent.OS) | .build/yarnlockhash" + path: .build/node_modules_cache + cacheHitVar: NODE_MODULES_RESTORED + displayName: Restore node_modules cache + + - script: | + set -e + tar -xzf .build/node_modules_cache/cache.tgz + condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) + displayName: Extract node_modules cache + + - script: | + set -e + npm install -g node-gyp@latest + node-gyp --version + displayName: Update node-gyp + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + + - script: | + set -e + npx https://aka.ms/enablesecurefeed standAlone + timeoutInMinutes: 5 + retryCountOnTaskFailure: 3 + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true')) + displayName: Switch to Terrapin packages + + - script: | + set -e + export npm_config_arch=$(VSCODE_ARCH) + export npm_config_node_gyp=$(which node-gyp) + + for i in {1..3}; do # try 3 times, for Terrapin + yarn --frozen-lockfile --check-files && break + if [ $i -eq 3 ]; then + echo "Yarn failed too many times" >&2 + exit 1 + fi + echo "Yarn failed $i, trying again..." + done + env: + ELECTRON_SKIP_BINARY_DOWNLOAD: 1 + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + GITHUB_TOKEN: "$(github-distro-mixin-password)" + displayName: Install dependencies + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + + - script: | + set -e + node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt + mkdir -p .build/node_modules_cache + tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + displayName: Create node_modules archive + + # This script brings in the right resources (images, icons, etc) based on the quality (insiders, stable, exploration) + - script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality + + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci + displayName: Build client + + - script: | + set -e + node build/azure-pipelines/mixin --server + displayName: Mix in server quality + + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci + displayName: Build Server + - script: | set -e VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" displayName: Download Electron and Playwright + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - ./scripts/test.sh --tfs "Unit Tests" - displayName: Run unit tests (Electron) - timeoutInMinutes: 15 + # Setting hardened entitlements is a requirement for: + # * Running tests on Big Sur (because Big Sur has additional security precautions) + - script: | + set -e + security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain + security default-keychain -s $(agent.tempdirectory)/buildagent.keychain + security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain + echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12 + security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain + VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js + displayName: Set Hardened Entitlements - - script: | - set -e - yarn test-node - displayName: Run unit tests (node.js) - timeoutInMinutes: 15 + - script: | + set -e + ./scripts/test.sh --build --tfs "Unit Tests" + displayName: Run unit tests (Electron) + timeoutInMinutes: 15 - - script: | - set -e - DEBUG=*browser* yarn test-browser-no-install --sequential --browser chromium --browser webkit --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium & Webkit) - timeoutInMinutes: 30 + - script: | + set -e + yarn test-node --build + displayName: Run unit tests (node.js) + timeoutInMinutes: 15 - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - ./scripts/test.sh --build --tfs "Unit Tests" - displayName: Run unit tests (Electron) - timeoutInMinutes: 15 + - script: | + set -e + DEBUG=*browser* yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests" + displayName: Run unit tests (Browser, Chromium & Webkit) + timeoutInMinutes: 30 - - script: | - set -e - yarn test-node --build - displayName: Run unit tests (node.js) - timeoutInMinutes: 15 + - script: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the integration tests + # to run with these builds instead of running out of sources. + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) + APP_NAME="`ls $APP_ROOT | head -n 1`" + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH)" \ + ./scripts/test-integration.sh --build --tfs "Integration Tests" + displayName: Run integration tests (Electron) + timeoutInMinutes: 20 - - script: | - set -e - DEBUG=*browser* yarn test-browser-no-install --sequential --build --browser chromium --browser webkit --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium & Webkit) - timeoutInMinutes: 30 + - script: | + set -e + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin-$(VSCODE_ARCH)" \ + ./scripts/test-web-integration.sh --browser webkit + displayName: Run integration tests (Browser, Webkit) + timeoutInMinutes: 20 - - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - - script: | - set -e - yarn gulp \ - compile-extension:configuration-editing \ - compile-extension:css-language-features-server \ - compile-extension:emmet \ - compile-extension:git \ - compile-extension:github-authentication \ - compile-extension:html-language-features-server \ - compile-extension:ipynb \ - compile-extension:json-language-features-server \ - compile-extension:markdown-language-features-server \ - compile-extension:markdown-language-features \ - compile-extension-media \ - compile-extension:microsoft-authentication \ - compile-extension:typescript-language-features \ - compile-extension:vscode-api-tests \ - compile-extension:vscode-colorize-tests \ - compile-extension:vscode-notebook-tests \ - compile-extension:vscode-test-resolver - displayName: Build integration tests + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) + APP_NAME="`ls $APP_ROOT | head -n 1`" + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH)" \ + ./scripts/test-remote-integration.sh + displayName: Run integration tests (Remote) + timeoutInMinutes: 20 - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - ./scripts/test-integration.sh --tfs "Integration Tests" - displayName: Run integration tests (Electron) - timeoutInMinutes: 20 + - script: | + set -e + ps -ef + displayName: Diagnostics before smoke test run + continueOnError: true + condition: succeededOrFailed() - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - # Figure out the full absolute path of the product we just built - # including the remote server and configure the integration tests - # to run with these builds instead of running out of sources. - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) - APP_NAME="`ls $APP_ROOT | head -n 1`" - INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH)" \ - ./scripts/test-integration.sh --build --tfs "Integration Tests" - displayName: Run integration tests (Electron) - timeoutInMinutes: 20 + - script: | + set -e + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin-$(VSCODE_ARCH)" \ + yarn smoketest-no-compile --web --tracing --headless + timeoutInMinutes: 10 + displayName: Run smoke tests (Browser, Chromium) - - script: | - set -e - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin-$(VSCODE_ARCH)" \ - ./scripts/test-web-integration.sh --browser webkit - displayName: Run integration tests (Browser, Webkit) - timeoutInMinutes: 20 + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) + APP_NAME="`ls $APP_ROOT | head -n 1`" + yarn smoketest-no-compile --tracing --build "$APP_ROOT/$APP_NAME" + timeoutInMinutes: 20 + displayName: Run smoke tests (Electron) - - script: | - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) - APP_NAME="`ls $APP_ROOT | head -n 1`" - INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH)" \ - ./scripts/test-remote-integration.sh - displayName: Run integration tests (Remote) - timeoutInMinutes: 20 + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) + APP_NAME="`ls $APP_ROOT | head -n 1`" + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH)" \ + yarn smoketest-no-compile --tracing --remote --build "$APP_ROOT/$APP_NAME" + timeoutInMinutes: 20 + displayName: Run smoke tests (Remote) - - ${{ if eq(parameters.VSCODE_RUN_SMOKE_TESTS, true) }}: - - script: | - set -e - ps -ef - displayName: Diagnostics before smoke test run - continueOnError: true - condition: succeededOrFailed() + - script: | + set -e + ps -ef + displayName: Diagnostics after smoke test run + continueOnError: true + condition: succeededOrFailed() - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - yarn --cwd test/smoke compile - displayName: Compile smoke tests + - task: PublishPipelineArtifact@0 + inputs: + artifactName: crash-dump-macos-$(VSCODE_ARCH) + targetPath: .build/crashes + displayName: "Publish Crash Reports" + continueOnError: true + condition: failed() - - script: | - set -e - yarn smoketest-no-compile --tracing - timeoutInMinutes: 20 - displayName: Run smoke tests (Electron) + # In order to properly symbolify above crash reports + # (if any), we need the compiled native modules too + - task: PublishPipelineArtifact@0 + inputs: + artifactName: node-modules-macos-$(VSCODE_ARCH) + targetPath: node_modules + displayName: "Publish Node Modules" + continueOnError: true + condition: failed() - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) - APP_NAME="`ls $APP_ROOT | head -n 1`" - yarn smoketest-no-compile --tracing --build "$APP_ROOT/$APP_NAME" - timeoutInMinutes: 20 - displayName: Run smoke tests (Electron) - - - script: | - set -e - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-darwin-$(VSCODE_ARCH)" \ - yarn smoketest-no-compile --web --tracing --headless - timeoutInMinutes: 20 - displayName: Run smoke tests (Browser, Chromium) - - - script: | - set -e - yarn gulp compile-extension:vscode-test-resolver - APP_ROOT=$(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) - APP_NAME="`ls $APP_ROOT | head -n 1`" - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-darwin-$(VSCODE_ARCH)" \ - yarn smoketest-no-compile --tracing --remote --build "$APP_ROOT/$APP_NAME" - timeoutInMinutes: 20 - displayName: Run smoke tests (Remote) - - - script: | - set -e - ps -ef - displayName: Diagnostics after smoke test run - continueOnError: true - condition: succeededOrFailed() - - - ${{ if or(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - - task: PublishPipelineArtifact@0 - inputs: - targetPath: .build/crashes - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: crash-dump-macos-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: crash-dump-macos-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: crash-dump-macos-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Crash Reports" - continueOnError: true - condition: failed() - - # In order to properly symbolify above crash reports - # (if any), we need the compiled native modules too - - task: PublishPipelineArtifact@0 - inputs: - targetPath: node_modules - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: node-modules-macos-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: node-modules-macos-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: node-modules-macos-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Node Modules" - continueOnError: true - condition: failed() - - - task: PublishPipelineArtifact@0 - inputs: - targetPath: .build/logs - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: logs-macos-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: logs-macos-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: logs-macos-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Log Files" - continueOnError: true - condition: succeededOrFailed() + - task: PublishPipelineArtifact@0 + inputs: + artifactName: logs-macos-$(VSCODE_ARCH)-$(System.JobAttempt) + targetPath: .build/logs + displayName: "Publish Log Files" + continueOnError: true + condition: failed() - task: PublishTestResults@2 displayName: Publish Tests Results diff --git a/build/azure-pipelines/darwin/product-build-darwin-universal.yml b/build/azure-pipelines/darwin/product-build-darwin-universal.yml index 929aaf4203..1b8cfef673 100644 --- a/build/azure-pipelines/darwin/product-build-darwin-universal.yml +++ b/build/azure-pipelines/darwin/product-build-darwin-universal.yml @@ -51,50 +51,6 @@ steps: set -e tar -xzf .build/node_modules_cache/cache.tgz displayName: Extract node_modules cache - condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) - - - script: | - set -e - npm install -g node-gyp@latest - node-gyp --version - displayName: Update node-gyp - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - - script: | - set -e - npx https://aka.ms/enablesecurefeed standAlone - timeoutInMinutes: 5 - retryCountOnTaskFailure: 3 - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true')) - displayName: Switch to Terrapin packages - - - script: | - set -e - export npm_config_arch=$(VSCODE_ARCH) - export npm_config_node_gyp=$(which node-gyp) - - for i in {1..3}; do # try 3 times, for Terrapin - yarn --frozen-lockfile --check-files && break - if [ $i -eq 3 ]; then - echo "Yarn failed too many times" >&2 - exit 1 - fi - echo "Yarn failed $i, trying again..." - done - env: - ELECTRON_SKIP_BINARY_DOWNLOAD: 1 - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Install dependencies - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - - script: | - set -e - node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt - mkdir -p .build/node_modules_cache - tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - displayName: Create node_modules archive - script: | set -e diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index eda79c53cf..5c524dd42f 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -1,73 +1,50 @@ -parameters: - - name: VSCODE_PUBLISH - type: boolean - - name: VSCODE_QUALITY - type: string - - name: VSCODE_RUN_UNIT_TESTS - type: boolean - - name: VSCODE_RUN_INTEGRATION_TESTS - type: boolean - - name: VSCODE_RUN_SMOKE_TESTS - type: boolean - steps: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - checkout: self - fetchDepth: 1 - retryCountOnTaskFailure: 3 - - task: NodeTool@0 inputs: versionSpec: "16.x" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: AzureKeyVault@1 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: "vscode-builds-subscription" - KeyVaultName: vscode - SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" + - task: AzureKeyVault@1 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "vscode-builds-subscription" + KeyVaultName: vscode + SecretsFilter: "github-distro-mixin-password,macos-developer-certificate,macos-developer-certificate-key" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: Compilation - path: $(Build.ArtifactStagingDirectory) - displayName: Download compilation output + - task: DownloadPipelineArtifact@2 + inputs: + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) + displayName: Download compilation output - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz - displayName: Extract compilation output + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - cat << EOF > ~/.netrc - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF + - script: | + set -e + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF - git config user.email "vscode@microsoft.com" - git config user.name "VSCode" - displayName: Prepare tooling + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF - echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" - git checkout FETCH_HEAD - condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) - displayName: Checkout override commit + - script: | + set -e + git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF + echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" + git checkout FETCH_HEAD + condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) + displayName: Checkout override commit - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") - displayName: Merge distro + - script: | + set -e + git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") + displayName: Merge distro - script: | mkdir -p .build @@ -87,6 +64,13 @@ steps: condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) displayName: Extract node_modules cache + - script: | + set -e + npm install -g node-gyp@latest + node-gyp --version + displayName: Update node-gyp + condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) + - script: | set -e npx https://aka.ms/enablesecurefeed standAlone @@ -123,142 +107,115 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - # This script brings in the right resources (images, icons, etc) based on the quality (insiders, stable, exploration) - - script: | - set -e - node build/azure-pipelines/mixin - displayName: Mix in quality + # This script brings in the right resources (images, icons, etc) based on the quality (insiders, stable, exploration) + - script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci - displayName: Build client + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-darwin-$(VSCODE_ARCH)-min-ci + displayName: Build client - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - node build/azure-pipelines/mixin --server - displayName: Mix in server quality + - script: | + set -e + node build/azure-pipelines/mixin --server + displayName: Mix in server quality - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci - displayName: Build Server + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-darwin-$(VSCODE_ARCH)-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-web-darwin-$(VSCODE_ARCH)-min-ci + displayName: Build Server - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp "transpile-client" "transpile-extensions" - displayName: Transpile + # Setting hardened entitlements is a requirement for: + # * Apple notarization + # * Running tests on Big Sur (because Big Sur has additional security precautions) + - script: | + set -e + security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain + security default-keychain -s $(agent.tempdirectory)/buildagent.keychain + security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain + echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12 + security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain + VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js + displayName: Set Hardened Entitlements - - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - - template: product-build-darwin-test.yml - parameters: - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }} - VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} + - script: | + set -e + pushd $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) && zip -r -X -y $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH).zip * && popd + displayName: Archive build - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - # Setting hardened entitlements is a requirement for: - # * Apple notarization - # * Running tests on Big Sur (because Big Sur has additional security precautions) - - script: | - set -e - security create-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain - security default-keychain -s $(agent.tempdirectory)/buildagent.keychain - security unlock-keychain -p pwd $(agent.tempdirectory)/buildagent.keychain - echo "$(macos-developer-certificate)" | base64 -D > $(agent.tempdirectory)/cert.p12 - security import $(agent.tempdirectory)/cert.p12 -k $(agent.tempdirectory)/buildagent.keychain -P "$(macos-developer-certificate-key)" -T /usr/bin/codesign - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $(agent.tempdirectory)/buildagent.keychain - VSCODE_ARCH=$(VSCODE_ARCH) DEBUG=electron-osx-sign* node build/darwin/sign.js - displayName: Set Hardened Entitlements + - script: | + set -e - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - script: | - set -e - pushd $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) && zip -r -X -y $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH).zip * && popd - displayName: Archive build + # package Remote Extension Host + pushd .. && mv vscode-reh-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH) && zip -Xry vscode-server-darwin-$(VSCODE_ARCH).zip vscode-server-darwin-$(VSCODE_ARCH) && popd - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - script: | - set -e + # package Remote Extension Host (Web) + pushd .. && mv vscode-reh-web-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH)-web && zip -Xry vscode-server-darwin-$(VSCODE_ARCH)-web.zip vscode-server-darwin-$(VSCODE_ARCH)-web && popd + displayName: Prepare to publish servers - # package Remote Extension Host - pushd .. && mv vscode-reh-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH) && zip -Xry vscode-server-darwin-$(VSCODE_ARCH).zip vscode-server-darwin-$(VSCODE_ARCH) && popd + - publish: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH).zip + artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive + displayName: Publish client archive - # package Remote Extension Host (Web) - pushd .. && mv vscode-reh-web-darwin-$(VSCODE_ARCH) vscode-server-darwin-$(VSCODE_ARCH)-web && zip -Xry vscode-server-darwin-$(VSCODE_ARCH)-web.zip vscode-server-darwin-$(VSCODE_ARCH)-web && popd - displayName: Prepare to publish servers + - publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH).zip + artifact: vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned + displayName: Publish server archive - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: Generate SBOM (client) - inputs: - BuildDropPath: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) - PackageName: Visual Studio Code + - publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web.zip + artifact: vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned + displayName: Publish web server archive - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - publish: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)/_manifest - displayName: Publish SBOM (client) - artifact: vscode_client_darwin_$(VSCODE_ARCH)_sbom + - task: AzureCLI@2 + inputs: + azureSubscription: "vscode-builds-subscription" + scriptType: pscore + scriptLocation: inlineScript + addSpnToEnvironment: true + inlineScript: | + Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" + Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" + Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey" - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: Generate SBOM (server) - inputs: - BuildDropPath: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) - PackageName: Visual Studio Code Server + - script: | + set -e + AZURE_STORAGE_ACCOUNT="ticino" \ + AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ + AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ + AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ + VSCODE_ARCH="$(VSCODE_ARCH)" \ + node build/azure-pipelines/upload-configuration + displayName: Upload configuration (for Bing settings search) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), ne(variables['VSCODE_PUBLISH'], 'false')) + continueOnError: true - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - publish: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)/_manifest - displayName: Publish SBOM (server) - artifact: vscode_server_darwin_$(VSCODE_ARCH)_sbom + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: Generate SBOM (client) + inputs: + BuildDropPath: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH) + PackageName: Visual Studio Code + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - publish: $(Agent.BuildDirectory)/VSCode-darwin-$(VSCODE_ARCH).zip - artifact: unsigned_vscode_client_darwin_$(VSCODE_ARCH)_archive - displayName: Publish client archive + - publish: $(agent.builddirectory)/VSCode-darwin-$(VSCODE_ARCH)/_manifest + displayName: Publish SBOM (client) + artifact: vscode_client_darwin_$(VSCODE_ARCH)_sbom + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH).zip - artifact: vscode_server_darwin_$(VSCODE_ARCH)_archive-unsigned - displayName: Publish server archive + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: Generate SBOM (server) + inputs: + BuildDropPath: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH) + PackageName: Visual Studio Code Server + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - publish: $(Agent.BuildDirectory)/vscode-server-darwin-$(VSCODE_ARCH)-web.zip - artifact: vscode_web_darwin_$(VSCODE_ARCH)_archive-unsigned - displayName: Publish web server archive - - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - task: AzureCLI@2 - inputs: - azureSubscription: "vscode-builds-subscription" - scriptType: pscore - scriptLocation: inlineScript - addSpnToEnvironment: true - inlineScript: | - Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" - Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" - Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey" - - - ${{ if and(eq(parameters.VSCODE_PUBLISH, true), eq(parameters.VSCODE_RUN_UNIT_TESTS, false), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - - script: | - set -e - AZURE_STORAGE_ACCOUNT="ticino" \ - AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ - AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ - AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ - VSCODE_ARCH="$(VSCODE_ARCH)" \ - node build/azure-pipelines/upload-configuration - displayName: Upload configuration (for Bing settings search) - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - continueOnError: true + - publish: $(agent.builddirectory)/vscode-server-darwin-$(VSCODE_ARCH)/_manifest + displayName: Publish SBOM (server) + artifact: vscode_server_darwin_$(VSCODE_ARCH)_sbom + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) diff --git a/build/azure-pipelines/darwin/sql-product-build-darwin.yml b/build/azure-pipelines/darwin/sql-product-build-darwin.yml index b3e07e96df..fb5082ecaf 100644 --- a/build/azure-pipelines/darwin/sql-product-build-darwin.yml +++ b/build/azure-pipelines/darwin/sql-product-build-darwin.yml @@ -112,19 +112,18 @@ steps: displayName: Run unit tests condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true')) -# {{SQL CARBON TODO}} Reenable "Run Core Integration Tests" - # - script: | - # # Figure out the full absolute path of the product we just built - # # including the remote server and configure the integration tests - # # to run with these builds instead of running out of sources. - # set -e - # APP_ROOT=$(agent.builddirectory)/azuredatastudio-darwin-x64 - # APP_NAME="`ls $APP_ROOT | head -n 1`" - # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ - # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-darwin" \ - # ./scripts/test-integration.sh --build --tfs "Integration Tests" - # displayName: Run core integration tests - # condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true')) + - script: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the integration tests + # to run with these builds instead of running out of sources. + set -e + APP_ROOT=$(agent.builddirectory)/azuredatastudio-darwin-x64 + APP_NAME="`ls $APP_ROOT | head -n 1`" + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME/Contents/MacOS/Electron" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-darwin" \ + ./scripts/test-integration.sh --build --tfs "Integration Tests" + displayName: Run core integration tests + condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true')) - script: | set -e diff --git a/build/azure-pipelines/distro-build.yml b/build/azure-pipelines/distro-build.yml index db2d245cc5..19af20b090 100644 --- a/build/azure-pipelines/distro-build.yml +++ b/build/azure-pipelines/distro-build.yml @@ -4,7 +4,9 @@ pool: trigger: branches: include: ["main", "release/*"] -pr: none +pr: + branches: + include: ["main", "release/*"] steps: - task: NodeTool@0 diff --git a/build/azure-pipelines/linux/product-build-alpine.yml b/build/azure-pipelines/linux/product-build-alpine.yml index 3aef727924..74577b52a6 100644 --- a/build/azure-pipelines/linux/product-build-alpine.yml +++ b/build/azure-pipelines/linux/product-build-alpine.yml @@ -118,9 +118,7 @@ steps: - script: | set -e - docker run -e VSCODE_QUALITY -e GITHUB_TOKEN -v $(pwd):/root/vscode -v ~/.netrc:/root/.netrc vscodehub.azurecr.io/vscode-linux-build-agent:alpine-$(VSCODE_ARCH) /root/vscode/build/azure-pipelines/linux/scripts/install-remote-dependencies.sh - env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" + docker run -e VSCODE_QUALITY -v $(pwd):/root/vscode -v ~/.netrc:/root/.netrc vscodehub.azurecr.io/vscode-linux-build-agent:alpine-$(VSCODE_ARCH) /root/vscode/build/azure-pipelines/linux/scripts/install-remote-dependencies.sh displayName: Prebuild - script: | diff --git a/build/azure-pipelines/linux/product-build-linux-client-test.yml b/build/azure-pipelines/linux/product-build-linux-client-test.yml deleted file mode 100644 index 31d477e93a..0000000000 --- a/build/azure-pipelines/linux/product-build-linux-client-test.yml +++ /dev/null @@ -1,272 +0,0 @@ -parameters: - - name: VSCODE_QUALITY - type: string - - name: VSCODE_RUN_UNIT_TESTS - type: boolean - - name: VSCODE_RUN_INTEGRATION_TESTS - type: boolean - - name: VSCODE_RUN_SMOKE_TESTS - type: boolean - -steps: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" - displayName: Download Electron and Playwright - - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - sudo apt-get update - sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0 libgbm1 - sudo cp build/azure-pipelines/linux/xvfb.init /etc/init.d/xvfb - sudo chmod +x /etc/init.d/xvfb - sudo update-rc.d xvfb defaults - sudo service xvfb start - displayName: Setup build environment - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - ELECTRON_ROOT=.build/electron - sudo chown root $APP_ROOT/chrome-sandbox - sudo chown root $ELECTRON_ROOT/chrome-sandbox - sudo chmod 4755 $APP_ROOT/chrome-sandbox - sudo chmod 4755 $ELECTRON_ROOT/chrome-sandbox - stat $APP_ROOT/chrome-sandbox - stat $ELECTRON_ROOT/chrome-sandbox - displayName: Change setuid helper binary permission - - - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - DISPLAY=:10 ./scripts/test.sh --tfs "Unit Tests" - displayName: Run unit tests (Electron) - timeoutInMinutes: 15 - - - script: | - set -e - yarn test-node - displayName: Run unit tests (node.js) - timeoutInMinutes: 15 - - - script: | - set -e - DEBUG=*browser* yarn test-browser-no-install --browser chromium --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium) - timeoutInMinutes: 15 - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - ./scripts/test.sh --build --tfs "Unit Tests" - displayName: Run unit tests (Electron) - timeoutInMinutes: 15 - - - script: | - set -e - yarn test-node --build - displayName: Run unit tests (node.js) - timeoutInMinutes: 15 - - - script: | - set -e - DEBUG=*browser* yarn test-browser-no-install --build --browser chromium --tfs "Browser Unit Tests" - displayName: Run unit tests (Browser, Chromium) - timeoutInMinutes: 15 - - - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - - script: | - set -e - yarn gulp \ - compile-extension:configuration-editing \ - compile-extension:css-language-features-server \ - compile-extension:emmet \ - compile-extension:git \ - compile-extension:github-authentication \ - compile-extension:html-language-features-server \ - compile-extension:ipynb \ - compile-extension:json-language-features-server \ - compile-extension:markdown-language-features-server \ - compile-extension:markdown-language-features \ - compile-extension-media \ - compile-extension:microsoft-authentication \ - compile-extension:typescript-language-features \ - compile-extension:vscode-api-tests \ - compile-extension:vscode-colorize-tests \ - compile-extension:vscode-notebook-tests \ - compile-extension:vscode-test-resolver - displayName: Build integration tests - - - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - DISPLAY=:10 ./scripts/test-integration.sh --tfs "Integration Tests" - displayName: Run integration tests (Electron) - timeoutInMinutes: 20 - - - script: | - set -e - ./scripts/test-web-integration.sh --browser chromium - displayName: Run integration tests (Browser, Chromium) - timeoutInMinutes: 20 - - - script: | - set -e - ./scripts/test-remote-integration.sh - displayName: Run integration tests (Remote) - timeoutInMinutes: 20 - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - # Figure out the full absolute path of the product we just built - # including the remote server and configure the integration tests - # to run with these builds instead of running out of sources. - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - INTEGRATION_TEST_APP_NAME="$APP_NAME" \ - INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - ./scripts/test-integration.sh --build --tfs "Integration Tests" - displayName: Run integration tests (Electron) - timeoutInMinutes: 20 - - - script: | - set -e - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ - ./scripts/test-web-integration.sh --browser chromium - displayName: Run integration tests (Browser, Chromium) - timeoutInMinutes: 20 - - - script: | - set -e - APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - INTEGRATION_TEST_APP_NAME="$APP_NAME" \ - INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - ./scripts/test-remote-integration.sh - displayName: Run integration tests (Remote) - timeoutInMinutes: 20 - - - ${{ if eq(parameters.VSCODE_RUN_SMOKE_TESTS, true) }}: - - script: | - set -e - ps -ef - cat /proc/sys/fs/inotify/max_user_watches - lsof | wc -l - displayName: Diagnostics before smoke test run (processes, max_user_watches, number of opened file handles) - continueOnError: true - condition: succeededOrFailed() - - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - yarn --cwd test/smoke compile - displayName: Compile smoke tests - - - script: | - set -e - yarn smoketest-no-compile --tracing - timeoutInMinutes: 20 - displayName: Run smoke tests (Electron) - - - script: | - set -e - yarn smoketest-no-compile --web --tracing --headless --electronArgs="--disable-dev-shm-usage" - timeoutInMinutes: 20 - displayName: Run smoke tests (Browser, Chromium) - - - script: | - set -e - yarn gulp compile-extension:vscode-test-resolver - yarn smoketest-no-compile --remote --tracing - timeoutInMinutes: 20 - displayName: Run smoke tests (Remote) - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - yarn smoketest-no-compile --tracing --build "$APP_PATH" - timeoutInMinutes: 20 - displayName: Run smoke tests (Electron) - - - script: | - set -e - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ - yarn smoketest-no-compile --web --tracing --headless --electronArgs="--disable-dev-shm-usage" - timeoutInMinutes: 20 - displayName: Run smoke tests (Browser, Chromium) - - - script: | - set -e - yarn gulp compile-extension:vscode-test-resolver - APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ - yarn smoketest-no-compile --tracing --remote --build "$APP_PATH" - timeoutInMinutes: 20 - displayName: Run smoke tests (Remote) - - - script: | - set -e - ps -ef - cat /proc/sys/fs/inotify/max_user_watches - lsof | wc -l - displayName: Diagnostics after smoke test run (processes, max_user_watches, number of opened file handles) - continueOnError: true - condition: succeededOrFailed() - - - ${{ if or(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - - task: PublishPipelineArtifact@0 - inputs: - targetPath: .build/crashes - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: crash-dump-linux-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: crash-dump-linux-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: crash-dump-linux-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Crash Reports" - continueOnError: true - condition: failed() - - # In order to properly symbolify above crash reports - # (if any), we need the compiled native modules too - - task: PublishPipelineArtifact@0 - inputs: - targetPath: node_modules - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: node-modules-linux-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: node-modules-linux-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: node-modules-linux-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Node Modules" - continueOnError: true - condition: failed() - - - task: PublishPipelineArtifact@0 - inputs: - targetPath: .build/logs - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: logs-linux-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: logs-linux-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: logs-linux-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Log Files" - continueOnError: true - condition: succeededOrFailed() - - - task: PublishTestResults@2 - displayName: Publish Tests Results - inputs: - testResultsFiles: "*-results.xml" - searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" - condition: succeededOrFailed() diff --git a/build/azure-pipelines/linux/product-build-linux-client.yml b/build/azure-pipelines/linux/product-build-linux-client.yml index 97a9cf31d6..b6472b5e57 100644 --- a/build/azure-pipelines/linux/product-build-linux-client.yml +++ b/build/azure-pipelines/linux/product-build-linux-client.yml @@ -1,113 +1,79 @@ -parameters: - - name: VSCODE_PUBLISH - type: boolean - - name: VSCODE_QUALITY - type: string - - name: VSCODE_RUN_UNIT_TESTS - type: boolean - - name: VSCODE_RUN_INTEGRATION_TESTS - type: boolean - - name: VSCODE_RUN_SMOKE_TESTS - type: boolean - steps: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - checkout: self - fetchDepth: 1 - retryCountOnTaskFailure: 3 - - task: NodeTool@0 inputs: versionSpec: "16.x" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: AzureKeyVault@1 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: "vscode-builds-subscription" - KeyVaultName: vscode - SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" + - task: AzureKeyVault@1 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "vscode-builds-subscription" + KeyVaultName: vscode + SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: Compilation - path: $(Build.ArtifactStagingDirectory) - displayName: Download compilation output + - task: DownloadPipelineArtifact@2 + inputs: + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) + displayName: Download compilation output - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: reh_node_modules-$(VSCODE_ARCH) - path: $(Build.ArtifactStagingDirectory) - displayName: Download server build dependencies - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf')) + - task: DownloadPipelineArtifact@2 + inputs: + artifact: reh_node_modules-$(VSCODE_ARCH) + path: $(Build.ArtifactStagingDirectory) + displayName: Download server build dependencies + condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - # Start X server - /etc/init.d/xvfb start - # Start dbus session - DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address) - echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT" - displayName: Setup system services - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) + - script: | + set -e + # Start X server + /etc/init.d/xvfb start + # Start dbus session + DBUS_LAUNCH_RESULT=$(sudo dbus-daemon --config-file=/usr/share/dbus-1/system.conf --print-address) + echo "##vso[task.setvariable variable=DBUS_SESSION_BUS_ADDRESS]$DBUS_LAUNCH_RESULT" + displayName: Setup system services + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz - displayName: Extract compilation output + - script: | + set -e + tar -xzf $(Build.ArtifactStagingDirectory)/compilation.tar.gz + displayName: Extract compilation output - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - cat << EOF > ~/.netrc - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF + - script: | + set -e + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF - git config user.email "vscode@microsoft.com" - git config user.name "VSCode" - displayName: Prepare tooling + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF - echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" - git checkout FETCH_HEAD - condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) - displayName: Checkout override commit + - script: | + set -e + git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF + echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" + git checkout FETCH_HEAD + condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) + displayName: Checkout override commit - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") - displayName: Merge distro + - script: | + set -e + git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") + displayName: Merge distro - script: | mkdir -p .build node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash displayName: Prepare yarn cache flags - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - task: Cache@2 - inputs: - key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash" - path: .build/node_modules_cache - cacheHitVar: NODE_MODULES_RESTORED - displayName: Restore node_modules cache - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: Cache@2 - inputs: - key: "nodeModules | $(Agent.OS) | .build/yarnlockhash" - path: .build/node_modules_cache - cacheHitVar: NODE_MODULES_RESTORED - displayName: Restore node_modules cache + - task: Cache@2 + inputs: + key: "nodeModules | $(Agent.OS) | .build/yarnlockhash" + path: .build/node_modules_cache + cacheHitVar: NODE_MODULES_RESTORED + displayName: Restore node_modules cache - script: | set -e @@ -125,7 +91,6 @@ steps: - script: | set -e - node build/npm/setupBuildYarnrc for i in {1..3}; do # try 3 times, for Terrapin yarn --cwd build --frozen-lockfile --check-files && break if [ $i -eq 3 ]; then @@ -138,16 +103,7 @@ steps: - script: | set -e - if [ "$NPM_ARCH" = "armv7l" ]; then - # There is no target_arch="armv7l" supported by node_gyp, - # arm versions for compilation are decided based on the CC - # macros. - # Mapping value is based on - # https://github.com/nodejs/node/blob/0903515e126c2697042d6546c6aa4b72e1a4b33e/configure.py#L49-L50 - export npm_config_arch="arm" - else - export npm_config_arch=$(NPM_ARCH) - fi + export npm_config_arch=$(NPM_ARCH) if [ -z "$CC" ] || [ -z "$CXX" ]; then # Download clang based on chromium revision used by vscode @@ -187,13 +143,12 @@ steps: displayName: Install dependencies condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - rm -rf remote/node_modules - tar -xzf $(Build.ArtifactStagingDirectory)/reh_node_modules-$(VSCODE_ARCH).tar.gz --directory $(Build.SourcesDirectory)/remote - displayName: Extract server node_modules output - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf')) + - script: | + set -e + rm -rf remote/node_modules + tar -xzf $(Build.ArtifactStagingDirectory)/reh_node_modules-$(VSCODE_ARCH).tar.gz --directory $(Build.SourcesDirectory)/remote + displayName: Extract server node_modules output + condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'armhf')) - script: | set -e @@ -203,136 +158,267 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - node build/azure-pipelines/mixin - displayName: Mix in quality + - script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci - displayName: Build + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-linux-$(VSCODE_ARCH)-min-ci + displayName: Build - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - node build/azure-pipelines/mixin --server - displayName: Mix in server quality + - script: | + set -e + node build/azure-pipelines/mixin --server + displayName: Mix in server quality - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci - displayName: Build Server + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-linux-$(VSCODE_ARCH)-min-ci + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn gulp vscode-reh-web-linux-$(VSCODE_ARCH)-min-ci + displayName: Build Server - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn gulp "transpile-client" "transpile-extensions" - displayName: Transpile + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" + displayName: Download Electron and Playwright - - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - - template: product-build-linux-client-test.yml - parameters: - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }} - VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + ELECTRON_ROOT=.build/electron + sudo chown root $APP_ROOT/chrome-sandbox + sudo chown root $ELECTRON_ROOT/chrome-sandbox + sudo chmod 4755 $APP_ROOT/chrome-sandbox + sudo chmod 4755 $ELECTRON_ROOT/chrome-sandbox + stat $APP_ROOT/chrome-sandbox + stat $ELECTRON_ROOT/chrome-sandbox + displayName: Change setuid helper binary permission - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - script: | - set -e - yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-deb" - yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm" - displayName: Build deb, rpm packages + - script: | + set -e + ./scripts/test.sh --build --tfs "Unit Tests" + displayName: Run unit tests (Electron) + timeoutInMinutes: 15 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - script: | - set -e - yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap" - displayName: Prepare snap package + - script: | + set -e + yarn test-node --build + displayName: Run unit tests (node.js) + timeoutInMinutes: 15 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: UseDotNet@2 - inputs: - version: 2.x + - script: | + set -e + DEBUG=*browser* yarn test-browser-no-install --build --browser chromium --tfs "Browser Unit Tests" + displayName: Run unit tests (Browser, Chromium) + timeoutInMinutes: 15 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: EsrpClientTool@1 - displayName: Download ESRPClient + - script: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the integration tests + # to run with these builds instead of running out of sources. + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + INTEGRATION_TEST_APP_NAME="$APP_NAME" \ + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + ./scripts/test-integration.sh --build --tfs "Integration Tests" + displayName: Run integration tests (Electron) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - script: | - set -e - node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' - displayName: Codesign rpm + - script: | + set -e + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ + ./scripts/test-web-integration.sh --browser chromium + displayName: Run integration tests (Browser, Chromium) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - script: | - set -e - VSCODE_ARCH="$(VSCODE_ARCH)" \ - ./build/azure-pipelines/linux/prepare-publish.sh - displayName: Prepare for Publish + - script: | + set -e + APP_ROOT=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + INTEGRATION_TEST_APP_NAME="$APP_NAME" \ + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + ./scripts/test-remote-integration.sh + displayName: Run integration tests (Remote) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: Generate SBOM (client) - inputs: - BuildDropPath: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) - PackageName: Visual Studio Code + - script: | + set -e + ps -ef + cat /proc/sys/fs/inotify/max_user_watches + lsof | wc -l + displayName: Diagnostics before smoke test run (processes, max_user_watches, number of opened file handles) + continueOnError: true + condition: and(succeededOrFailed(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/_manifest - displayName: Publish SBOM (client) - artifact: vscode_client_linux_$(VSCODE_ARCH)_sbom + - script: | + set -e + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-web-linux-$(VSCODE_ARCH)" \ + yarn smoketest-no-compile --web --tracing --headless --electronArgs="--disable-dev-shm-usage" + timeoutInMinutes: 10 + displayName: Run smoke tests (Browser, Chromium) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: Generate SBOM (server) - inputs: - BuildDropPath: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH) - PackageName: Visual Studio Code Server + - script: | + set -e + APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + yarn smoketest-no-compile --tracing --build "$APP_PATH" + timeoutInMinutes: 20 + displayName: Run smoke tests (Electron) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)/_manifest - displayName: Publish SBOM (server) - artifact: vscode_server_linux_$(VSCODE_ARCH)_sbom + - script: | + set -e + APP_PATH=$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/vscode-reh-linux-$(VSCODE_ARCH)" \ + yarn smoketest-no-compile --tracing --remote --build "$APP_PATH" + timeoutInMinutes: 20 + displayName: Run smoke tests (Remote) + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(DEB_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package - displayName: Publish deb package + - script: | + set -e + ps -ef + cat /proc/sys/fs/inotify/max_user_watches + lsof | wc -l + displayName: Diagnostics after smoke test run (processes, max_user_watches, number of opened file handles) + continueOnError: true + condition: and(succeededOrFailed(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(RPM_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package - displayName: Publish rpm package + - task: PublishPipelineArtifact@0 + inputs: + artifactName: crash-dump-linux-$(VSCODE_ARCH) + targetPath: .build/crashes + displayName: "Publish Crash Reports" + continueOnError: true + condition: failed() - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(TARBALL_PATH) - artifact: vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned - displayName: Publish client archive + # In order to properly symbolify above crash reports + # (if any), we need the compiled native modules too + - task: PublishPipelineArtifact@0 + inputs: + artifactName: node-modules-linux-$(VSCODE_ARCH) + targetPath: node_modules + displayName: "Publish Node Modules" + continueOnError: true + condition: failed() - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH).tar.gz - artifact: vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned - displayName: Publish server archive + - task: PublishPipelineArtifact@0 + inputs: + artifactName: logs-linux-$(VSCODE_ARCH)-$(System.JobAttempt) + targetPath: .build/logs + displayName: "Publish Log Files" + continueOnError: true + condition: and(failed(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz - artifact: vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned - displayName: Publish web server archive + - task: PublishTestResults@2 + displayName: Publish Tests Results + inputs: + testResultsFiles: "*-results.xml" + searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" + condition: and(succeededOrFailed(), eq(variables['VSCODE_ARCH'], 'x64'), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: PublishPipelineArtifact@0 - displayName: "Publish Pipeline Artifact" - inputs: - artifactName: "snap-$(VSCODE_ARCH)" - targetPath: .build/linux/snap-tarball + - script: | + set -e + yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-deb" + yarn gulp "vscode-linux-$(VSCODE_ARCH)-build-rpm" + displayName: Build deb, rpm packages + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - script: | + set -e + yarn gulp "vscode-linux-$(VSCODE_ARCH)-prepare-snap" + displayName: Prepare snap package + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - task: UseDotNet@2 + inputs: + version: 2.x + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - task: EsrpClientTool@1 + displayName: Download ESRPClient + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - script: | + set -e + node build/azure-pipelines/common/sign "$(esrpclient.toolpath)/$(esrpclient.toolname)" rpm $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) .build/linux/rpm '*.rpm' + displayName: Codesign rpm + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - script: | + set -e + VSCODE_ARCH="$(VSCODE_ARCH)" \ + ./build/azure-pipelines/linux/prepare-publish.sh + displayName: Prepare for Publish + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(DEB_PATH) + artifact: vscode_client_linux_$(VSCODE_ARCH)_deb-package + displayName: Publish deb package + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(RPM_PATH) + artifact: vscode_client_linux_$(VSCODE_ARCH)_rpm-package + displayName: Publish rpm package + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(TARBALL_PATH) + artifact: vscode_client_linux_$(VSCODE_ARCH)_archive-unsigned + displayName: Publish client archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH).tar.gz + artifact: vscode_server_linux_$(VSCODE_ARCH)_archive-unsigned + displayName: Publish server archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(Agent.BuildDirectory)/vscode-server-linux-$(VSCODE_ARCH)-web.tar.gz + artifact: vscode_web_linux_$(VSCODE_ARCH)_archive-unsigned + displayName: Publish web server archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - task: PublishPipelineArtifact@0 + displayName: "Publish Pipeline Artifact" + inputs: + artifactName: "snap-$(VSCODE_ARCH)" + targetPath: .build/linux/snap-tarball + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: Generate SBOM (client) + inputs: + BuildDropPath: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH) + PackageName: Visual Studio Code + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/_manifest + displayName: Publish SBOM (client) + artifact: vscode_client_linux_$(VSCODE_ARCH)_sbom + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: Generate SBOM (server) + inputs: + BuildDropPath: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH) + PackageName: Visual Studio Code Server + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(agent.builddirectory)/vscode-server-linux-$(VSCODE_ARCH)/_manifest + displayName: Publish SBOM (server) + artifact: vscode_server_linux_$(VSCODE_ARCH)_sbom + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) diff --git a/build/azure-pipelines/linux/product-build-linux-server.yml b/build/azure-pipelines/linux/product-build-linux-server.yml index 8ab58da435..07fa3e4649 100644 --- a/build/azure-pipelines/linux/product-build-linux-server.yml +++ b/build/azure-pipelines/linux/product-build-linux-server.yml @@ -1,58 +1,49 @@ -parameters: - - name: VSCODE_QUALITY - type: string - steps: - task: NodeTool@0 inputs: versionSpec: "16.x" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: AzureKeyVault@1 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: "vscode-builds-subscription" - KeyVaultName: vscode - SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" + - task: AzureKeyVault@1 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "vscode-builds-subscription" + KeyVaultName: vscode + SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: Docker@1 - displayName: "Pull Docker image" - inputs: - azureSubscriptionEndpoint: "vscode-builds-subscription" - azureContainerRegistry: vscodehub.azurecr.io - command: "Run an image" - imageName: "vscode-linux-build-agent:centos7-devtoolset8-arm64" - containerCommand: uname - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) + - task: Docker@1 + displayName: "Pull Docker image" + inputs: + azureSubscriptionEndpoint: "vscode-builds-subscription" + azureContainerRegistry: vscodehub.azurecr.io + command: "Run an image" + imageName: "vscode-linux-build-agent:centos7-devtoolset8-arm64" + containerCommand: uname + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - cat << EOF > ~/.netrc - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF + - script: | + set -e + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF - git config user.email "vscode@microsoft.com" - git config user.name "VSCode" - displayName: Prepare tooling + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF - echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" - git checkout FETCH_HEAD - condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) - displayName: Checkout override commit + - script: | + set -e + git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF + echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" + git checkout FETCH_HEAD + condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) + displayName: Checkout override commit - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") - displayName: Merge distro + - script: | + set -e + git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") + displayName: Merge distro - script: | set -e @@ -70,19 +61,17 @@ steps: GITHUB_TOKEN: "$(github-distro-mixin-password)" condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'x64')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - displayName: Register Docker QEMU - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) + - script: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + displayName: Register Docker QEMU + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - docker run -e VSCODE_QUALITY -e GITHUB_TOKEN -v $(pwd):/root/vscode -v ~/.netrc:/root/.netrc vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-arm64 /root/vscode/build/azure-pipelines/linux/scripts/install-remote-dependencies.sh - displayName: Install dependencies via qemu - env: - GITHUB_TOKEN: "$(github-distro-mixin-password)" - condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) + - script: | + set -e + docker run -e VSCODE_QUALITY -e GITHUB_TOKEN -v $(pwd):/root/vscode -v ~/.netrc:/root/.netrc vscodehub.azurecr.io/vscode-linux-build-agent:centos7-devtoolset8-arm64 /root/vscode/build/azure-pipelines/linux/scripts/install-remote-dependencies.sh + displayName: Install dependencies via qemu + env: + GITHUB_TOKEN: "$(github-distro-mixin-password)" + condition: and(succeeded(), eq(variables['VSCODE_ARCH'], 'arm64')) - script: | set -e diff --git a/build/azure-pipelines/linux/sql-product-build-linux.yml b/build/azure-pipelines/linux/sql-product-build-linux.yml index 4d6d2fae20..5f29358cc5 100644 --- a/build/azure-pipelines/linux/sql-product-build-linux.yml +++ b/build/azure-pipelines/linux/sql-product-build-linux.yml @@ -136,56 +136,54 @@ steps: displayName: Run core integration tests condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'), ne(variables['EXTENSIONS_ONLY'], 'true')) -# {{SQL CARBON TODO}} Reenable "Run Extension Unit Tests (Continue on Error)" and "Run Extension Unit Tests (Fail on Error)" and "Archive Logs" - # - script: | - # # Figure out the full absolute path of the product we just built - # # including the remote server and configure the unit tests - # # to run with these builds instead of running out of sources. - # set -e - # APP_ROOT=$(agent.builddirectory)/azuredatastudio-linux-x64 - # APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - # NO_CLEANUP=1 \ - # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-linux-x64" \ - # DISPLAY=:10 ./scripts/test-extensions-unit.sh --build --tfs "Extension Unit Tests" - # displayName: Run Extension Unit Tests (Continue on Error) - # continueOnError: true - # condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), eq(variables['EXTENSION_UNIT_TESTS_FAIL_ON_ERROR'], 'false'))) + - script: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the unit tests + # to run with these builds instead of running out of sources. + set -e + APP_ROOT=$(agent.builddirectory)/azuredatastudio-linux-x64 + APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + NO_CLEANUP=1 \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-linux-x64" \ + DISPLAY=:10 ./scripts/test-extensions-unit.sh --build --tfs "Extension Unit Tests" + displayName: Run Extension Unit Tests (Continue on Error) + continueOnError: true + condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), eq(variables['EXTENSION_UNIT_TESTS_FAIL_ON_ERROR'], 'false'))) - # - script: | - # # Figure out the full absolute path of the product we just built - # # including the remote server and configure the unit tests - # # to run with these builds instead of running out of sources. - # set -e - # APP_ROOT=$(agent.builddirectory)/azuredatastudio-linux-x64 - # APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") - # INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ - # NO_CLEANUP=1 \ - # VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-linux-x64" \ - # DISPLAY=:10 ./scripts/test-extensions-unit.sh --build --tfs "Extension Unit Tests" - # displayName: Run Extension Unit Tests (Fail on Error) - # condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['EXTENSION_UNIT_TESTS_FAIL_ON_ERROR'], 'false'))) + - script: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the unit tests + # to run with these builds instead of running out of sources. + set -e + APP_ROOT=$(agent.builddirectory)/azuredatastudio-linux-x64 + APP_NAME=$(node -p "require(\"$APP_ROOT/resources/app/product.json\").applicationName") + INTEGRATION_TEST_ELECTRON_PATH="$APP_ROOT/$APP_NAME" \ + NO_CLEANUP=1 \ + VSCODE_REMOTE_SERVER_PATH="$(agent.builddirectory)/azuredatastudio-reh-linux-x64" \ + DISPLAY=:10 ./scripts/test-extensions-unit.sh --build --tfs "Extension Unit Tests" + displayName: Run Extension Unit Tests (Fail on Error) + condition: and(succeeded(), and(eq(variables['RUN_TESTS'], 'true'), ne(variables['EXTENSION_UNIT_TESTS_FAIL_ON_ERROR'], 'false'))) - # - bash: | - # set -e - # mkdir -p $(Build.ArtifactStagingDirectory)/logs/linux-x64 - # cd /tmp - # for folder in adsuser*/ - # do - # folder=${folder%/} - # # Only archive directories we want for debugging purposes - # tar -czvf $(Build.ArtifactStagingDirectory)/logs/linux-x64/$folder.tar.gz $folder/User $folder/logs - # done - # displayName: Archive Logs - # continueOnError: true - # condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true')) + - bash: | + set -e + mkdir -p $(Build.ArtifactStagingDirectory)/logs/linux-x64 + cd /tmp + for folder in adsuser*/ + do + folder=${folder%/} + # Only archive directories we want for debugging purposes + tar -czvf $(Build.ArtifactStagingDirectory)/logs/linux-x64/$folder.tar.gz $folder/User $folder/logs + done + displayName: Archive Logs + continueOnError: true + condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true')) - # {{SQL CARBON TODO}} - Reenable - # - script: | - # set -e - # yarn gulp vscode-linux-x64-build-deb - # displayName: Build Deb - # condition: and(succeeded(), ne(variables['EXTENSIONS_ONLY'], 'true')) + - script: | + set -e + yarn gulp vscode-linux-x64-build-deb + displayName: Build Deb + condition: and(succeeded(), ne(variables['EXTENSIONS_ONLY'], 'true')) - script: | set -e diff --git a/build/azure-pipelines/mixin.js b/build/azure-pipelines/mixin.js index 8e676d9983..0a17e8008b 100644 --- a/build/azure-pipelines/mixin.js +++ b/build/azure-pipelines/mixin.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const json = require("gulp-json-editor"); const buffer = require('gulp-buffer'); diff --git a/build/azure-pipelines/mixin.ts b/build/azure-pipelines/mixin.ts index 8658d98125..bc174b7308 100644 --- a/build/azure-pipelines/mixin.ts +++ b/build/azure-pipelines/mixin.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as json from 'gulp-json-editor'; const buffer = require('gulp-buffer'); import * as filter from 'gulp-filter'; diff --git a/build/azure-pipelines/product-build-pr-cache.yml b/build/azure-pipelines/product-build-pr-cache.yml deleted file mode 100644 index 067afa7492..0000000000 --- a/build/azure-pipelines/product-build-pr-cache.yml +++ /dev/null @@ -1,59 +0,0 @@ -steps: - - checkout: self - fetchDepth: 1 - retryCountOnTaskFailure: 3 - - - task: NodeTool@0 - inputs: - versionSpec: "16.x" - - - script: | - mkdir -p .build - node build/azure-pipelines/common/computeNodeModulesCacheKey.js $VSCODE_ARCH $ENABLE_TERRAPIN > .build/yarnlockhash - displayName: Prepare yarn cache flags - - - task: Cache@2 - inputs: - key: "genericNodeModules | $(Agent.OS) | .build/yarnlockhash" - path: .build/node_modules_cache - cacheHitVar: NODE_MODULES_RESTORED - displayName: Restore node_modules cache - - - script: | - set -e - tar -xzf .build/node_modules_cache/cache.tgz - condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true')) - displayName: Extract node_modules cache - - - script: | - set -e - npx https://aka.ms/enablesecurefeed standAlone - timeoutInMinutes: 5 - retryCountOnTaskFailure: 3 - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), eq(variables['ENABLE_TERRAPIN'], 'true')) - displayName: Switch to Terrapin packages - - - script: | - set -e - for i in {1..3}; do # try 3 times, for Terrapin - yarn --frozen-lockfile --check-files && break - if [ $i -eq 3 ]; then - echo "Yarn failed too many times" >&2 - exit 1 - fi - echo "Yarn failed $i, trying again..." - done - env: - ELECTRON_SKIP_BINARY_DOWNLOAD: 1 - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - GITHUB_TOKEN: "$(github-distro-mixin-password)" - displayName: Install dependencies - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - - - script: | - set -e - node build/azure-pipelines/common/listNodeModules.js .build/node_modules_list.txt - mkdir -p .build/node_modules_cache - tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt - condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) - displayName: Create node_modules archive diff --git a/build/azure-pipelines/product-build-pr.yml b/build/azure-pipelines/product-build-pr.yml deleted file mode 100644 index 8362da25ee..0000000000 --- a/build/azure-pipelines/product-build-pr.yml +++ /dev/null @@ -1,189 +0,0 @@ -trigger: - - main - - release/* - -pr: - branches: - include: ["main", "release/*"] - -variables: - - name: Codeql.SkipTaskAutoInjection - value: true - - name: skipComponentGovernanceDetection - value: true - - name: ENABLE_TERRAPIN - value: false - - name: VSCODE_CIBUILD - value: ${{ in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }} - - name: VSCODE_PUBLISH - value: false - - name: VSCODE_QUALITY - value: oss - - name: VSCODE_STEP_ON_IT - value: false - -jobs: - - ${{ if ne(variables['VSCODE_CIBUILD'], true) }}: - - job: Compile - displayName: Compile & Hygiene - pool: vscode-1es-vscode-linux-20.04 - timeoutInMinutes: 30 - variables: - VSCODE_ARCH: x64 - steps: - - template: product-compile.yml - parameters: - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - - - job: Linuxx64UnitTest - displayName: Linux (Unit Tests) - pool: vscode-1es-vscode-linux-20.04 - timeoutInMinutes: 30 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: true - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - - job: Linuxx64IntegrationTest - displayName: Linux (Integration Tests) - pool: vscode-1es-vscode-linux-20.04 - timeoutInMinutes: 30 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: true - VSCODE_RUN_SMOKE_TESTS: false - - - job: Linuxx64SmokeTest - displayName: Linux (Smoke Tests) - pool: vscode-1es-vscode-linux-20.04 - timeoutInMinutes: 30 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: true - - - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - - job: Linuxx64MaintainNodeModulesCache - displayName: Linux (Maintain node_modules cache) - pool: vscode-1es-vscode-linux-20.04 - timeoutInMinutes: 30 - variables: - VSCODE_ARCH: x64 - steps: - - template: product-build-pr-cache.yml - - # - job: macOSUnitTest - # displayName: macOS (Unit Tests) - # pool: - # vmImage: macOS-latest - # timeoutInMinutes: 60 - # variables: - # BUILDSECMON_OPT_IN: true - # VSCODE_ARCH: x64 - # steps: - # - template: darwin/product-build-darwin.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: true - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: false - # - job: macOSIntegrationTest - # displayName: macOS (Integration Tests) - # pool: - # vmImage: macOS-latest - # timeoutInMinutes: 60 - # variables: - # BUILDSECMON_OPT_IN: true - # VSCODE_ARCH: x64 - # steps: - # - template: darwin/product-build-darwin.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: true - # VSCODE_RUN_SMOKE_TESTS: false - # - job: macOSSmokeTest - # displayName: macOS (Smoke Tests) - # pool: - # vmImage: macOS-latest - # timeoutInMinutes: 60 - # variables: - # BUILDSECMON_OPT_IN: true - # VSCODE_ARCH: x64 - # steps: - # - template: darwin/product-build-darwin.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: true - - # - job: WindowsUnitTests - # displayName: Windows (Unit Tests) - # pool: vscode-1es-vscode-windows-2019 - # timeoutInMinutes: 60 - # variables: - # VSCODE_ARCH: x64 - # steps: - # - template: win32/product-build-win32.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: true - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: false - # - job: WindowsIntegrationTests - # displayName: Windows (Integration Tests) - # pool: vscode-1es-vscode-windows-2019 - # timeoutInMinutes: 60 - # variables: - # VSCODE_ARCH: x64 - # steps: - # - template: win32/product-build-win32.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: true - # VSCODE_RUN_SMOKE_TESTS: false - # - job: WindowsSmokeTests - # displayName: Windows (Smoke Tests) - # pool: vscode-1es-vscode-windows-2019 - # timeoutInMinutes: 60 - # variables: - # VSCODE_ARCH: x64 - # steps: - # - template: win32/product-build-win32.yml - # parameters: - # VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - # VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - # VSCODE_RUN_UNIT_TESTS: false - # VSCODE_RUN_INTEGRATION_TESTS: false - # VSCODE_RUN_SMOKE_TESTS: true diff --git a/build/azure-pipelines/product-build.yml b/build/azure-pipelines/product-build.yml index 958203ec56..f642d0a680 100644 --- a/build/azure-pipelines/product-build.yml +++ b/build/azure-pipelines/product-build.yml @@ -8,10 +8,6 @@ schedules: - main - joao/web -trigger: - branches: - include: ["main", "release/*"] - parameters: - name: VSCODE_DISTRO_REF displayName: Distro Ref (Private build) @@ -108,11 +104,9 @@ variables: - name: VSCODE_BUILD_STAGE_WINDOWS value: ${{ or(eq(parameters.VSCODE_BUILD_WIN32, true), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }} - name: VSCODE_BUILD_STAGE_LINUX - value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true)) }} + value: ${{ or(eq(parameters.VSCODE_BUILD_LINUX, true), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE, true), eq(parameters.VSCODE_BUILD_LINUX_ALPINE_ARM64, true), eq(parameters.VSCODE_BUILD_WEB, true)) }} - name: VSCODE_BUILD_STAGE_MACOS value: ${{ or(eq(parameters.VSCODE_BUILD_MACOS, true), eq(parameters.VSCODE_BUILD_MACOS_ARM64, true)) }} - - name: VSCODE_BUILD_STAGE_WEB - value: ${{ eq(parameters.VSCODE_BUILD_WEB, true) }} - name: VSCODE_CIBUILD value: ${{ in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI') }} - name: VSCODE_PUBLISH @@ -168,8 +162,6 @@ stages: VSCODE_ARCH: x64 steps: - template: product-compile.yml - parameters: - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WINDOWS'], true)) }}: - stage: Windows @@ -177,60 +169,13 @@ stages: - Compile pool: vscode-1es-windows jobs: - - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - - job: WindowsUnitTests - displayName: Unit Tests - timeoutInMinutes: 60 - variables: - VSCODE_ARCH: x64 - steps: - - template: win32/product-build-win32.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: true - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - job: WindowsIntegrationTests - displayName: Integration Tests - timeoutInMinutes: 60 - variables: - VSCODE_ARCH: x64 - steps: - - template: win32/product-build-win32.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: true - VSCODE_RUN_SMOKE_TESTS: false - - job: WindowsSmokeTests - displayName: Smoke Tests - timeoutInMinutes: 60 - variables: - VSCODE_ARCH: x64 - steps: - - template: win32/product-build-win32.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: true - - - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32, true)) }}: + - ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}: - job: Windows timeoutInMinutes: 120 variables: VSCODE_ARCH: x64 steps: - template: win32/product-build-win32.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_32BIT, true)) }}: - job: Windows32 @@ -239,12 +184,6 @@ stages: VSCODE_ARCH: ia32 steps: - template: win32/product-build-win32.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WIN32_ARM64, true)) }}: - job: WindowsARM64 @@ -253,12 +192,6 @@ stages: VSCODE_ARCH: arm64 steps: - template: win32/product-build-win32.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX'], true)) }}: - stage: LinuxServerDependencies @@ -273,17 +206,13 @@ stages: NPM_ARCH: x64 steps: - template: linux/product-build-linux-server.yml - parameters: - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}: + - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - job: arm64 variables: VSCODE_ARCH: arm64 steps: - template: linux/product-build-linux-server.yml - parameters: - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX'], true)) }}: - stage: Linux @@ -292,54 +221,7 @@ stages: - LinuxServerDependencies pool: vscode-1es-linux jobs: - - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - - job: Linuxx64UnitTest - displayName: Unit Tests - container: vscode-bionic-x64 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: true - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - job: Linuxx64IntegrationTest - displayName: Integration Tests - container: vscode-bionic-x64 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: true - VSCODE_RUN_SMOKE_TESTS: false - - job: Linuxx64SmokeTest - displayName: Smoke Tests - container: vscode-bionic-x64 - variables: - VSCODE_ARCH: x64 - NPM_ARCH: x64 - DISPLAY: ":10" - steps: - - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: true - - - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true)) }}: + - ${{ if eq(parameters.VSCODE_BUILD_LINUX, true) }}: - job: Linuxx64 container: vscode-bionic-x64 variables: @@ -348,12 +230,6 @@ stages: DISPLAY: ":10" steps: - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX, true), ne(variables['VSCODE_PUBLISH'], 'false')) }}: - job: LinuxSnap @@ -373,12 +249,6 @@ stages: NPM_ARCH: armv7l steps: - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false # TODO@joaomoreno: We don't ship ARM snaps for now - ${{ if and(false, eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARMHF, true)) }}: @@ -399,12 +269,6 @@ stages: NPM_ARCH: arm64 steps: - template: linux/product-build-linux-client.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false # TODO@joaomoreno: We don't ship ARM snaps for now - ${{ if and(false, eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_LINUX_ARM64, true)) }}: @@ -432,6 +296,13 @@ stages: steps: - template: linux/product-build-alpine.yml + - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_WEB, true)) }}: + - job: LinuxWeb + variables: + VSCODE_ARCH: x64 + steps: + - template: web/product-build-web.yml + - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_MACOS'], true)) }}: - stage: macOS dependsOn: @@ -441,76 +312,20 @@ stages: variables: BUILDSECMON_OPT_IN: true jobs: - - ${{ if eq(variables['VSCODE_CIBUILD'], true) }}: - - job: macOSUnitTest - displayName: Unit Tests + - ${{ if eq(parameters.VSCODE_BUILD_MACOS, true) }}: + - job: macOSTest timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - - template: darwin/product-build-darwin.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: true - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - job: macOSIntegrationTest - displayName: Integration Tests - timeoutInMinutes: 90 - variables: - VSCODE_ARCH: x64 - steps: - - template: darwin/product-build-darwin.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: true - VSCODE_RUN_SMOKE_TESTS: false - - job: macOSSmokeTest - displayName: Smoke Tests - timeoutInMinutes: 90 - variables: - VSCODE_ARCH: x64 - steps: - - template: darwin/product-build-darwin.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: true - - - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_BUILD_MACOS, true)) }}: - - job: macOS - timeoutInMinutes: 90 - variables: - VSCODE_ARCH: x64 - steps: - - template: darwin/product-build-darwin.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - - ${{ if eq(parameters.VSCODE_STEP_ON_IT, false) }}: - - job: macOSTest + - template: darwin/product-build-darwin-test.yml + - ${{ if eq(variables['VSCODE_CIBUILD'], false) }}: + - job: macOS timeoutInMinutes: 90 variables: VSCODE_ARCH: x64 steps: - template: darwin/product-build-darwin.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - VSCODE_RUN_SMOKE_TESTS: ${{ eq(parameters.VSCODE_STEP_ON_IT, false) }} - - - ${{ if eq(variables['VSCODE_PUBLISH'], true) }}: - job: macOSSign dependsOn: - macOS @@ -527,14 +342,7 @@ stages: VSCODE_ARCH: arm64 steps: - template: darwin/product-build-darwin.yml - parameters: - VSCODE_PUBLISH: ${{ variables.VSCODE_PUBLISH }} - VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: false - VSCODE_RUN_INTEGRATION_TESTS: false - VSCODE_RUN_SMOKE_TESTS: false - - - ${{ if eq(variables['VSCODE_PUBLISH'], true) }}: + - ${{ if eq(variables['VSCODE_CIBUILD'], false) }}: - job: macOSARM64Sign dependsOn: - macOSARM64 @@ -554,8 +362,7 @@ stages: VSCODE_ARCH: universal steps: - template: darwin/product-build-darwin-universal.yml - - - ${{ if eq(variables['VSCODE_PUBLISH'], true) }}: + - ${{ if eq(variables['VSCODE_CIBUILD'], false) }}: - job: macOSUniversalSign dependsOn: - macOSUniversal @@ -565,19 +372,6 @@ stages: steps: - template: darwin/product-build-darwin-sign.yml - - ${{ if and(eq(variables['VSCODE_CIBUILD'], false), eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WEB'], true)) }}: - - stage: Web - dependsOn: - - Compile - pool: vscode-1es-linux - jobs: - - ${{ if eq(parameters.VSCODE_BUILD_WEB, true) }}: - - job: Web - variables: - VSCODE_ARCH: x64 - steps: - - template: web/product-build-web.yml - - ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), ne(variables['VSCODE_PUBLISH'], 'false')) }}: - stage: Publish dependsOn: diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index 381d49ee75..2b109f3cc5 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -1,47 +1,39 @@ -parameters: - - name: VSCODE_QUALITY - type: string - steps: - task: NodeTool@0 inputs: versionSpec: "16.x" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: AzureKeyVault@1 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: "vscode-builds-subscription" - KeyVaultName: vscode - SecretsFilter: "github-distro-mixin-password" + - task: AzureKeyVault@1 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "vscode-builds-subscription" + KeyVaultName: vscode + SecretsFilter: "github-distro-mixin-password" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - cat << EOF > ~/.netrc - machine github.com - login vscode - password $(github-distro-mixin-password) - EOF + - script: | + set -e + cat << EOF > ~/.netrc + machine github.com + login vscode + password $(github-distro-mixin-password) + EOF - git config user.email "vscode@microsoft.com" - git config user.name "VSCode" - displayName: Prepare tooling + git config user.email "vscode@microsoft.com" + git config user.name "VSCode" + displayName: Prepare tooling - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF - echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" - git checkout FETCH_HEAD - condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) - displayName: Checkout override commit + - script: | + set -e + git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $VSCODE_DISTRO_REF + echo "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" + git checkout FETCH_HEAD + condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) + displayName: Checkout override commit - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") - displayName: Merge distro + - script: | + set -e + git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") + displayName: Merge distro - script: | mkdir -p .build @@ -102,12 +94,11 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - # Mixin must run before optimize, because the CSS loader will inline small SVGs - - script: | - set -e - node build/azure-pipelines/mixin - displayName: Mix in quality + # Mixin must run before optimize, because the CSS loader will inline small SVGs + - script: | + set -e + node build/azure-pipelines/mixin + displayName: Mix in quality - script: | set -e @@ -116,65 +107,59 @@ steps: GITHUB_TOKEN: "$(github-distro-mixin-password)" displayName: Compile & Hygiene - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - yarn --cwd test/smoke compile - yarn --cwd test/integration/browser compile - displayName: Compile test suites - condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) + - script: | + set -e + yarn --cwd test/smoke compile + yarn --cwd test/integration/browser compile + displayName: Compile test suites + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: AzureCLI@2 - inputs: - azureSubscription: "vscode-builds-subscription" - scriptType: pscore - scriptLocation: inlineScript - addSpnToEnvironment: true - inlineScript: | - Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" - Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" - Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey" + - task: AzureCLI@2 + inputs: + azureSubscription: "vscode-builds-subscription" + scriptType: pscore + scriptLocation: inlineScript + addSpnToEnvironment: true + inlineScript: | + Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId" + Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId" + Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;issecret=true]$env:servicePrincipalKey" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - AZURE_STORAGE_ACCOUNT="ticino" \ - AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ - AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ - AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ - node build/azure-pipelines/upload-sourcemaps - displayName: Upload sourcemaps + - script: | + set -e + AZURE_STORAGE_ACCOUNT="ticino" \ + AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \ + AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \ + AZURE_CLIENT_SECRET="$(AZURE_CLIENT_SECRET)" \ + node build/azure-pipelines/upload-sourcemaps + displayName: Upload sourcemaps + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set - - ./build/azure-pipelines/common/extract-telemetry.sh - displayName: Extract Telemetry + - script: | + set - + ./build/azure-pipelines/common/extract-telemetry.sh + displayName: Extract Telemetry + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - tar -cz --ignore-failed-read -f $(Build.ArtifactStagingDirectory)/compilation.tar.gz .build out-* test/integration/browser/out test/smoke/out test/automation/out - displayName: Compress compilation artifact + - script: | + set -e + tar -cz --ignore-failed-read -f $(Build.ArtifactStagingDirectory)/compilation.tar.gz .build out-* test/integration/browser/out test/smoke/out test/automation/out + displayName: Compress compilation artifact - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: PublishPipelineArtifact@1 - inputs: - targetPath: $(Build.ArtifactStagingDirectory)/compilation.tar.gz - artifactName: Compilation - displayName: Publish compilation artifact + - task: PublishPipelineArtifact@1 + inputs: + targetPath: $(Build.ArtifactStagingDirectory)/compilation.tar.gz + artifactName: Compilation + displayName: Publish compilation artifact - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - script: | - set -e - VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ - yarn download-builtin-extensions-cg - displayName: Built-in extensions component details + - script: | + set -e + VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" \ + yarn download-builtin-extensions-cg + displayName: Built-in extensions component details - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 - displayName: "Component Detection" - inputs: - sourceScanPath: $(Build.SourcesDirectory) - continueOnError: true + - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0 + displayName: "Component Detection" + inputs: + sourceScanPath: $(Build.SourcesDirectory) + continueOnError: true diff --git a/build/azure-pipelines/product-publish.ps1 b/build/azure-pipelines/product-publish.ps1 index 5006ec61a3..5abfed48dc 100644 --- a/build/azure-pipelines/product-publish.ps1 +++ b/build/azure-pipelines/product-publish.ps1 @@ -46,7 +46,6 @@ $stages = @( if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' } if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' } if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' } - if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' } ) do { diff --git a/build/azure-pipelines/product-publish.yml b/build/azure-pipelines/product-publish.yml index 80076fd666..4d711aba12 100644 --- a/build/azure-pipelines/product-publish.yml +++ b/build/azure-pipelines/product-publish.yml @@ -109,7 +109,6 @@ steps: if ($env:VSCODE_BUILD_STAGE_WINDOWS -eq 'True') { 'Windows' } if ($env:VSCODE_BUILD_STAGE_LINUX -eq 'True') { 'Linux' } if ($env:VSCODE_BUILD_STAGE_MACOS -eq 'True') { 'macOS' } - if ($env:VSCODE_BUILD_STAGE_WEB -eq 'True') { 'Web' } ) Write-Host "Stages to check: $stages" diff --git a/build/azure-pipelines/publish-types/check-version.js b/build/azure-pipelines/publish-types/check-version.js index f787f897ae..95563bf95e 100644 --- a/build/azure-pipelines/publish-types/check-version.js +++ b/build/azure-pipelines/publish-types/check-version.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const cp = require("child_process"); let tag = ''; diff --git a/build/azure-pipelines/publish-types/check-version.ts b/build/azure-pipelines/publish-types/check-version.ts index 72bf428f47..3e3614a867 100644 --- a/build/azure-pipelines/publish-types/check-version.ts +++ b/build/azure-pipelines/publish-types/check-version.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as cp from 'child_process'; let tag = ''; diff --git a/build/azure-pipelines/publish-types/update-types.js b/build/azure-pipelines/publish-types/update-types.js index 6da5a12a86..2da8ae32e9 100644 --- a/build/azure-pipelines/publish-types/update-types.js +++ b/build/azure-pipelines/publish-types/update-types.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const fs = require("fs"); const cp = require("child_process"); diff --git a/build/azure-pipelines/publish-types/update-types.ts b/build/azure-pipelines/publish-types/update-types.ts index 93b19a5b4a..c3ed3324a7 100644 --- a/build/azure-pipelines/publish-types/update-types.ts +++ b/build/azure-pipelines/publish-types/update-types.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fs from 'fs'; import * as cp from 'child_process'; import * as path from 'path'; diff --git a/build/azure-pipelines/upload-cdn.js b/build/azure-pipelines/upload-cdn.js index 5bf24c505a..6f0f9c7194 100644 --- a/build/azure-pipelines/upload-cdn.js +++ b/build/azure-pipelines/upload-cdn.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const es = require("event-stream"); const Vinyl = require("vinyl"); diff --git a/build/azure-pipelines/upload-cdn.ts b/build/azure-pipelines/upload-cdn.ts index d28f20ac52..1229a06ba6 100644 --- a/build/azure-pipelines/upload-cdn.ts +++ b/build/azure-pipelines/upload-cdn.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as es from 'event-stream'; import * as Vinyl from 'vinyl'; import * as vfs from 'vinyl-fs'; diff --git a/build/azure-pipelines/upload-configuration.js b/build/azure-pipelines/upload-configuration.js index a8739f80cd..bc641b7d49 100644 --- a/build/azure-pipelines/upload-configuration.js +++ b/build/azure-pipelines/upload-configuration.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getSettingsSearchBuildId = exports.shouldSetupSettingsSearch = void 0; const path = require("path"); @@ -52,7 +52,7 @@ function generateVSCodeConfigurationTask() { const timer = setTimeout(() => { codeProc.kill(); reject(new Error('export-default-configuration process timed out')); - }, 60 * 1000); + }, 12 * 1000); codeProc.on('error', err => { clearTimeout(timer); reject(err); diff --git a/build/azure-pipelines/upload-configuration.ts b/build/azure-pipelines/upload-configuration.ts index dbcc1b99b7..3cb5622c66 100644 --- a/build/azure-pipelines/upload-configuration.ts +++ b/build/azure-pipelines/upload-configuration.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as path from 'path'; import * as os from 'os'; import * as cp from 'child_process'; @@ -61,7 +63,7 @@ function generateVSCodeConfigurationTask(): Promise { const timer = setTimeout(() => { codeProc.kill(); reject(new Error('export-default-configuration process timed out')); - }, 60 * 1000); + }, 12 * 1000); codeProc.on('error', err => { clearTimeout(timer); diff --git a/build/azure-pipelines/upload-nlsmetadata.js b/build/azure-pipelines/upload-nlsmetadata.js index df30c0d159..7eddb74807 100644 --- a/build/azure-pipelines/upload-nlsmetadata.js +++ b/build/azure-pipelines/upload-nlsmetadata.js @@ -1,16 +1,14 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const es = require("event-stream"); const vfs = require("vinyl-fs"); const merge = require("gulp-merge-json"); const gzip = require("gulp-gzip"); const identity_1 = require("@azure/identity"); -const path = require("path"); -const fs_1 = require("fs"); const azure = require('gulp-azure-storage'); const commit = process.env['VSCODE_DISTRO_COMMIT'] || process.env['BUILD_SOURCEVERSION']; const credential = new identity_1.ClientSecretCredential(process.env['AZURE_TENANT_ID'], process.env['AZURE_CLIENT_ID'], process.env['AZURE_CLIENT_SECRET']); @@ -20,8 +18,8 @@ function main() { .pipe(merge({ fileName: 'combined.nls.metadata.json', jsonSpace: '', - concatArrays: true, edit: (parsedJson, file) => { + let key; if (file.base === 'out-vscode-web-min') { return { vscode: parsedJson }; } @@ -65,11 +63,7 @@ function main() { break; } } - // Get extension id and use that as the key - const folderPath = path.join(file.base, file.relative.split('/')[0]); - const manifest = (0, fs_1.readFileSync)(path.join(folderPath, 'package.json'), 'utf-8'); - const manifestJson = JSON.parse(manifest); - const key = manifestJson.publisher + '.' + manifestJson.name; + key = 'vscode.' + file.relative.split('/')[0]; return { [key]: parsedJson }; }, })) diff --git a/build/azure-pipelines/upload-nlsmetadata.ts b/build/azure-pipelines/upload-nlsmetadata.ts index e2a95c782b..dbb1bf7651 100644 --- a/build/azure-pipelines/upload-nlsmetadata.ts +++ b/build/azure-pipelines/upload-nlsmetadata.ts @@ -3,14 +3,14 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as es from 'event-stream'; import * as Vinyl from 'vinyl'; import * as vfs from 'vinyl-fs'; import * as merge from 'gulp-merge-json'; import * as gzip from 'gulp-gzip'; import { ClientSecretCredential } from '@azure/identity'; -import path = require('path'); -import { readFileSync } from 'fs'; const azure = require('gulp-azure-storage'); const commit = process.env['VSCODE_DISTRO_COMMIT'] || process.env['BUILD_SOURCEVERSION']; @@ -33,8 +33,8 @@ function main(): Promise { .pipe(merge({ fileName: 'combined.nls.metadata.json', jsonSpace: '', - concatArrays: true, edit: (parsedJson, file) => { + let key; if (file.base === 'out-vscode-web-min') { return { vscode: parsedJson }; } @@ -82,12 +82,7 @@ function main(): Promise { break; } } - - // Get extension id and use that as the key - const folderPath = path.join(file.base, file.relative.split('/')[0]); - const manifest = readFileSync(path.join(folderPath, 'package.json'), 'utf-8'); - const manifestJson = JSON.parse(manifest); - const key = manifestJson.publisher + '.' + manifestJson.name; + key = 'vscode.' + file.relative.split('/')[0]; return { [key]: parsedJson }; }, })) @@ -118,3 +113,4 @@ main().catch(err => { console.error(err); process.exit(1); }); + diff --git a/build/azure-pipelines/upload-sourcemaps.js b/build/azure-pipelines/upload-sourcemaps.js index 7392cd2efe..034fb8e753 100644 --- a/build/azure-pipelines/upload-sourcemaps.js +++ b/build/azure-pipelines/upload-sourcemaps.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const es = require("event-stream"); diff --git a/build/azure-pipelines/upload-sourcemaps.ts b/build/azure-pipelines/upload-sourcemaps.ts index b679938e8b..bf3066ab83 100644 --- a/build/azure-pipelines/upload-sourcemaps.ts +++ b/build/azure-pipelines/upload-sourcemaps.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as path from 'path'; import * as es from 'event-stream'; import * as Vinyl from 'vinyl'; diff --git a/build/azure-pipelines/web/product-build-web.yml b/build/azure-pipelines/web/product-build-web.yml index 376f14c6bc..fa07a82305 100644 --- a/build/azure-pipelines/web/product-build-web.yml +++ b/build/azure-pipelines/web/product-build-web.yml @@ -163,7 +163,6 @@ steps: cd $ROOT && tar --owner=0 --group=0 -czf $WEB_TARBALL_PATH $WEB_BUILD_NAME displayName: Prepare for publish - condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - publish: $(Agent.BuildDirectory)/vscode-web.tar.gz artifact: vscode_web_linux_standalone_archive-unsigned diff --git a/build/azure-pipelines/win32/product-build-win32-test.yml b/build/azure-pipelines/win32/product-build-win32-test.yml deleted file mode 100644 index 59c91cd2b1..0000000000 --- a/build/azure-pipelines/win32/product-build-win32-test.yml +++ /dev/null @@ -1,247 +0,0 @@ -parameters: - - name: VSCODE_QUALITY - type: string - - name: VSCODE_RUN_UNIT_TESTS - type: boolean - - name: VSCODE_RUN_INTEGRATION_TESTS - type: boolean - - name: VSCODE_RUN_SMOKE_TESTS - type: boolean - -steps: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" - exec { yarn npm-run-all -lp "electron $(VSCODE_ARCH)" "playwright-install" } - displayName: Download Electron and Playwright - - - ${{ if eq(parameters.VSCODE_RUN_UNIT_TESTS, true) }}: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn electron $(VSCODE_ARCH) } - exec { .\scripts\test.bat --tfs "Unit Tests" } - displayName: Run unit tests (Electron) - timeoutInMinutes: 15 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn test-node } - displayName: Run unit tests (node.js) - timeoutInMinutes: 15 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { node test/unit/browser/index.js --sequential --browser chromium --browser firefox --tfs "Browser Unit Tests" } - displayName: Run unit tests (Browser, Chromium & Firefox) - timeoutInMinutes: 20 - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn electron $(VSCODE_ARCH) } - exec { .\scripts\test.bat --build --tfs "Unit Tests" } - displayName: Run unit tests (Electron) - timeoutInMinutes: 15 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn test-node --build } - displayName: Run unit tests (node.js) - timeoutInMinutes: 15 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn test-browser-no-install --sequential --build --browser chromium --browser firefox --tfs "Browser Unit Tests" } - displayName: Run unit tests (Browser, Chromium & Firefox) - timeoutInMinutes: 20 - - - ${{ if eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn gulp ` - compile-extension:configuration-editing ` - compile-extension:css-language-features-server ` - compile-extension:emmet ` - compile-extension:git ` - compile-extension:github-authentication ` - compile-extension:html-language-features-server ` - compile-extension:ipynb ` - compile-extension:json-language-features-server ` - compile-extension:markdown-language-features-server ` - compile-extension:markdown-language-features ` - compile-extension-media ` - compile-extension:microsoft-authentication ` - compile-extension:typescript-language-features ` - compile-extension:vscode-api-tests ` - compile-extension:vscode-colorize-tests ` - compile-extension:vscode-notebook-tests ` - compile-extension:vscode-test-resolver ` - } - displayName: Build integration tests - - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { .\scripts\test-integration.bat --tfs "Integration Tests" } - displayName: Run integration tests (Electron) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { .\scripts\test-web-integration.bat --browser firefox } - displayName: Run integration tests (Browser, Firefox) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { .\scripts\test-remote-integration.bat } - displayName: Run integration tests (Remote) - timeoutInMinutes: 20 - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - # Figure out the full absolute path of the product we just built - # including the remote server and configure the integration tests - # to run with these builds instead of running out of sources. - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" - $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json - $AppNameShort = $AppProductJson.nameShort - exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-integration.bat --build --tfs "Integration Tests" } - displayName: Run integration tests (Electron) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH)"; .\scripts\test-web-integration.bat --browser firefox } - displayName: Run integration tests (Browser, Firefox) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" - $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json - $AppNameShort = $AppProductJson.nameShort - exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-remote-integration.bat } - displayName: Run integration tests (Remote) - timeoutInMinutes: 20 - - - ${{ if eq(parameters.VSCODE_RUN_SMOKE_TESTS, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - exec {.\build\azure-pipelines\win32\listprocesses.bat } - displayName: Diagnostics before smoke test run - continueOnError: true - condition: succeededOrFailed() - - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn --cwd test/smoke compile } - displayName: Compile smoke tests - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn smoketest-no-compile --tracing } - displayName: Run smoke tests (Electron) - timeoutInMinutes: 20 - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" - exec { yarn smoketest-no-compile --tracing --build "$AppRoot" } - displayName: Run smoke tests (Electron) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH)" - exec { yarn smoketest-no-compile --web --tracing --headless } - displayName: Run smoke tests (Browser, Chromium) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" - $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)" - exec { yarn gulp compile-extension:vscode-test-resolver } - exec { yarn smoketest-no-compile --tracing --remote --build "$AppRoot" } - displayName: Run smoke tests (Remote) - timeoutInMinutes: 20 - - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - exec {.\build\azure-pipelines\win32\listprocesses.bat } - displayName: Diagnostics after smoke test run - continueOnError: true - condition: succeededOrFailed() - - - ${{ if or(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - - task: PublishPipelineArtifact@0 - inputs: - targetPath: .build\crashes - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: crash-dump-windows-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: crash-dump-windows-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: crash-dump-windows-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Crash Reports" - continueOnError: true - condition: failed() - - # In order to properly symbolify above crash reports - # (if any), we need the compiled native modules too - - task: PublishPipelineArtifact@0 - inputs: - targetPath: node_modules - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: node-modules-windows-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: node-modules-windows-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: node-modules-windows-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Node Modules" - continueOnError: true - condition: failed() - - - task: PublishPipelineArtifact@0 - inputs: - targetPath: .build\logs - ${{ if and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, false)) }}: - artifactName: logs-windows-$(VSCODE_ARCH)-integration-$(System.JobAttempt) - ${{ elseif and(eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, false), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - artifactName: logs-windows-$(VSCODE_ARCH)-smoke-$(System.JobAttempt) - ${{ else }}: - artifactName: logs-windows-$(VSCODE_ARCH)-$(System.JobAttempt) - displayName: "Publish Log Files" - continueOnError: true - condition: succeededOrFailed() - - - task: PublishTestResults@2 - displayName: Publish Tests Results - inputs: - testResultsFiles: "*-results.xml" - searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" - condition: succeededOrFailed() diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 41f0a8da8c..99b39ee2b2 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -1,21 +1,4 @@ -parameters: - - name: VSCODE_PUBLISH - type: boolean - - name: VSCODE_QUALITY - type: string - - name: VSCODE_RUN_UNIT_TESTS - type: boolean - - name: VSCODE_RUN_INTEGRATION_TESTS - type: boolean - - name: VSCODE_RUN_SMOKE_TESTS - type: boolean - steps: - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - checkout: self - fetchDepth: 1 - retryCountOnTaskFailure: 3 - - task: NodeTool@0 inputs: versionSpec: "16.x" @@ -25,58 +8,51 @@ steps: versionSpec: "3.x" addToPath: true - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: AzureKeyVault@1 - displayName: "Azure Key Vault: Get Secrets" - inputs: - azureSubscription: "vscode-builds-subscription" - KeyVaultName: vscode - SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" + - task: AzureKeyVault@1 + displayName: "Azure Key Vault: Get Secrets" + inputs: + azureSubscription: "vscode-builds-subscription" + KeyVaultName: vscode + SecretsFilter: "github-distro-mixin-password,ESRP-PKI,esrp-aad-username,esrp-aad-password" - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: DownloadPipelineArtifact@2 - inputs: - artifact: Compilation - path: $(Build.ArtifactStagingDirectory) - displayName: Download compilation output + - task: DownloadPipelineArtifact@2 + inputs: + artifact: Compilation + path: $(Build.ArtifactStagingDirectory) + displayName: Download compilation output - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - task: ExtractFiles@1 - displayName: Extract compilation output - inputs: - archiveFilePatterns: "$(Build.ArtifactStagingDirectory)/compilation.tar.gz" - cleanDestinationFolder: false - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII - - exec { git config user.email "vscode@microsoft.com" } - exec { git config user.name "VSCode" } - displayName: Prepare tooling - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - - exec { git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $(VSCODE_DISTRO_REF) } - Write-Host "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" - exec { git checkout FETCH_HEAD } - condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) - displayName: Checkout override commit - - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") } - displayName: Merge distro + - task: ExtractFiles@1 + displayName: Extract compilation output + inputs: + archiveFilePatterns: "$(Build.ArtifactStagingDirectory)/compilation.tar.gz" + cleanDestinationFolder: false + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + "machine github.com`nlogin vscode`npassword $(github-distro-mixin-password)" | Out-File "$env:USERPROFILE\_netrc" -Encoding ASCII + + exec { git config user.email "vscode@microsoft.com" } + exec { git config user.name "VSCode" } + displayName: Prepare tooling + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + + exec { git fetch https://github.com/$(VSCODE_MIXIN_REPO).git $(VSCODE_DISTRO_REF) } + Write-Host "##vso[task.setvariable variable=VSCODE_DISTRO_COMMIT;]$(git rev-parse FETCH_HEAD)" + exec { git checkout FETCH_HEAD } + condition: and(succeeded(), ne(variables.VSCODE_DISTRO_REF, ' ')) + displayName: Checkout override commit + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { git pull --no-rebase https://github.com/$(VSCODE_MIXIN_REPO).git $(node -p "require('./package.json').distro") } + displayName: Merge distro - powershell: | - if (!(Test-Path ".build")) { New-Item -Path ".build" -ItemType Directory } "$(VSCODE_ARCH)" | Out-File -Encoding ascii -NoNewLine .build\arch "$env:ENABLE_TERRAPIN" | Out-File -Encoding ascii -NoNewLine .build\terrapin node build/azure-pipelines/common/computeNodeModulesCacheKey.js > .build/yarnlockhash @@ -128,176 +104,291 @@ steps: condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true')) displayName: Create node_modules archive - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { node build/azure-pipelines/mixin } - displayName: Mix in quality + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { node build/azure-pipelines/mixin } + displayName: Mix in quality - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { node build\lib\policies } - displayName: Generate Group Policy definitions + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" + exec { yarn npm-run-all -lp "electron $(VSCODE_ARCH)" } + displayName: Download Electron + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" - exec { yarn gulp "transpile-client" "transpile-extensions" } - displayName: Transpile + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-min-ci" } + echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)" + displayName: Build - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" - exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-min-ci" } - echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)" - displayName: Build + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" } + displayName: Prepare Package + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" - exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-inno-updater" } - displayName: Prepare Package + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { node build/azure-pipelines/mixin --server } + displayName: Mix in quality - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { node build/azure-pipelines/mixin --server } - displayName: Mix in quality - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" + exec { yarn gulp "vscode-reh-win32-$(VSCODE_ARCH)-min-ci" } + exec { yarn gulp "vscode-reh-web-win32-$(VSCODE_ARCH)-min-ci" } + echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(agent.builddirectory)/vscode-reh-win32-$(VSCODE_ARCH)" + displayName: Build Server + condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" - exec { yarn gulp "vscode-reh-win32-$(VSCODE_ARCH)-min-ci" } - exec { yarn gulp "vscode-reh-web-win32-$(VSCODE_ARCH)-min-ci" } - echo "##vso[task.setvariable variable=CodeSigningFolderPath]$(CodeSigningFolderPath),$(agent.builddirectory)/vscode-reh-win32-$(VSCODE_ARCH)" - displayName: Build Server - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:VSCODE_MIXIN_PASSWORD="$(github-distro-mixin-password)" + exec { yarn npm-run-all -lp "playwright-install" } + displayName: Download Playwright + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if or(eq(parameters.VSCODE_RUN_UNIT_TESTS, true), eq(parameters.VSCODE_RUN_INTEGRATION_TESTS, true), eq(parameters.VSCODE_RUN_SMOKE_TESTS, true)) }}: - - template: product-build-win32-test.yml - parameters: - VSCODE_QUALITY: ${{ parameters.VSCODE_QUALITY }} - VSCODE_RUN_UNIT_TESTS: ${{ parameters.VSCODE_RUN_UNIT_TESTS }} - VSCODE_RUN_INTEGRATION_TESTS: ${{ parameters.VSCODE_RUN_INTEGRATION_TESTS }} - VSCODE_RUN_SMOKE_TESTS: ${{ parameters.VSCODE_RUN_SMOKE_TESTS }} + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { yarn electron $(VSCODE_ARCH) } + exec { .\scripts\test.bat --build --tfs "Unit Tests" } + displayName: Run unit tests (Electron) + timeoutInMinutes: 15 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: UseDotNet@2 - inputs: - version: 3.x - condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { yarn test-node --build } + displayName: Run unit tests (node.js) + timeoutInMinutes: 15 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: EsrpClientTool@1 - displayName: Download ESRPClient + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { yarn test-browser-no-install --sequential --build --browser chromium --browser firefox --tfs "Browser Unit Tests" } + displayName: Run unit tests (Browser, Chromium & Firefox) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $EsrpClientTool = (gci -directory -filter EsrpClientTool_* $(Agent.RootDirectory)\_tasks | Select-Object -last 1).FullName - $EsrpCliZip = (gci -recurse -filter esrpcli.*.zip $EsrpClientTool | Select-Object -last 1).FullName - mkdir -p $(Agent.TempDirectory)\esrpcli - Expand-Archive -Path $EsrpCliZip -DestinationPath $(Agent.TempDirectory)\esrpcli - $EsrpCliDllPath = (gci -recurse -filter esrpcli.dll $(Agent.TempDirectory)\esrpcli | Select-Object -last 1).FullName - echo "##vso[task.setvariable variable=EsrpCliDllPath]$EsrpCliDllPath" - displayName: Find ESRP CLI + - powershell: | + # Figure out the full absolute path of the product we just built + # including the remote server and configure the integration tests + # to run with these builds instead of running out of sources. + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" + $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json + $AppNameShort = $AppProductJson.nameShort + exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-integration.bat --build --tfs "Integration Tests" } + displayName: Run integration tests (Electron) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { node build\azure-pipelines\common\sign $env:EsrpCliDllPath windows $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(CodeSigningFolderPath) '*.dll,*.exe,*.node' } - displayName: Codesign + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH)"; .\scripts\test-web-integration.bat --browser firefox } + displayName: Run integration tests (Browser, Firefox) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-archive" } - displayName: Package archive + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" + $AppProductJson = Get-Content -Raw -Path "$AppRoot\resources\app\product.json" | ConvertFrom-Json + $AppNameShort = $AppProductJson.nameShort + exec { $env:INTEGRATION_TEST_ELECTRON_PATH = "$AppRoot\$AppNameShort.exe"; $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)"; .\scripts\test-remote-integration.bat } + displayName: Run integration tests (Remote) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - $env:ESRPPKI = "$(ESRP-PKI)" - $env:ESRPAADUsername = "$(esrp-aad-username)" - $env:ESRPAADPassword = "$(esrp-aad-password)" - exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-system-setup" --sign } - exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign } - displayName: Package setups + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + exec {.\build\azure-pipelines\win32\listprocesses.bat } + displayName: Diagnostics before smoke test run + continueOnError: true + condition: and(succeededOrFailed(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - powershell: | - . build/azure-pipelines/win32/exec.ps1 - $ErrorActionPreference = "Stop" - .\build\azure-pipelines\win32\prepare-publish.ps1 - displayName: Publish + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-web-win32-$(VSCODE_ARCH)" + exec { yarn smoketest-no-compile --web --tracing --headless } + displayName: Run smoke tests (Browser, Chromium) + timeoutInMinutes: 10 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: Generate SBOM (client) - inputs: - BuildDropPath: $(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH) - PackageName: Visual Studio Code + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" + exec { yarn smoketest-no-compile --tracing --build "$AppRoot" } + displayName: Run smoke tests (Electron) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/_manifest - displayName: Publish SBOM (client) - artifact: vscode_client_win32_$(VSCODE_ARCH)_sbom + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $AppRoot = "$(agent.builddirectory)\VSCode-win32-$(VSCODE_ARCH)" + $env:VSCODE_REMOTE_SERVER_PATH = "$(agent.builddirectory)\vscode-reh-win32-$(VSCODE_ARCH)" + exec { yarn smoketest-no-compile --tracing --remote --build "$AppRoot" } + displayName: Run smoke tests (Remote) + timeoutInMinutes: 20 + condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 - displayName: Generate SBOM (server) - inputs: - BuildDropPath: $(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH) - PackageName: Visual Studio Code Server - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + exec {.\build\azure-pipelines\win32\listprocesses.bat } + displayName: Diagnostics after smoke test run + continueOnError: true + condition: and(succeededOrFailed(), eq(variables['VSCODE_STEP_ON_IT'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH)/_manifest - displayName: Publish SBOM (server) - artifact: vscode_server_win32_$(VSCODE_ARCH)_sbom - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + - task: PublishPipelineArtifact@0 + inputs: + artifactName: crash-dump-windows-$(VSCODE_ARCH) + targetPath: .build\crashes + displayName: "Publish Crash Reports" + continueOnError: true + condition: failed() - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\archive\$(ARCHIVE_NAME) - artifact: vscode_client_win32_$(VSCODE_ARCH)_archive - displayName: Publish archive + # In order to properly symbolify above crash reports + # (if any), we need the compiled native modules too + - task: PublishPipelineArtifact@0 + inputs: + artifactName: node-modules-windows-$(VSCODE_ARCH) + targetPath: node_modules + displayName: "Publish Node Modules" + continueOnError: true + condition: failed() - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\system-setup\$(SYSTEM_SETUP_NAME) - artifact: vscode_client_win32_$(VSCODE_ARCH)_setup - displayName: Publish system setup + - task: PublishPipelineArtifact@0 + inputs: + artifactName: logs-windows-$(VSCODE_ARCH)-$(System.JobAttempt) + targetPath: .build\logs + displayName: "Publish Log Files" + continueOnError: true + condition: and(failed(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\user-setup\$(USER_SETUP_NAME) - artifact: vscode_client_win32_$(VSCODE_ARCH)_user-setup - displayName: Publish user setup - condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + - task: PublishTestResults@2 + displayName: Publish Tests Results + inputs: + testResultsFiles: "*-results.xml" + searchFolder: "$(Build.ArtifactStagingDirectory)/test-results" + condition: and(succeededOrFailed(), eq(variables['VSCODE_STEP_ON_IT'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(System.DefaultWorkingDirectory)\.build\vscode-server-win32-$(VSCODE_ARCH).zip - artifact: vscode_server_win32_$(VSCODE_ARCH)_archive - displayName: Publish server archive - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + - task: UseDotNet@2 + inputs: + version: 3.x + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) - - ${{ if eq(parameters.VSCODE_PUBLISH, true) }}: - - publish: $(System.DefaultWorkingDirectory)\.build\vscode-server-win32-$(VSCODE_ARCH)-web.zip - artifact: vscode_web_win32_$(VSCODE_ARCH)_archive - displayName: Publish web server archive - condition: and(succeeded(), ne(variables['VSCODE_ARCH'], 'arm64')) + - task: EsrpClientTool@1 + displayName: Download ESRPClient + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $EsrpClientTool = (gci -directory -filter EsrpClientTool_* $(Agent.RootDirectory)\_tasks | Select-Object -last 1).FullName + $EsrpCliZip = (gci -recurse -filter esrpcli.*.zip $EsrpClientTool | Select-Object -last 1).FullName + mkdir -p $(Agent.TempDirectory)\esrpcli + Expand-Archive -Path $EsrpCliZip -DestinationPath $(Agent.TempDirectory)\esrpcli + $EsrpCliDllPath = (gci -recurse -filter esrpcli.dll $(Agent.TempDirectory)\esrpcli | Select-Object -last 1).FullName + echo "##vso[task.setvariable variable=EsrpCliDllPath]$EsrpCliDllPath" + displayName: Find ESRP CLI + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { node build\azure-pipelines\common\sign $env:EsrpCliDllPath windows $(ESRP-PKI) $(esrp-aad-username) $(esrp-aad-password) $(CodeSigningFolderPath) '*.dll,*.exe,*.node' } + displayName: Codesign + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-archive" } + displayName: Package archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + $env:ESRPPKI = "$(ESRP-PKI)" + $env:ESRPAADUsername = "$(esrp-aad-username)" + $env:ESRPAADPassword = "$(esrp-aad-password)" + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-system-setup" --sign } + exec { yarn gulp "vscode-win32-$(VSCODE_ARCH)-user-setup" --sign } + displayName: Package setups + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - powershell: | + . build/azure-pipelines/win32/exec.ps1 + $ErrorActionPreference = "Stop" + .\build\azure-pipelines\win32\prepare-publish.ps1 + displayName: Publish + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\archive\$(ARCHIVE_NAME) + artifact: vscode_client_win32_$(VSCODE_ARCH)_archive + displayName: Publish archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\system-setup\$(SYSTEM_SETUP_NAME) + artifact: vscode_client_win32_$(VSCODE_ARCH)_setup + displayName: Publish system setup + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(System.DefaultWorkingDirectory)\.build\win32-$(VSCODE_ARCH)\user-setup\$(USER_SETUP_NAME) + artifact: vscode_client_win32_$(VSCODE_ARCH)_user-setup + displayName: Publish user setup + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(System.DefaultWorkingDirectory)\.build\vscode-server-win32-$(VSCODE_ARCH).zip + artifact: vscode_server_win32_$(VSCODE_ARCH)_archive + displayName: Publish server archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) + + - publish: $(System.DefaultWorkingDirectory)\.build\vscode-server-win32-$(VSCODE_ARCH)-web.zip + artifact: vscode_web_win32_$(VSCODE_ARCH)_archive + displayName: Publish web server archive + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: Generate SBOM (client) + inputs: + BuildDropPath: $(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH) + PackageName: Visual Studio Code + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - publish: $(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/_manifest + displayName: Publish SBOM (client) + artifact: vscode_client_win32_$(VSCODE_ARCH)_sbom + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false')) + + - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: Generate SBOM (server) + inputs: + BuildDropPath: $(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH) + PackageName: Visual Studio Code Server + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) + + - publish: $(agent.builddirectory)/vscode-server-win32-$(VSCODE_ARCH)/_manifest + displayName: Publish SBOM (server) + artifact: vscode_server_win32_$(VSCODE_ARCH)_sbom + condition: and(succeeded(), ne(variables['VSCODE_PUBLISH'], 'false'), ne(variables['VSCODE_ARCH'], 'arm64')) diff --git a/build/darwin/create-universal-app.js b/build/darwin/create-universal-app.js index 24476a1fbd..a76d9df018 100644 --- a/build/darwin/create-universal-app.js +++ b/build/darwin/create-universal-app.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const vscode_universal_bundler_1 = require("vscode-universal-bundler"); const cross_spawn_promise_1 = require("@malept/cross-spawn-promise"); @@ -71,7 +71,7 @@ async function main() { outAppPath, force: true }); - const productJson = await fs.readJson(productJsonPath); + let productJson = await fs.readJson(productJsonPath); Object.assign(productJson, { darwinUniversalAssetId: 'darwin-universal' }); diff --git a/build/darwin/create-universal-app.ts b/build/darwin/create-universal-app.ts index 56fc1722db..66c935b2c6 100644 --- a/build/darwin/create-universal-app.ts +++ b/build/darwin/create-universal-app.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import { makeUniversalApp } from 'vscode-universal-bundler'; import { spawn } from '@malept/cross-spawn-promise'; import * as fs from 'fs-extra'; @@ -78,7 +80,7 @@ async function main() { force: true }); - const productJson = await fs.readJson(productJsonPath); + let productJson = await fs.readJson(productJsonPath); Object.assign(productJson, { darwinUniversalAssetId: 'darwin-universal' }); diff --git a/build/darwin/sign.js b/build/darwin/sign.js index 06d7ac039d..b33fdc01bc 100644 --- a/build/darwin/sign.js +++ b/build/darwin/sign.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const codesign = require("electron-osx-sign"); const path = require("path"); diff --git a/build/darwin/sign.ts b/build/darwin/sign.ts index 03bc801677..69bd06b783 100644 --- a/build/darwin/sign.ts +++ b/build/darwin/sign.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as codesign from 'electron-osx-sign'; import * as path from 'path'; import * as util from '../lib/util'; diff --git a/build/filters.js b/build/filters.js index c24a7a3eab..6573eb4678 100644 --- a/build/filters.js +++ b/build/filters.js @@ -52,6 +52,7 @@ module.exports.unicodeFilter = [ '!extensions/typescript-language-features/test-workspace/**', '!extensions/vscode-api-tests/testWorkspace/**', '!extensions/vscode-api-tests/testWorkspace2/**', + '!extensions/vscode-custom-editor-tests/test-workspace/**', '!extensions/**/dist/**', '!extensions/**/out/**', '!extensions/**/snippets/**', @@ -92,6 +93,7 @@ module.exports.indentationFilter = [ '!extensions/markdown-math/notebook-out/**', '!extensions/vscode-api-tests/testWorkspace/**', '!extensions/vscode-api-tests/testWorkspace2/**', + '!extensions/vscode-custom-editor-tests/test-workspace/**', '!build/monaco/**', '!build/win32/**', diff --git a/build/gulpfile.editor.js b/build/gulpfile.editor.js index 9e2759c05d..e0e026cd9e 100644 --- a/build/gulpfile.editor.js +++ b/build/gulpfile.editor.js @@ -17,41 +17,34 @@ const compilation = require('./lib/compilation'); const monacoapi = require('./lib/monaco-api'); const fs = require('fs'); -const root = path.dirname(__dirname); -const sha1 = util.getVersion(root); -const semver = require('./monaco/package.json').version; -const headerVersion = semver + '(' + sha1 + ')'; +let root = path.dirname(__dirname); +let sha1 = util.getVersion(root); +let semver = require('./monaco/package.json').version; +let headerVersion = semver + '(' + sha1 + ')'; // Build -const editorEntryPoints = [ +let editorEntryPoints = [ { name: 'vs/editor/editor.main', include: [], exclude: ['vs/css', 'vs/nls'], - prepend: [ - { path: 'out-editor-build/vs/css.js', amdModuleId: 'vs/css' }, - { path: 'out-editor-build/vs/nls.js', amdModuleId: 'vs/nls' } - ], + prepend: ['out-editor-build/vs/css.js', 'out-editor-build/vs/nls.js'], }, { name: 'vs/base/common/worker/simpleWorker', include: ['vs/editor/common/services/editorSimpleWorker'], - exclude: ['vs/nls'], - prepend: [ - { path: 'vs/loader.js' }, - { path: 'vs/nls.js', amdModuleId: 'vs/nls' }, - { path: 'vs/base/worker/workerMain.js' } - ], + prepend: ['vs/loader.js'], + append: ['vs/base/worker/workerMain'], dest: 'vs/base/worker/workerMain.js' } ]; -const editorResources = [ +let editorResources = [ 'out-editor-build/vs/base/browser/ui/codicons/**/*.ttf' ]; -const BUNDLED_FILE_HEADER = [ +let BUNDLED_FILE_HEADER = [ '/*!-----------------------------------------------------------', ' * Copyright (c) Microsoft Corporation. All rights reserved.', ' * Version: ' + headerVersion, @@ -116,6 +109,12 @@ const createESMSourcesAndResourcesTask = task.define('extract-editor-esm', () => 'inlineEntryPoint:0.ts', 'inlineEntryPoint:1.ts', 'vs/loader.js', + 'vs/nls.ts', + 'vs/nls.build.js', + 'vs/nls.d.ts', + 'vs/css.js', + 'vs/css.build.js', + 'vs/css.d.ts', 'vs/base/worker/workerMain.ts', ], renames: { @@ -225,7 +224,7 @@ const appendJSToESMImportsTask = task.define('append-js-to-esm-imports', () => { result.push(line); continue; } - const modifiedLine = ( + let modifiedLine = ( line .replace(/^import(.*)\'([^']+)\'/, `import$1'$2.js'`) .replace(/^export \* from \'([^']+)\'/, `export * from '$1.js'`) @@ -240,10 +239,10 @@ const appendJSToESMImportsTask = task.define('append-js-to-esm-imports', () => { * @param {string} contents */ function toExternalDTS(contents) { - const lines = contents.split(/\r\n|\r|\n/); + let lines = contents.split(/\r\n|\r|\n/); let killNextCloseCurlyBrace = false; for (let i = 0; i < lines.length; i++) { - const line = lines[i]; + let line = lines[i]; if (killNextCloseCurlyBrace) { if ('}' === line) { @@ -317,7 +316,7 @@ const finalEditorResourcesTask = task.define('final-editor-resources', () => { // package.json gulp.src('build/monaco/package.json') .pipe(es.through(function (data) { - const json = JSON.parse(data.contents.toString()); + let json = JSON.parse(data.contents.toString()); json.private = false; data.contents = Buffer.from(JSON.stringify(json, null, ' ')); this.emit('data', data); @@ -361,10 +360,10 @@ const finalEditorResourcesTask = task.define('final-editor-resources', () => { return; } - const relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map')); + let relativePathToMap = path.relative(path.join(data.relative), path.join('min-maps', data.relative + '.map')); let strContents = data.contents.toString(); - const newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/'); + let newStr = '//# sourceMappingURL=' + relativePathToMap.replace(/\\/g, '/'); strContents = strContents.replace(/\/\/# sourceMappingURL=[^ ]+$/, newStr); data.contents = Buffer.from(strContents); @@ -484,13 +483,13 @@ function createTscCompileTask(watch) { cwd: path.join(__dirname, '..'), // stdio: [null, 'pipe', 'inherit'] }); - const errors = []; - const reporter = createReporter('monaco'); + let errors = []; + let reporter = createReporter('monaco'); /** @type {NodeJS.ReadWriteStream | undefined} */ let report; // eslint-disable-next-line no-control-regex - const magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings + let magic = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g; // https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings child.stdout.on('data', data => { let str = String(data); @@ -503,12 +502,12 @@ function createTscCompileTask(watch) { report.end(); } else if (str) { - const match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str); + let match = /(.*\(\d+,\d+\): )(.*: )(.*)/.exec(str); if (match) { // trying to massage the message so that it matches the gulp-tsb error messages // e.g. src/vs/base/common/strings.ts(663,5): error TS2322: Type '1234' is not assignable to type 'string'. - const fullpath = path.join(root, match[1]); - const message = match[3]; + let fullpath = path.join(root, match[1]); + let message = match[3]; reporter(fullpath + message); } else { reporter(str); diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index d342c9d24f..fe6272b7a9 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -56,7 +56,6 @@ const compilations = [ 'json-language-features/client/tsconfig.json', 'json-language-features/server/tsconfig.json', 'markdown-language-features/preview-src/tsconfig.json', - 'markdown-language-features/server/tsconfig.json', 'markdown-language-features/tsconfig.json', 'markdown-math/tsconfig.json', 'merge-conflict/tsconfig.json', @@ -64,13 +63,12 @@ const compilations = [ 'npm/tsconfig.json', 'php-language-features/tsconfig.json', 'search-result/tsconfig.json', - 'references-view/tsconfig.json', 'simple-browser/tsconfig.json', 'typescript-language-features/test-workspace/tsconfig.json', 'typescript-language-features/tsconfig.json', 'vscode-api-tests/tsconfig.json', 'vscode-colorize-tests/tsconfig.json', - 'vscode-notebook-tests/tsconfig.json', + 'vscode-custom-editor-tests/tsconfig.json', 'vscode-test-resolver/tsconfig.json' ]; */ @@ -95,7 +93,7 @@ const tasks = compilations.map(function (tsconfigFile) { const baseUrl = getBaseUrl(out); let headerId, headerOut; - const index = relativeDirname.indexOf('/'); + let index = relativeDirname.indexOf('/'); if (index < 0) { headerId = 'microsoft.' + relativeDirname; // {{SQL CARBON EDIT}} headerOut = 'out'; @@ -104,9 +102,9 @@ const tasks = compilations.map(function (tsconfigFile) { headerOut = relativeDirname.substr(index + 1) + '/out'; } - function createPipeline(build, emitError, transpileOnly) { + function createPipeline(build, emitError) { const nlsDev = require('vscode-nls-dev'); - const tsb = require('./lib/tsb'); + const tsb = require('gulp-tsb'); const sourcemaps = require('gulp-sourcemaps'); const reporter = createReporter('extensions'); @@ -114,7 +112,7 @@ const tasks = compilations.map(function (tsconfigFile) { overrideOptions.inlineSources = Boolean(build); overrideOptions.base = path.dirname(absolutePath); - const compilation = tsb.create(absolutePath, overrideOptions, { verbose: false, transpileOnly, transpileOnlyIncludesDts: transpileOnly }, err => reporter(err.toString())); + const compilation = tsb.create(absolutePath, overrideOptions, false, err => reporter(err.toString())); const pipeline = function () { const input = es.through(); @@ -156,16 +154,6 @@ const tasks = compilations.map(function (tsconfigFile) { const cleanTask = task.define(`clean-extension-${name}`, util.rimraf(out)); - const transpileTask = task.define(`transpile-extension:${name}`, task.series(cleanTask, () => { - const pipeline = createPipeline(false, true, true); - const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'])); - const input = es.merge(nonts, pipeline.tsProjectSrc()); - - return input - .pipe(pipeline()) - .pipe(gulp.dest(out)); - })); - const compileTask = task.define(`compile-extension:${name}`, task.series(cleanTask, () => { const pipeline = createPipeline(false, true); const nonts = gulp.src(src, srcOpts).pipe(filter(['**', '!**/*.ts'])); @@ -198,16 +186,12 @@ const tasks = compilations.map(function (tsconfigFile) { })); // Tasks - gulp.task(transpileTask); gulp.task(compileTask); gulp.task(watchTask); - return { transpileTask, compileTask, watchTask, compileBuildTask }; + return { compileTask, watchTask, compileBuildTask }; }); -const transpileExtensionsTask = task.define('transpile-extensions', task.parallel(...tasks.map(t => t.transpileTask))); -gulp.task(transpileExtensionsTask); - const compileExtensionsTask = task.define('compile-extensions', task.parallel(...tasks.map(t => t.compileTask))); gulp.task(compileExtensionsTask); exports.compileExtensionsTask = compileExtensionsTask; @@ -245,11 +229,7 @@ const compileExtensionsBuildTask = task.define('compile-extensions-build', task. )); gulp.task(compileExtensionsBuildTask); -// {{SQL CARBON EDIT}} Needed to pass the "done" gulp callback function to fix "Did you roget to signal async completion" error -gulp.task(task.define('extensions-ci', (done) => { - task.series(compileExtensionsBuildTask, compileExtensionMediaBuildTask); - done(); -})); +gulp.task(task.define('extensions-ci', task.series(compileExtensionsBuildTask, compileExtensionMediaBuildTask))); exports.compileExtensionsBuildTask = compileExtensionsBuildTask; diff --git a/build/gulpfile.hygiene.js b/build/gulpfile.hygiene.js index 7294d319ad..d2ccb4885f 100644 --- a/build/gulpfile.hygiene.js +++ b/build/gulpfile.hygiene.js @@ -16,7 +16,7 @@ function checkPackageJSON(actualPath) { const actual = require(path.join(__dirname, '..', actualPath)); const rootPackageJSON = require('../package.json'); const checkIncluded = (set1, set2) => { - for (const depName in set1) { + for (let depName in set1) { if (depName === 'typescript') { continue; } diff --git a/build/gulpfile.js b/build/gulpfile.js index 06b1268cf7..a4cccae498 100644 --- a/build/gulpfile.js +++ b/build/gulpfile.js @@ -11,7 +11,7 @@ require('events').EventEmitter.defaultMaxListeners = 100; const gulp = require('gulp'); const util = require('./lib/util'); const task = require('./lib/task'); -const { transpileTask, compileTask, watchTask, compileApiProposalNamesTask, watchApiProposalNamesTask } = require('./lib/compilation'); +const { compileTask, watchTask, compileApiProposalNamesTask, watchApiProposalNamesTask } = require('./lib/compilation'); const { monacoTypecheckTask/* , monacoTypecheckWatchTask */ } = require('./gulpfile.editor'); const { compileExtensionsTask, watchExtensionsTask, compileExtensionMediaTask } = require('./gulpfile.extensions'); @@ -19,10 +19,6 @@ const { compileExtensionsTask, watchExtensionsTask, compileExtensionMediaTask } gulp.task(compileApiProposalNamesTask); gulp.task(watchApiProposalNamesTask); -// Transpile only -const transpileClientTask = task.define('transpile-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), transpileTask('src', 'out'))); -gulp.task(transpileClientTask); - // Fast compile for development time const compileClientTask = task.define('compile-client', task.series(util.rimraf('out'), util.buildWebNodePaths('out'), compileApiProposalNamesTask, compileTask('src', 'out', false))); gulp.task(compileClientTask); diff --git a/build/gulpfile.reh.js b/build/gulpfile.reh.js index 87fcfe27df..3a669fce9f 100644 --- a/build/gulpfile.reh.js +++ b/build/gulpfile.reh.js @@ -116,7 +116,7 @@ const serverEntryPoints = [ name: 'vs/workbench/api/node/extensionHostProcess', exclude: ['vs/css', 'vs/nls'] }, - { + { name: 'vs/platform/files/node/watcher/watcherMain', exclude: ['vs/css', 'vs/nls'] }, @@ -135,7 +135,7 @@ try { // Include workbench web ...vscodeWebEntryPoints - ]; + ]; } catch (err) { serverWithWebEntryPoints = [ // Include all of server @@ -356,14 +356,14 @@ function copyConfigTask(folder) { const json = require('gulp-json-editor'); return gulp.src(['remote/pkg-package.json'], { base: 'remote' }) - .pipe(rename(path => path.basename += '.' + folder)) - .pipe(json(obj => { - const pkg = obj.pkg; - pkg.scripts = pkg.scripts && pkg.scripts.map(p => path.join(destination, p)); - pkg.assets = pkg.assets && pkg.assets.map(p => path.join(destination, p)); - return obj; - })) - .pipe(vfs.dest('out-vscode-reh-pkg')); + .pipe(rename(path => path.basename += '.' + folder)) + .pipe(json(obj => { + const pkg = obj.pkg; + pkg.scripts = pkg.scripts && pkg.scripts.map(p => path.join(destination, p)); + pkg.assets = pkg.assets && pkg.assets.map(p => path.join(destination, p)); + return obj; + })) + .pipe(vfs.dest('out-vscode-reh-pkg')); }; } diff --git a/build/gulpfile.vscode.js b/build/gulpfile.vscode.js index 877e088292..be7e312349 100644 --- a/build/gulpfile.vscode.js +++ b/build/gulpfile.vscode.js @@ -64,6 +64,7 @@ const vscodeResources = [ 'out-build/vs/base/browser/ui/codicons/codicon/**', 'out-build/vs/base/parts/sandbox/electron-browser/preload.js', 'out-build/vs/platform/environment/node/userDataPath.js', + 'out-build/vs/platform/extensions/node/extensionHostStarterWorkerMain.js', 'out-build/vs/workbench/browser/media/*-theme.css', 'out-build/vs/workbench/contrib/debug/**/*.json', 'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt', @@ -75,7 +76,7 @@ const vscodeResources = [ 'out-build/vs/workbench/contrib/tasks/**/*.json', 'out-build/vs/platform/files/**/*.exe', 'out-build/vs/platform/files/**/*.md', - 'out-build/vs/code/electron-sandbox/workbench/**', + 'out-build/vs/code/electron-browser/workbench/**', 'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js', 'out-build/vs/code/electron-sandbox/issue/issueReporter.js', 'out-build/sql/**/*.{svg,png,cur,html}', @@ -186,9 +187,9 @@ gulp.task(core); * @return {Object} A map of paths to checksums. */ function computeChecksums(out, filenames) { - const result = {}; + let result = {}; filenames.forEach(function (filename) { - const fullPath = path.join(process.cwd(), out, filename); + let fullPath = path.join(process.cwd(), out, filename); result[filename] = computeChecksum(fullPath); }); return result; @@ -201,9 +202,9 @@ function computeChecksums(out, filenames) { * @return {string} The checksum for `filename`. */ function computeChecksum(filename) { - const contents = fs.readFileSync(filename); + let contents = fs.readFileSync(filename); - const hash = crypto + let hash = crypto .createHash('md5') .update(contents) .digest('base64') @@ -229,8 +230,8 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op 'vs/workbench/workbench.desktop.main.js', 'vs/workbench/workbench.desktop.main.css', 'vs/workbench/api/node/extensionHostProcess.js', - 'vs/code/electron-sandbox/workbench/workbench.html', - 'vs/code/electron-sandbox/workbench/workbench.js' + 'vs/code/electron-browser/workbench/workbench.html', + 'vs/code/electron-browser/workbench/workbench.js' ]); const src = gulp.src(out + '/**', { base: '.' }) @@ -321,7 +322,6 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' })); } else if (platform === 'darwin') { const shortcut = gulp.src('resources/darwin/bin/code.sh') - .pipe(replace('@@APPNAME@@', product.applicationName)) .pipe(rename('bin/code')); all = es.merge(all, shortcut); @@ -366,14 +366,10 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op result = es.merge(result, gulp.src('resources/win32/VisualElementsManifest.xml', { base: 'resources/win32' }) .pipe(rename(product.nameShort + '.VisualElementsManifest.xml'))); - - result = es.merge(result, gulp.src('.build/policies/win32/**', { base: '.build/policies/win32' }) - .pipe(rename(f => f.dirname = `policies/${f.dirname}`))); - } else if (platform === 'linux') { result = es.merge(result, gulp.src('resources/linux/bin/code.sh', { base: '.' }) .pipe(replace('@@PRODNAME@@', product.nameLong)) - .pipe(replace('@@APPNAME@@', product.applicationName)) + .pipe(replace('@@NAME@@', product.applicationName)) .pipe(rename('bin/' + product.applicationName))); } @@ -527,7 +523,7 @@ gulp.task(task.define( gulp.task('vscode-translations-pull', function () { return es.merge([...i18n.defaultLanguages, ...i18n.extraLanguages].map(language => { - const includeDefault = !!innoSetupConfig[language.id].defaultInfo; + let includeDefault = !!innoSetupConfig[language.id].defaultInfo; return i18n.pullSetupXlfFiles(apiHostname, apiName, apiToken, language, includeDefault).pipe(vfs.dest(`../vscode-translations-import/${language.id}/setup`)); })); }); diff --git a/build/gulpfile.vscode.linux.js b/build/gulpfile.vscode.linux.js index dc1b101c85..2770151708 100644 --- a/build/gulpfile.vscode.linux.js +++ b/build/gulpfile.vscode.linux.js @@ -16,9 +16,6 @@ const task = require('./lib/task'); const packageJson = require('../package.json'); const product = require('../product.json'); const rpmDependenciesGenerator = require('./linux/rpm/dependencies-generator'); -const debianDependenciesGenerator = require('./linux/debian/dependencies-generator'); -const sysrootInstaller = require('./linux/debian/install-sysroot'); -const debianRecommendedDependencies = require('./linux/debian/dep-lists').recommendedDeps; const path = require('path'); const root = path.dirname(__dirname); const commit = util.getVersion(root); @@ -78,16 +75,12 @@ function prepareDebPackage(arch) { let size = 0; const control = code.pipe(es.through( function (f) { size += f.isDirectory() ? 4096 : f.contents.length; }, - async function () { + function () { const that = this; - const sysroot = await sysrootInstaller.getSysroot(debArch); - const dependencies = debianDependenciesGenerator.getDependencies(binaryDir, product.applicationName, debArch, sysroot); gulp.src('resources/linux/debian/control.template', { base: '.' }) .pipe(replace('@@NAME@@', product.applicationName)) .pipe(replace('@@VERSION@@', packageJson.version + '-' + linuxPackageRevision)) .pipe(replace('@@ARCHITECTURE@@', debArch)) - .pipe(replace('@@DEPENDS@@', dependencies.join(', '))) - .pipe(replace('@@RECOMMENDS@@', debianRecommendedDependencies.join(', '))) .pipe(replace('@@INSTALLEDSIZE@@', Math.ceil(size / 1024))) .pipe(rename('DEBIAN/control')) .pipe(es.through(function (f) { that.emit('data', f); }, function () { that.emit('end'); })); @@ -219,7 +212,7 @@ function buildRpmPackage(arch) { return shell.task([ 'mkdir -p ' + destination, - 'HOME="$(pwd)/' + destination + '" rpmbuild -bb ' + rpmBuildPath + '/SPECS/' + product.applicationName + '.spec --target=' + rpmArch, + 'HOME="$(pwd)/' + destination + '" fakeroot rpmbuild -bb ' + rpmBuildPath + '/SPECS/' + product.applicationName + '.spec --target=' + rpmArch, 'cp "' + rpmOut + '/$(ls ' + rpmOut + ')" ' + destination + '/' ]); } diff --git a/build/gulpfile.vscode.web.js b/build/gulpfile.vscode.web.js index 9a00be9971..2e82737c2f 100644 --- a/build/gulpfile.vscode.web.js +++ b/build/gulpfile.vscode.web.js @@ -208,7 +208,7 @@ function packageTask(sourceFolderName, destinationFolderName) { gulp.src('resources/server/code-512.png', { base: 'resources/server' }) ); - const all = es.merge( + let all = es.merge( packageJsonStream, license, sources, @@ -218,7 +218,7 @@ function packageTask(sourceFolderName, destinationFolderName) { pwaicons ); - const result = all + let result = all .pipe(util.skipDirectories()) .pipe(util.fixWin32DirectoryPermissions()); diff --git a/build/hygiene.js b/build/hygiene.js index a12329e5a8..9e08a8b001 100644 --- a/build/hygiene.js +++ b/build/hygiene.js @@ -53,7 +53,7 @@ function hygiene(some, linting = true) { const m = /([^\t\n\r\x20-\x7E⊃⊇✔︎✓🎯⚠️🛑🔴🚗🚙🚕🎉✨❗⇧⌥⌘×÷¦⋯…↑↓→→←↔⟷·•●◆▼⟪⟫┌└├⏎↩√φ]+)/g.exec(line); if (m) { console.error( - file.relative + `(${i + 1},${m.index + 1}): Unexpected unicode character: "${m[0]}" (charCode: ${m[0].charCodeAt(0)}). To suppress, use // allow-any-unicode-next-line` + file.relative + `(${i + 1},${m.index + 1}): Unexpected unicode character: "${m[0]}". To suppress, use // allow-any-unicode-next-line` ); errorCount++; } @@ -115,8 +115,8 @@ function hygiene(some, linting = true) { }) .then( (result) => { - const original = result.src.replace(/\r\n/gm, '\n'); - const formatted = result.dest.replace(/\r\n/gm, '\n'); + let original = result.src.replace(/\r\n/gm, '\n'); + let formatted = result.dest.replace(/\r\n/gm, '\n'); if (original !== formatted) { console.error( diff --git a/build/lib/asar.js b/build/lib/asar.js index 2a25780d44..c3ada32736 100644 --- a/build/lib/asar.js +++ b/build/lib/asar.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAsar = void 0; const path = require("path"); @@ -81,7 +81,7 @@ function createAsar(folderPath, unpackGlobs, destFilename) { out.push(file.contents); } }, function () { - const finish = () => { + let finish = () => { { const headerPickle = pickle.createEmpty(); headerPickle.writeString(JSON.stringify(filesystem.header)); diff --git a/build/lib/asar.ts b/build/lib/asar.ts index 508339ff85..2a50b219ba 100644 --- a/build/lib/asar.ts +++ b/build/lib/asar.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as path from 'path'; import * as es from 'event-stream'; const pickle = require('chromium-pickle-js'); @@ -96,7 +98,7 @@ export function createAsar(folderPath: string, unpackGlobs: string[], destFilena } }, function () { - const finish = () => { + let finish = () => { { const headerPickle = pickle.createEmpty(); headerPickle.writeString(JSON.stringify(filesystem.header)); diff --git a/build/lib/builtInExtensions.js b/build/lib/builtInExtensions.js index e0a4dc74a8..50d2dbb787 100644 --- a/build/lib/builtInExtensions.js +++ b/build/lib/builtInExtensions.js @@ -98,12 +98,12 @@ function writeControlFile(control) { fs.writeFileSync(controlFilePath, JSON.stringify(control, null, 2)); } function getBuiltInExtensions() { - log('Synchronizing built-in extensions...'); + log('Syncronizing built-in extensions...'); log(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`); const control = readControlFile(); const streams = []; for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { - const controlState = control[extension.name] || 'marketplace'; + let controlState = control[extension.name] || 'marketplace'; control[extension.name] = controlState; streams.push(syncExtension(extension, controlState)); } diff --git a/build/lib/builtInExtensions.ts b/build/lib/builtInExtensions.ts index 2373db4738..f5daac1919 100644 --- a/build/lib/builtInExtensions.ts +++ b/build/lib/builtInExtensions.ts @@ -136,14 +136,14 @@ function writeControlFile(control: IControlFile): void { } export function getBuiltInExtensions(): Promise { - log('Synchronizing built-in extensions...'); + log('Syncronizing built-in extensions...'); log(`You can manage built-in extensions with the ${ansiColors.cyan('--builtin')} flag`); const control = readControlFile(); const streams: Stream[] = []; for (const extension of [...builtInExtensions, ...webBuiltInExtensions]) { - const controlState = control[extension.name] || 'marketplace'; + let controlState = control[extension.name] || 'marketplace'; control[extension.name] = controlState; streams.push(syncExtension(extension, controlState)); diff --git a/build/lib/bundle.js b/build/lib/bundle.js index 571cbb27f7..6ea3384ff3 100644 --- a/build/lib/bundle.js +++ b/build/lib/bundle.js @@ -43,20 +43,14 @@ function bundle(entryPoints, config, callback) { if (!config.paths['vs/css']) { config.paths['vs/css'] = 'out-build/vs/css.build'; } - config.buildForceInvokeFactory = config.buildForceInvokeFactory || {}; - config.buildForceInvokeFactory['vs/nls'] = true; - config.buildForceInvokeFactory['vs/css'] = true; loader.config(config); loader(['require'], (localRequire) => { - const resolvePath = (entry) => { - let r = localRequire.toUrl(entry.path); - if (!r.endsWith('.js')) { - r += '.js'; + const resolvePath = (path) => { + const r = localRequire.toUrl(path); + if (!/\.js/.test(r)) { + return r + '.js'; } - // avoid packaging the build version of plugins: - r = r.replace('vs/nls.build.js', 'vs/nls.js'); - r = r.replace('vs/css.build.js', 'vs/css.js'); - return { path: r, amdModuleId: entry.amdModuleId }; + return r; }; for (const moduleId in entryPointsMap) { const entryPoint = entryPointsMap[moduleId]; @@ -305,17 +299,8 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend, if (module.shim) { mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents)); } - else if (module.defineLocation) { - mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents)); - } else { - const moduleCopy = { - id: module.id, - path: module.path, - defineLocation: module.defineLocation, - dependencies: module.dependencies - }; - throw new Error(`Cannot bundle module '${module.id}' for entry point '${entryPoint}' because it has no shim and it lacks a defineLocation: ${JSON.stringify(moduleCopy)}`); + mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents)); } }); Object.keys(usedPlugins).forEach((pluginName) => { @@ -337,13 +322,10 @@ function emitEntryPoint(modulesMap, deps, entryPoint, includedModules, prepend, plugin.writeFile(pluginName, entryPoint, req, write, {}); } }); - const toIFile = (entry) => { - let contents = readFileAndRemoveBOM(entry.path); - if (entry.amdModuleId) { - contents = contents.replace(/^define\(/m, `define("${entry.amdModuleId}",`); - } + const toIFile = (path) => { + const contents = readFileAndRemoveBOM(path); return { - path: entry.path, + path: path, contents: contents }; }; diff --git a/build/lib/bundle.ts b/build/lib/bundle.ts index 62a22b03bc..779a23e575 100644 --- a/build/lib/bundle.ts +++ b/build/lib/bundle.ts @@ -15,7 +15,7 @@ interface IPosition { interface IBuildModuleInfo { id: string; path: string; - defineLocation: IPosition | null; + defineLocation: IPosition; dependencies: string[]; shim: string; exports: any; @@ -42,17 +42,12 @@ interface ILoaderPluginReqFunc { toUrl(something: string): string; } -export interface IExtraFile { - path: string; - amdModuleId?: string; -} - export interface IEntryPoint { name: string; include?: string[]; exclude?: string[]; - prepend?: IExtraFile[]; - append?: IExtraFile[]; + prepend?: string[]; + append?: string[]; dest?: string; } @@ -97,13 +92,6 @@ interface IPartialBundleResult { export interface ILoaderConfig { isBuild?: boolean; paths?: { [path: string]: any }; - /* - * Normally, during a build, no module factories are invoked. This can be used - * to forcefully execute a module's factory. - */ - buildForceInvokeFactory: { - [moduleId: string]: boolean; - }; } /** @@ -144,21 +132,15 @@ export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callba if (!config.paths['vs/css']) { config.paths['vs/css'] = 'out-build/vs/css.build'; } - config.buildForceInvokeFactory = config.buildForceInvokeFactory || {}; - config.buildForceInvokeFactory['vs/nls'] = true; - config.buildForceInvokeFactory['vs/css'] = true; loader.config(config); loader(['require'], (localRequire: any) => { - const resolvePath = (entry: IExtraFile) => { - let r = localRequire.toUrl(entry.path); - if (!r.endsWith('.js')) { - r += '.js'; + const resolvePath = (path: string) => { + const r = localRequire.toUrl(path); + if (!/\.js/.test(r)) { + return r + '.js'; } - // avoid packaging the build version of plugins: - r = r.replace('vs/nls.build.js', 'vs/nls.js'); - r = r.replace('vs/css.build.js', 'vs/css.js'); - return { path: r, amdModuleId: entry.amdModuleId }; + return r; }; for (const moduleId in entryPointsMap) { const entryPoint = entryPointsMap[moduleId]; @@ -421,8 +403,8 @@ function emitEntryPoint( deps: IGraph, entryPoint: string, includedModules: string[], - prepend: IExtraFile[], - append: IExtraFile[], + prepend: string[], + append: string[], dest: string | undefined ): IEmitEntryPointResult { if (!dest) { @@ -462,16 +444,8 @@ function emitEntryPoint( if (module.shim) { mainResult.sources.push(emitShimmedModule(c, deps[c], module.shim, module.path, contents)); - } else if (module.defineLocation) { - mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents)); } else { - const moduleCopy = { - id: module.id, - path: module.path, - defineLocation: module.defineLocation, - dependencies: module.dependencies - }; - throw new Error(`Cannot bundle module '${module.id}' for entry point '${entryPoint}' because it has no shim and it lacks a defineLocation: ${JSON.stringify(moduleCopy)}`); + mainResult.sources.push(emitNamedModule(c, module.defineLocation, module.path, contents)); } }); @@ -496,13 +470,10 @@ function emitEntryPoint( } }); - const toIFile = (entry: IExtraFile): IFile => { - let contents = readFileAndRemoveBOM(entry.path); - if (entry.amdModuleId) { - contents = contents.replace(/^define\(/m, `define("${entry.amdModuleId}",`); - } + const toIFile = (path: string): IFile => { + const contents = readFileAndRemoveBOM(path); return { - path: entry.path, + path: path, contents: contents }; }; diff --git a/build/lib/compilation.js b/build/lib/compilation.js index a6f8577f13..6e1ea4beb2 100644 --- a/build/lib/compilation.js +++ b/build/lib/compilation.js @@ -1,10 +1,10 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); -exports.watchApiProposalNamesTask = exports.compileApiProposalNamesTask = exports.watchTask = exports.compileTask = exports.transpileTask = void 0; +exports.watchApiProposalNamesTask = exports.compileApiProposalNamesTask = exports.watchTask = exports.compileTask = void 0; const es = require("event-stream"); const fs = require("fs"); const gulp = require("gulp"); @@ -22,7 +22,7 @@ const watch = require('./watch'); const reporter = (0, reporter_1.createReporter)(); function getTypeScriptCompilerOptions(src) { const rootDir = path.join(__dirname, `../../${src}`); - const options = {}; + let options = {}; options.verbose = false; options.sourceMap = true; if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry @@ -34,8 +34,8 @@ function getTypeScriptCompilerOptions(src) { options.newLine = /\r\n/.test(fs.readFileSync(__filename, 'utf8')) ? 0 : 1; return options; } -function createCompile(src, build, emitError, transpileOnly) { - const tsb = require('./tsb'); +function createCompile(src, build, emitError) { + const tsb = require('gulp-tsb'); const sourcemaps = require('gulp-sourcemaps'); const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json'); const overrideOptions = Object.assign(Object.assign({}, getTypeScriptCompilerOptions(src)), { inlineSources: Boolean(build) }); @@ -69,7 +69,7 @@ function createCompile(src, build, emitError, transpileOnly) { .pipe(noDeclarationsFilter) .pipe(build ? nls.nls() : es.through()) .pipe(noDeclarationsFilter.restore) - .pipe(transpileOnly ? es.through() : sourcemaps.write('.', { + .pipe(sourcemaps.write('.', { addComment: false, includeContent: !!build, sourceRoot: overrideOptions.sourceRoot @@ -83,24 +83,14 @@ function createCompile(src, build, emitError, transpileOnly) { }; return pipeline; } -function transpileTask(src, out) { - return function () { - const transpile = createCompile(src, false, true, true); - const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); - return srcPipe - .pipe(transpile()) - .pipe(gulp.dest(out)); - }; -} -exports.transpileTask = transpileTask; function compileTask(src, out, build) { return function () { if (os.totalmem() < 4000000000) { throw new Error('compilation requires 4GB of RAM'); } - const compile = createCompile(src, build, true, false); + const compile = createCompile(src, build, true); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); - const generator = new MonacoGenerator(false); + let generator = new MonacoGenerator(false); if (src === 'src') { generator.execute(); } @@ -113,10 +103,10 @@ function compileTask(src, out, build) { exports.compileTask = compileTask; function watchTask(out, build) { return function () { - const compile = createCompile('src', build, false, false); + const compile = createCompile('src', build); const src = gulp.src('src/**', { base: 'src' }); const watchSrc = watch('src/**', { base: 'src', readDelay: 200 }); - const generator = new MonacoGenerator(true); + let generator = new MonacoGenerator(true); generator.execute(); return watchSrc .pipe(generator.stream) @@ -132,7 +122,7 @@ class MonacoGenerator { this._isWatch = isWatch; this.stream = es.through(); this._watchedFiles = {}; - const onWillReadFile = (moduleId, filePath) => { + let onWillReadFile = (moduleId, filePath) => { if (!this._isWatch) { return; } @@ -169,7 +159,7 @@ class MonacoGenerator { }, 20); } _run() { - const r = monacodts.run3(this._declarationResolver); + let r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { // The build must always be able to generate the monaco.d.ts throw new Error(`monaco.d.ts generation error - Cannot continue`); @@ -198,15 +188,6 @@ class MonacoGenerator { } } function generateApiProposalNames() { - let eol; - try { - const src = fs.readFileSync('src/vs/workbench/services/extensions/common/extensionsApiProposals.ts', 'utf-8'); - const match = /\r?\n/m.exec(src); - eol = match ? match[0] : os.EOL; - } - catch { - eol = os.EOL; - } const pattern = /vscode\.proposed\.([a-zA-Z]+)\.d\.ts$/; const proposalNames = new Set(); const input = es.through(); @@ -233,7 +214,7 @@ function generateApiProposalNames() { '});', 'export type ApiProposalName = keyof typeof allApiProposals;', '', - ].join(eol); + ].join(os.EOL); this.emit('data', new File({ path: 'vs/workbench/services/extensions/common/extensionsApiProposals.ts', contents: Buffer.from(contents) diff --git a/build/lib/compilation.ts b/build/lib/compilation.ts index a764c6a7a2..7a5a0bc2ff 100644 --- a/build/lib/compilation.ts +++ b/build/lib/compilation.ts @@ -26,7 +26,7 @@ const reporter = createReporter(); function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions { const rootDir = path.join(__dirname, `../../${src}`); - const options: ts.CompilerOptions = {}; + let options: ts.CompilerOptions = {}; options.verbose = false; options.sourceMap = true; if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry @@ -39,8 +39,8 @@ function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions { return options; } -function createCompile(src: string, build: boolean, emitError: boolean, transpileOnly: boolean) { - const tsb = require('./tsb') as typeof import('./tsb'); +function createCompile(src: string, build: boolean, emitError?: boolean) { + const tsb = require('gulp-tsb') as typeof import('gulp-tsb'); const sourcemaps = require('gulp-sourcemaps') as typeof import('gulp-sourcemaps'); @@ -80,7 +80,7 @@ function createCompile(src: string, build: boolean, emitError: boolean, transpil .pipe(noDeclarationsFilter) .pipe(build ? nls.nls() : es.through()) .pipe(noDeclarationsFilter.restore) - .pipe(transpileOnly ? es.through() : sourcemaps.write('.', { + .pipe(sourcemaps.write('.', { addComment: false, includeContent: !!build, sourceRoot: overrideOptions.sourceRoot @@ -96,19 +96,6 @@ function createCompile(src: string, build: boolean, emitError: boolean, transpil return pipeline; } -export function transpileTask(src: string, out: string): () => NodeJS.ReadWriteStream { - - return function () { - - const transpile = createCompile(src, false, true, true); - const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); - - return srcPipe - .pipe(transpile()) - .pipe(gulp.dest(out)); - }; -} - export function compileTask(src: string, out: string, build: boolean): () => NodeJS.ReadWriteStream { return function () { @@ -117,9 +104,9 @@ export function compileTask(src: string, out: string, build: boolean): () => Nod throw new Error('compilation requires 4GB of RAM'); } - const compile = createCompile(src, build, true, false); + const compile = createCompile(src, build, true); const srcPipe = gulp.src(`${src}/**`, { base: `${src}` }); - const generator = new MonacoGenerator(false); + let generator = new MonacoGenerator(false); if (src === 'src') { generator.execute(); } @@ -134,12 +121,12 @@ export function compileTask(src: string, out: string, build: boolean): () => Nod export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteStream { return function () { - const compile = createCompile('src', build, false, false); + const compile = createCompile('src', build); const src = gulp.src('src/**', { base: 'src' }); const watchSrc = watch('src/**', { base: 'src', readDelay: 200 }); - const generator = new MonacoGenerator(true); + let generator = new MonacoGenerator(true); generator.execute(); return watchSrc @@ -163,7 +150,7 @@ class MonacoGenerator { this._isWatch = isWatch; this.stream = es.through(); this._watchedFiles = {}; - const onWillReadFile = (moduleId: string, filePath: string) => { + let onWillReadFile = (moduleId: string, filePath: string) => { if (!this._isWatch) { return; } @@ -205,7 +192,7 @@ class MonacoGenerator { } private _run(): monacodts.IMonacoDeclarationResult | null { - const r = monacodts.run3(this._declarationResolver); + let r = monacodts.run3(this._declarationResolver); if (!r && !this._isWatch) { // The build must always be able to generate the monaco.d.ts throw new Error(`monaco.d.ts generation error - Cannot continue`); @@ -238,16 +225,6 @@ class MonacoGenerator { } function generateApiProposalNames() { - let eol: string; - - try { - const src = fs.readFileSync('src/vs/workbench/services/extensions/common/extensionsApiProposals.ts', 'utf-8'); - const match = /\r?\n/m.exec(src); - eol = match ? match[0] : os.EOL; - } catch { - eol = os.EOL; - } - const pattern = /vscode\.proposed\.([a-zA-Z]+)\.d\.ts$/; const proposalNames = new Set(); @@ -276,7 +253,7 @@ function generateApiProposalNames() { '});', 'export type ApiProposalName = keyof typeof allApiProposals;', '', - ].join(eol); + ].join(os.EOL); this.emit('data', new File({ path: 'vs/workbench/services/extensions/common/extensionsApiProposals.ts', diff --git a/build/lib/dependencies.js b/build/lib/dependencies.js index 658d63a576..31a8c9450b 100644 --- a/build/lib/dependencies.js +++ b/build/lib/dependencies.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getProductionDependencies = void 0; const path = require("path"); diff --git a/build/lib/dependencies.ts b/build/lib/dependencies.ts index 4ef161bc7c..8292d92bdc 100644 --- a/build/lib/dependencies.ts +++ b/build/lib/dependencies.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as path from 'path'; import * as cp from 'child_process'; import * as _ from 'underscore'; diff --git a/build/lib/electron.js b/build/lib/electron.js index c4060df064..1c804081d3 100644 --- a/build/lib/electron.js +++ b/build/lib/electron.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.config = void 0; const fs = require("fs"); diff --git a/build/lib/electron.ts b/build/lib/electron.ts index 7aedd39710..b2e11a07b8 100644 --- a/build/lib/electron.ts +++ b/build/lib/electron.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fs from 'fs'; import * as path from 'path'; import * as vfs from 'vinyl-fs'; diff --git a/build/lib/eslint/code-no-look-behind-regex.js b/build/lib/eslint/code-no-look-behind-regex.js index 065be7d9ff..03212ee32e 100644 --- a/build/lib/eslint/code-no-look-behind-regex.js +++ b/build/lib/eslint/code-no-look-behind-regex.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); //------------------------------------------------------------------------------ // Rule Definition diff --git a/build/lib/eslint/code-no-look-behind-regex.ts b/build/lib/eslint/code-no-look-behind-regex.ts index 9e6d2bda50..7d10462639 100644 --- a/build/lib/eslint/code-no-look-behind-regex.ts +++ b/build/lib/eslint/code-no-look-behind-regex.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/experimental-utils'; import * as ESTree from 'estree'; diff --git a/build/lib/eslint/code-no-unexternalized-strings.js b/build/lib/eslint/code-no-unexternalized-strings.js index e72ea0974b..748778d151 100644 --- a/build/lib/eslint/code-no-unexternalized-strings.js +++ b/build/lib/eslint/code-no-unexternalized-strings.js @@ -41,7 +41,7 @@ module.exports = new (_a = class NoUnexternalizedStrings { key = keyNode.value; } else if (keyNode.type === experimental_utils_1.AST_NODE_TYPES.ObjectExpression) { - for (const property of keyNode.properties) { + for (let property of keyNode.properties) { if (property.type === experimental_utils_1.AST_NODE_TYPES.Property && !property.computed) { if (property.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier && property.key.name === 'key') { if (isStringLiteral(property.value)) { @@ -83,7 +83,7 @@ module.exports = new (_a = class NoUnexternalizedStrings { // (2) // report all invalid NLS keys if (!key.match(NoUnexternalizedStrings._rNlsKeys)) { - for (const value of values) { + for (let value of values) { context.report({ loc: value.call.loc, messageId: 'badKey', data: { key } }); } } diff --git a/build/lib/eslint/code-no-unexternalized-strings.ts b/build/lib/eslint/code-no-unexternalized-strings.ts index a0cacc63fc..ae9f6f8044 100644 --- a/build/lib/eslint/code-no-unexternalized-strings.ts +++ b/build/lib/eslint/code-no-unexternalized-strings.ts @@ -51,7 +51,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { key = keyNode.value; } else if (keyNode.type === AST_NODE_TYPES.ObjectExpression) { - for (const property of keyNode.properties) { + for (let property of keyNode.properties) { if (property.type === AST_NODE_TYPES.Property && !property.computed) { if (property.key.type === AST_NODE_TYPES.Identifier && property.key.name === 'key') { if (isStringLiteral(property.value)) { @@ -97,7 +97,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule { // (2) // report all invalid NLS keys if (!key.match(NoUnexternalizedStrings._rNlsKeys)) { - for (const value of values) { + for (let value of values) { context.report({ loc: value.call.loc, messageId: 'badKey', data: { key } }); } } diff --git a/build/lib/eslint/code-no-unused-expressions.js b/build/lib/eslint/code-no-unused-expressions.js index 19c6e2b183..30097ba58f 100644 --- a/build/lib/eslint/code-no-unused-expressions.js +++ b/build/lib/eslint/code-no-unused-expressions.js @@ -1,8 +1,14 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// FORKED FROM https://github.com/eslint/eslint/blob/b23ad0d789a909baf8d7c41a35bc53df932eaf30/lib/rules/no-unused-expressions.js +// and added support for `OptionalCallExpression`, see https://github.com/facebook/create-react-app/issues/8107 and https://github.com/eslint/eslint/issues/12642 +/** + * @fileoverview Flag expressions in statement position that do not side effect + * @author Michael Ficarra + */ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); //------------------------------------------------------------------------------ // Rule Definition diff --git a/build/lib/eslint/code-no-unused-expressions.ts b/build/lib/eslint/code-no-unused-expressions.ts index 19ddb9fc35..b6122759fa 100644 --- a/build/lib/eslint/code-no-unused-expressions.ts +++ b/build/lib/eslint/code-no-unused-expressions.ts @@ -11,6 +11,8 @@ * @author Michael Ficarra */ +'use strict'; + import * as eslint from 'eslint'; import { TSESTree } from '@typescript-eslint/experimental-utils'; import * as ESTree from 'estree'; diff --git a/build/lib/eslint/vscode-dts-cancellation.js b/build/lib/eslint/vscode-dts-cancellation.js index 10a4576d34..32e59a2344 100644 --- a/build/lib/eslint/vscode-dts-cancellation.js +++ b/build/lib/eslint/vscode-dts-cancellation.js @@ -16,7 +16,7 @@ module.exports = new class ApiProviderNaming { return { ['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature[key.name=/^(provide|resolve).+/]']: (node) => { let found = false; - for (const param of node.params) { + for (let param of node.params) { if (param.type === experimental_utils_1.AST_NODE_TYPES.Identifier) { found = found || param.name === 'token'; } diff --git a/build/lib/eslint/vscode-dts-cancellation.ts b/build/lib/eslint/vscode-dts-cancellation.ts index eabcc4f945..b78d023b4f 100644 --- a/build/lib/eslint/vscode-dts-cancellation.ts +++ b/build/lib/eslint/vscode-dts-cancellation.ts @@ -20,7 +20,7 @@ export = new class ApiProviderNaming implements eslint.Rule.RuleModule { ['TSInterfaceDeclaration[id.name=/.+Provider/] TSMethodSignature[key.name=/^(provide|resolve).+/]']: (node: any) => { let found = false; - for (const param of (node).params) { + for (let param of (node).params) { if (param.type === AST_NODE_TYPES.Identifier) { found = found || param.name === 'token'; } diff --git a/build/lib/eslint/vscode-dts-event-naming.js b/build/lib/eslint/vscode-dts-event-naming.js index 26466baa9b..55e1f62eba 100644 --- a/build/lib/eslint/vscode-dts-event-naming.js +++ b/build/lib/eslint/vscode-dts-event-naming.js @@ -77,7 +77,7 @@ module.exports = new (_a = class ApiEventNaming { if (def.type === experimental_utils_1.AST_NODE_TYPES.Identifier) { return def; } - else if ((def.type === experimental_utils_1.AST_NODE_TYPES.TSPropertySignature || def.type === experimental_utils_1.AST_NODE_TYPES.PropertyDefinition) && def.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier) { + else if ((def.type === experimental_utils_1.AST_NODE_TYPES.TSPropertySignature || def.type === experimental_utils_1.AST_NODE_TYPES.Property) && def.key.type === experimental_utils_1.AST_NODE_TYPES.Identifier) { return def.key; } return this.getIdent(def.parent); diff --git a/build/lib/eslint/vscode-dts-event-naming.ts b/build/lib/eslint/vscode-dts-event-naming.ts index 906682cfa8..c72e659c19 100644 --- a/build/lib/eslint/vscode-dts-event-naming.ts +++ b/build/lib/eslint/vscode-dts-event-naming.ts @@ -88,10 +88,11 @@ export = new class ApiEventNaming implements eslint.Rule.RuleModule { if (def.type === AST_NODE_TYPES.Identifier) { return def; - } else if ((def.type === AST_NODE_TYPES.TSPropertySignature || def.type === AST_NODE_TYPES.PropertyDefinition) && def.key.type === AST_NODE_TYPES.Identifier) { + } else if ((def.type === AST_NODE_TYPES.TSPropertySignature || def.type === AST_NODE_TYPES.Property) && def.key.type === AST_NODE_TYPES.Identifier) { return def.key; } return this.getIdent(def.parent); } }; + diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 924f76548c..e0352f9703 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -34,14 +34,14 @@ function minifyExtensionResources(input) { .pipe(jsonFilter) .pipe(buffer()) .pipe(es.mapSync((f) => { - const errors = []; - const value = jsoncParser.parse(f.contents.toString('utf8'), errors); - if (errors.length === 0) { - // file parsed OK => just stringify to drop whitespace and comments - f.contents = Buffer.from(JSON.stringify(value)); - } - return f; - })) + const errors = []; + const value = jsoncParser.parse(f.contents.toString('utf8'), errors); + if (errors.length === 0) { + // file parsed OK => just stringify to drop whitespace and comments + f.contents = Buffer.from(JSON.stringify(value)); + } + return f; + })) .pipe(jsonFilter.restore); } function updateExtensionPackageJSON(input, update) { @@ -50,10 +50,10 @@ function updateExtensionPackageJSON(input, update) { .pipe(packageJsonFilter) .pipe(buffer()) .pipe(es.mapSync((f) => { - const data = JSON.parse(f.contents.toString('utf8')); - f.contents = Buffer.from(JSON.stringify(update(data))); - return f; - })) + const data = JSON.parse(f.contents.toString('utf8')); + f.contents = Buffer.from(JSON.stringify(update(data))); + return f; + })) .pipe(packageJsonFilter.restore); } function fromLocal(extensionPath, forWeb) { @@ -95,11 +95,11 @@ function fromLocalWebpack(extensionPath, webpackConfigFileName) { const files = fileNames .map(fileName => path.join(extensionPath, fileName)) .map(filePath => new File({ - path: filePath, - stat: fs.statSync(filePath), - base: extensionPath, - contents: fs.createReadStream(filePath) - })); + path: filePath, + stat: fs.statSync(filePath), + base: extensionPath, + contents: fs.createReadStream(filePath) + })); // check for a webpack configuration files, then invoke webpack // and merge its output with the files stream. const webpackConfigLocations = glob.sync(path.join(extensionPath, '**', webpackConfigFileName), { ignore: ['**/node_modules'] }); @@ -123,20 +123,20 @@ function fromLocalWebpack(extensionPath, webpackConfigFileName) { const relativeOutputPath = path.relative(extensionPath, webpackConfig.output.path); return webpackGulp(webpackConfig, webpack, webpackDone) .pipe(es.through(function (data) { - data.stat = data.stat || {}; - data.base = extensionPath; - this.emit('data', data); - })) + data.stat = data.stat || {}; + data.base = extensionPath; + this.emit('data', data); + })) .pipe(es.through(function (data) { - // source map handling: - // * rewrite sourceMappingURL - // * save to disk so that upload-task picks this up - const contents = data.contents.toString('utf8'); - data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { - return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; - }), 'utf8'); - this.emit('data', data); - })); + // source map handling: + // * rewrite sourceMappingURL + // * save to disk so that upload-task picks this up + const contents = data.contents.toString('utf8'); + data.contents = Buffer.from(contents.replace(/\n\/\/# sourceMappingURL=(.*)$/gm, function (_m, g1) { + return `\n//# sourceMappingURL=${sourceMappingURLBase}/extensions/${path.basename(extensionPath)}/${relativeOutputPath}/${g1}`; + }), 'utf8'); + this.emit('data', data); + })); }); }); es.merge(...webpackStreams, es.readArray(files)) @@ -158,16 +158,16 @@ function fromLocalNormal(extensionPath) { const result = es.through(); vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn }) .then(fileNames => { - const files = fileNames - .map(fileName => path.join(extensionPath, fileName)) - .map(filePath => new File({ - path: filePath, - stat: fs.statSync(filePath), - base: extensionPath, - contents: fs.createReadStream(filePath) - })); - es.readArray(files).pipe(result); - }) + const files = fileNames + .map(fileName => path.join(extensionPath, fileName)) + .map(filePath => new File({ + path: filePath, + stat: fs.statSync(filePath), + base: extensionPath, + contents: fs.createReadStream(filePath) + })); + es.readArray(files).pipe(result); + }) .catch(err => result.emit('error', err)); return result.pipe((0, stats_1.createStatsStream)(path.basename(extensionPath))); } @@ -324,11 +324,11 @@ function isWebExtension(manifest) { function packageLocalExtensionsStream(forWeb) { const localExtensionsDescriptions = (glob.sync('extensions/*/package.json') .map(manifestPath => { - const absoluteManifestPath = path.join(root, manifestPath); - const extensionPath = path.dirname(path.join(root, manifestPath)); - const extensionName = path.basename(extensionPath); - return { name: extensionName, path: extensionPath, manifestPath: absoluteManifestPath }; - }) + const absoluteManifestPath = path.join(root, manifestPath); + const extensionPath = path.dirname(path.join(root, manifestPath)); + const extensionName = path.basename(extensionPath); + return { name: extensionName, path: extensionPath, manifestPath: absoluteManifestPath }; + }) .filter(({ name }) => excludedExtensions.indexOf(name) === -1) .filter(({ name }) => builtInExtensions.every(b => b.name !== name)) .filter(({ name }) => externalExtensions.indexOf(name) === -1) // {{SQL CARBON EDIT}} Remove external Extensions with separate package @@ -359,15 +359,15 @@ function packageMarketplaceExtensionsStream(forWeb, galleryServiceUrl) { ]; const marketplaceExtensionsStream = minifyExtensionResources(es.merge(...marketplaceExtensionsDescriptions .map(extension => { - const input = (galleryServiceUrl ? fromMarketplace(galleryServiceUrl, extension) : fromGithub(extension)) - .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); - return updateExtensionPackageJSON(input, (data) => { - delete data.scripts; - delete data.dependencies; - delete data.devDependencies; - return data; - }); - }))); + const input = (galleryServiceUrl ? fromMarketplace(galleryServiceUrl, extension) : fromGithub(extension)) + .pipe(rename(p => p.dirname = `extensions/${extension.name}/${p.dirname}`)); + return updateExtensionPackageJSON(input, (data) => { + delete data.scripts; + delete data.dependencies; + delete data.devDependencies; + return data; + }); + }))); return (marketplaceExtensionsStream .pipe(util2.setExecutableBit(['**/*.sh']))); } @@ -384,7 +384,7 @@ function scanBuiltinExtensions(extensionsRoot, exclude = []) { if (!fs.existsSync(packageJSONPath)) { continue; } - const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); + let packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); if (!isWebExtension(packageJSON)) { continue; } @@ -412,10 +412,10 @@ exports.scanBuiltinExtensions = scanBuiltinExtensions; function packageExternalExtensionsStream() { const extenalExtensionDescriptions = glob.sync('extensions/*/package.json') .map(manifestPath => { - const extensionPath = path.dirname(path.join(root, manifestPath)); - const extensionName = path.basename(extensionPath); - return { name: extensionName, path: extensionPath }; - }) + const extensionPath = path.dirname(path.join(root, manifestPath)); + const extensionName = path.basename(extensionPath); + return { name: extensionName, path: extensionPath }; + }) .filter(({ name }) => externalExtensions.indexOf(name) >= 0 || exports.vscodeExternalExtensions.indexOf(name) >= 0); const builtExtensions = extenalExtensionDescriptions.map(extension => { return fromLocal(extension.path, false) @@ -433,10 +433,10 @@ exports.cleanRebuildExtensions = cleanRebuildExtensions; function packageRebuildExtensionsStream() { const extenalExtensionDescriptions = glob.sync('extensions/*/package.json') .map(manifestPath => { - const extensionPath = path.dirname(path.join(root, manifestPath)); - const extensionName = path.basename(extensionPath); - return { name: extensionName, path: extensionPath }; - }) + const extensionPath = path.dirname(path.join(root, manifestPath)); + const extensionName = path.basename(extensionPath); + return { name: extensionName, path: extensionPath }; + }) .filter(({ name }) => rebuildExtensions.indexOf(name) >= 0); const builtExtensions = extenalExtensionDescriptions.map(extension => { return fromLocal(extension.path, false) @@ -450,7 +450,7 @@ function translatePackageJSON(packageJSON, packageNLSPath) { const CharCode_PC = '%'.charCodeAt(0); const packageNls = JSON.parse(fs.readFileSync(packageNLSPath).toString()); const translate = (obj) => { - for (const key in obj) { + for (let key in obj) { const val = obj[key]; if (Array.isArray(val)) { val.forEach(translate); @@ -477,7 +477,6 @@ const esbuildMediaScripts = [ 'markdown-language-features/esbuild-preview.js', 'markdown-math/esbuild.js', 'notebook-renderers/esbuild.js', - 'ipynb/esbuild.js', 'simple-browser/esbuild-preview.js', ]; async function webpackExtensions(taskName, isWatch, webpackConfigLocations) { diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 60f8d9ccef..e3639249f8 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -9,7 +9,7 @@ import * as cp from 'child_process'; import * as glob from 'glob'; import * as gulp from 'gulp'; import * as path from 'path'; -import * as through2 from 'through2' +import * as through2 from 'through2'; import got from 'got'; import { Stream } from 'stream'; import * as File from 'vinyl'; @@ -285,7 +285,6 @@ const excludedExtensions = [ 'ms-vscode.node-debug', 'ms-vscode.node-debug2', 'vscode-custom-editor-tests', - 'vscode-notebook-tests', 'integration-tests', // {{SQL CARBON EDIT}} ]; @@ -477,7 +476,7 @@ export function scanBuiltinExtensions(extensionsRoot: string, exclude: string[] if (!fs.existsSync(packageJSONPath)) { continue; } - const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); + let packageJSON = JSON.parse(fs.readFileSync(packageJSONPath).toString('utf8')); if (!isWebExtension(packageJSON)) { continue; } @@ -550,7 +549,7 @@ export function translatePackageJSON(packageJSON: string, packageNLSPath: string const CharCode_PC = '%'.charCodeAt(0); const packageNls: NLSFormat = JSON.parse(fs.readFileSync(packageNLSPath).toString()); const translate = (obj: any) => { - for (const key in obj) { + for (let key in obj) { const val = obj[key]; if (Array.isArray(val)) { val.forEach(translate); @@ -576,7 +575,6 @@ const esbuildMediaScripts = [ 'markdown-language-features/esbuild-preview.js', 'markdown-math/esbuild.js', 'notebook-renderers/esbuild.js', - 'ipynb/esbuild.js', 'simple-browser/esbuild-preview.js', ]; @@ -590,7 +588,7 @@ export async function webpackExtensions(taskName: string, isWatch: boolean, webp function addConfig(configOrFn: webpack.Configuration | Function) { let config; if (typeof configOrFn === 'function') { - config = (configOrFn as Function)({}, {}); + config = configOrFn({}, {}); webpackConfigs.push(config); } else { config = configOrFn; diff --git a/build/lib/git.js b/build/lib/git.js index 0bdd2f247e..b3624674fa 100644 --- a/build/lib/git.js +++ b/build/lib/git.js @@ -1,10 +1,10 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getVersion = void 0; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getVersion = void 0; const path = require("path"); const fs = require("fs"); /** @@ -45,7 +45,7 @@ function getVersion(repo) { } const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm; let refsMatch; - const refs = {}; + let refs = {}; while (refsMatch = refsRegex.exec(refsRaw)) { refs[refsMatch[2]] = refsMatch[1]; } diff --git a/build/lib/git.ts b/build/lib/git.ts index 5e6e4d3dea..366d642626 100644 --- a/build/lib/git.ts +++ b/build/lib/git.ts @@ -2,6 +2,8 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as path from 'path'; import * as fs from 'fs'; @@ -49,7 +51,7 @@ export function getVersion(repo: string): string | undefined { const refsRegex = /^([0-9a-f]{40})\s+(.+)$/gm; let refsMatch: RegExpExecArray | null; - const refs: { [ref: string]: string } = {}; + let refs: { [ref: string]: string } = {}; while (refsMatch = refsRegex.exec(refsRaw)) { refs[refsMatch[2]] = refsMatch[1]; diff --git a/build/lib/i18n.js b/build/lib/i18n.js index 51cf249847..74fcbc4ba4 100644 --- a/build/lib/i18n.js +++ b/build/lib/i18n.js @@ -46,7 +46,7 @@ exports.externalExtensionsWithTranslations = { var LocalizeInfo; (function (LocalizeInfo) { function is(value) { - const candidate = value; + let candidate = value; return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(element => Is.string(element)))); } LocalizeInfo.is = is; @@ -57,8 +57,8 @@ var BundledFormat; if (Is.undef(value)) { return false; } - const candidate = value; - const length = Object.keys(value).length; + let candidate = value; + let length = Object.keys(value).length; return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles); } BundledFormat.is = is; @@ -70,7 +70,7 @@ var PackageJsonFormat; return false; } return Object.keys(value).every(key => { - const element = value[key]; + let element = value[key]; return Is.string(element) || (Is.object(element) && Is.defined(element.message) && Is.defined(element.comment)); }); } @@ -133,9 +133,9 @@ class XLF { } this.numberOfMessages += keys.length; this.files[original] = []; - const existingKeys = new Set(); + let existingKeys = new Set(); for (let i = 0; i < keys.length; i++) { - const key = keys[i]; + let key = keys[i]; let realKey; let comment; if (Is.string(key)) { @@ -152,7 +152,7 @@ class XLF { continue; } existingKeys.add(realKey); - const message = encodeEntities(messages[i]); + let message = encodeEntities(messages[i]); this.files[original].push({ id: realKey, message: message, comment: comment }); } } @@ -178,7 +178,7 @@ class XLF { this.appendNewLine('', 0); } appendNewLine(content, indent) { - const line = new Line(indent); + let line = new Line(indent); line.append(content); this.buffer.push(line.toString()); } @@ -186,8 +186,8 @@ class XLF { exports.XLF = XLF; XLF.parsePseudo = function (xlfString) { return new Promise((resolve) => { - const parser = new xml2js.Parser(); - const files = []; + let parser = new xml2js.Parser(); + let files = []; parser.parseString(xlfString, function (_err, result) { const fileNodes = result['xliff']['file']; fileNodes.forEach(file => { @@ -211,8 +211,8 @@ XLF.parsePseudo = function (xlfString) { }; XLF.parse = function (xlfString) { return new Promise((resolve, reject) => { - const parser = new xml2js.Parser(); - const files = []; + let parser = new xml2js.Parser(); + let files = []; parser.parseString(xlfString, function (err, result) { if (err) { reject(new Error(`XLF parsing error: Failed to parse XLIFF string. ${err}`)); @@ -226,7 +226,7 @@ XLF.parse = function (xlfString) { if (!originalFilePath) { reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); } - const language = file.$['target-language']; + let language = file.$['target-language']; if (!language) { reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); } @@ -295,10 +295,9 @@ function stripComments(content) { // Second group matches a single quoted string // Third group matches a multi line comment // Forth group matches a single line comment - // Fifth group matches a trailing comma - const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))|(,\s*[}\]])/g; - const result = content.replace(regexp, (match, _m1, _m2, m3, m4, m5) => { - // Only one of m1, m2, m3, m4, m5 matches + const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; + let result = content.replace(regexp, (match, _m1, _m2, m3, m4) => { + // Only one of m1, m2, m3, m4 matches if (m3) { // A block comment. Replace with nothing return ''; @@ -314,10 +313,6 @@ function stripComments(content) { return ''; } } - else if (m5) { - // Remove the trailing comma - return match.substring(1); - } else { // We match a string return match; @@ -361,20 +356,20 @@ function escapeCharacters(value) { return result.join(''); } function processCoreBundleFormat(fileHeader, languages, json, emitter) { - const keysSection = json.keys; - const messageSection = json.messages; - const bundleSection = json.bundles; - const statistics = Object.create(null); - const defaultMessages = Object.create(null); - const modules = Object.keys(keysSection); + let keysSection = json.keys; + let messageSection = json.messages; + let bundleSection = json.bundles; + let statistics = Object.create(null); + let defaultMessages = Object.create(null); + let modules = Object.keys(keysSection); modules.forEach((module) => { - const keys = keysSection[module]; - const messages = messageSection[module]; + let keys = keysSection[module]; + let messages = messageSection[module]; if (!messages || keys.length !== messages.length) { emitter.emit('error', `Message for module ${module} corrupted. Mismatch in number of keys and messages.`); return; } - const messageMap = Object.create(null); + let messageMap = Object.create(null); defaultMessages[module] = messageMap; keys.map((key, i) => { if (typeof key === 'string') { @@ -385,27 +380,27 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) { } }); }); - const languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n'); + let languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n'); if (!fs.existsSync(languageDirectory)) { log(`No VS Code localization repository found. Looking at ${languageDirectory}`); log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); } - const sortedLanguages = sortLanguages(languages); + let sortedLanguages = sortLanguages(languages); sortedLanguages.forEach((language) => { if (process.env['VSCODE_BUILD_VERBOSE']) { log(`Generating nls bundles for: ${language.id}`); } statistics[language.id] = 0; - const localizedModules = Object.create(null); - const languageFolderName = language.translationId || language.id; - const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); + let localizedModules = Object.create(null); + let languageFolderName = language.translationId || language.id; + let i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); let allMessages; if (fs.existsSync(i18nFile)) { - const content = stripComments(fs.readFileSync(i18nFile, 'utf8')); + let content = stripComments(fs.readFileSync(i18nFile, 'utf8')); allMessages = JSON.parse(content); } modules.forEach((module) => { - const order = keysSection[module]; + let order = keysSection[module]; let moduleMessage; if (allMessages) { moduleMessage = allMessages.contents[module]; @@ -417,7 +412,7 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) { moduleMessage = defaultMessages[module]; statistics[language.id] = statistics[language.id] + Object.keys(moduleMessage).length; } - const localizedMessages = []; + let localizedMessages = []; order.forEach((keyInfo) => { let key = null; if (typeof keyInfo === 'string') { @@ -439,14 +434,14 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) { localizedModules[module] = localizedMessages; }); Object.keys(bundleSection).forEach((bundle) => { - const modules = bundleSection[bundle]; - const contents = [ + let modules = bundleSection[bundle]; + let contents = [ fileHeader, `define("${bundle}.nls.${language.id}", {` ]; modules.forEach((module, index) => { contents.push(`\t"${module}": [`); - const messages = localizedModules[module]; + let messages = localizedModules[module]; if (!messages) { emitter.emit('error', `Didn't find messages for module ${module}.`); return; @@ -461,11 +456,11 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) { }); }); Object.keys(statistics).forEach(key => { - const value = statistics[key]; + let value = statistics[key]; log(`${key} has ${value} untranslated strings.`); }); sortedLanguages.forEach(language => { - const stats = statistics[language.id]; + let stats = statistics[language.id]; if (Is.undef(stats)) { log(`\tNo translations found for language ${language.id}. Using default language instead.`); } @@ -473,7 +468,7 @@ function processCoreBundleFormat(fileHeader, languages, json, emitter) { } function processNlsFiles(opts) { return (0, event_stream_1.through)(function (file) { - const fileName = path.basename(file.path); + let fileName = path.basename(file.path); if (fileName === 'nls.metadata.json') { let json = null; if (file.isBuffer()) { @@ -559,7 +554,7 @@ function createXlfFilesForCoreBundle() { xlf.addFile(`src/${coreModule}`, keys, messages); } } - for (const resource in xlfs) { + for (let resource in xlfs) { const xlf = xlfs[resource]; const filePath = `${xlf.project}/${resource.replace(/\//g, '_')}.xlf`; const xlfFile = new File({ @@ -591,7 +586,7 @@ function createXlfFilesForExtensions() { if (!stat.isDirectory()) { return; } - const extensionName = path.basename(extensionFolder.path); + let extensionName = path.basename(extensionFolder.path); if (extensionName === 'node_modules') { return; } @@ -609,24 +604,17 @@ function createXlfFilesForExtensions() { const basename = path.basename(file.path); if (basename === 'package.nls.json') { const json = JSON.parse(buffer.toString('utf8')); - const keys = []; - const messages = []; - Object.keys(json).forEach((key) => { + const keys = Object.keys(json); + const messages = keys.map((key) => { const value = json[key]; if (Is.string(value)) { - keys.push(key); - messages.push(value); + return value; } else if (value) { - keys.push({ - key, - comment: value.comment - }); - messages.push(value.message); + return value.message; } else { - keys.push(key); - messages.push(`Unknown message for key: ${key}`); + return `Unknown message for key: ${key}`; } }); getXlf().addFile(`extensions/${extensionName}/package`, keys, messages); @@ -634,7 +622,7 @@ function createXlfFilesForExtensions() { else if (basename === 'nls.metadata.json') { const json = JSON.parse(buffer.toString('utf8')); const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path)); - for (const file in json) { + for (let file in json) { const fileContent = json[file]; getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages); } @@ -646,7 +634,7 @@ function createXlfFilesForExtensions() { } }, function () { if (_xlf) { - const xlfFile = new File({ + let xlfFile = new File({ path: path.join(extensionsProject, extensionName + '.xlf'), contents: Buffer.from(_xlf.toString(), 'utf8') }); @@ -678,14 +666,14 @@ function createXlfFilesForIsl() { else { throw new Error(`Unknown input file ${file.path}`); } - const xlf = new XLF(projectName), keys = [], messages = []; - const model = new TextModel(file.contents.toString()); + let xlf = new XLF(projectName), keys = [], messages = []; + let model = new TextModel(file.contents.toString()); let inMessageSection = false; model.lines.forEach(line => { if (line.length === 0) { return; } - const firstChar = line.charAt(0); + let firstChar = line.charAt(0); switch (firstChar) { case ';': // Comment line; @@ -697,13 +685,13 @@ function createXlfFilesForIsl() { if (!inMessageSection) { return; } - const sections = line.split('='); + let sections = line.split('='); if (sections.length !== 2) { throw new Error(`Badly formatted message found: ${line}`); } else { - const key = sections[0]; - const value = sections[1]; + let key = sections[0]; + let value = sections[1]; if (key.length > 0 && value.length > 0) { keys.push(key); messages.push(value); @@ -720,8 +708,8 @@ function createXlfFilesForIsl() { } exports.createXlfFilesForIsl = createXlfFilesForIsl; function pushXlfFiles(apiHostname, username, password) { - const tryGetPromises = []; - const updateCreatePromises = []; + let tryGetPromises = []; + let updateCreatePromises = []; return (0, event_stream_1.through)(function (file) { const project = path.dirname(file.relative); const fileName = path.basename(file.path); @@ -759,11 +747,11 @@ function getAllResources(project, apiHostname, username, password) { method: 'GET' }; const request = https.request(options, (res) => { - const buffer = []; + let buffer = []; res.on('data', (chunk) => buffer.push(chunk)); res.on('end', () => { if (res.statusCode === 200) { - const json = JSON.parse(Buffer.concat(buffer).toString()); + let json = JSON.parse(Buffer.concat(buffer).toString()); if (Array.isArray(json)) { resolve(json.map(o => o.slug)); return; @@ -782,7 +770,7 @@ function getAllResources(project, apiHostname, username, password) { }); } function findObsoleteResources(apiHostname, username, password) { - const resourcesByProject = Object.create(null); + let resourcesByProject = Object.create(null); resourcesByProject[extensionsProject] = [].concat(exports.externalExtensionsWithTranslations); // clone return (0, event_stream_1.through)(function (file) { const project = path.dirname(file.relative); @@ -796,10 +784,10 @@ function findObsoleteResources(apiHostname, username, password) { this.push(file); }, function () { const json = JSON.parse(fs.readFileSync('./build/lib/i18n.resources.json', 'utf8')); - const i18Resources = [...json.editor, ...json.workbench].map((r) => r.project + '/' + r.name.replace(/\//g, '_')); - const extractedResources = []; - for (const project of [workbenchProject, editorProject]) { - for (const resource of resourcesByProject[project]) { + let i18Resources = [...json.editor, ...json.workbench].map((r) => r.project + '/' + r.name.replace(/\//g, '_')); + let extractedResources = []; + for (let project of [workbenchProject, editorProject]) { + for (let resource of resourcesByProject[project]) { if (resource !== 'setup_messages') { extractedResources.push(project + '/' + resource); } @@ -809,11 +797,11 @@ function findObsoleteResources(apiHostname, username, password) { console.log(`[i18n] Obsolete resources in file 'build/lib/i18n.resources.json': JSON.stringify(${i18Resources.filter(p => extractedResources.indexOf(p) === -1)})`); console.log(`[i18n] Missing resources in file 'build/lib/i18n.resources.json': JSON.stringify(${extractedResources.filter(p => i18Resources.indexOf(p) === -1)})`); } - const promises = []; - for (const project in resourcesByProject) { + let promises = []; + for (let project in resourcesByProject) { promises.push(getAllResources(project, apiHostname, username, password).then(resources => { - const expectedResources = resourcesByProject[project]; - const unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1); + let expectedResources = resourcesByProject[project]; + let unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1); if (unusedResources.length) { console.log(`[transifex] Obsolete resources in project '${project}': ${unusedResources.join(', ')}`); } @@ -868,7 +856,7 @@ function createResource(project, slug, xlfFile, apiHostname, credentials) { auth: credentials, method: 'POST' }; - const request = https.request(options, (res) => { + let request = https.request(options, (res) => { if (res.statusCode === 201) { log(`Resource ${project}/${slug} successfully created on Transifex.`); } @@ -900,7 +888,7 @@ function updateResource(project, slug, xlfFile, apiHostname, credentials) { auth: credentials, method: 'PUT' }; - const request = https.request(options, (res) => { + let request = https.request(options, (res) => { if (res.statusCode === 200) { res.setEncoding('utf8'); let responseBuffer = ''; @@ -925,7 +913,7 @@ function updateResource(project, slug, xlfFile, apiHostname, credentials) { }); } function pullSetupXlfFiles(apiHostname, username, password, language, includeDefault) { - const setupResources = [{ name: 'setup_messages', project: workbenchProject }]; + let setupResources = [{ name: 'setup_messages', project: workbenchProject }]; if (includeDefault) { setupResources.push({ name: 'setup_default', project: setupProject }); } @@ -934,7 +922,7 @@ function pullSetupXlfFiles(apiHostname, username, password, language, includeDef exports.pullSetupXlfFiles = pullSetupXlfFiles; function pullXlfFiles(apiHostname, username, password, language, resources) { const credentials = `${username}:${password}`; - const expectedTranslationsCount = resources.length; + let expectedTranslationsCount = resources.length; let translationsRetrieved = 0, called = false; return (0, event_stream_1.readable)(function (_count, callback) { // Mark end of stream when all resources were retrieved @@ -961,7 +949,7 @@ function retrieveResource(language, resource, apiHostname, credentials) { return limiter.queue(() => new Promise((resolve, reject) => { const slug = resource.name.replace(/\//g, '_'); const project = resource.project; - const transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id; + let transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id; const options = { hostname: apiHostname, path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`, @@ -970,8 +958,8 @@ function retrieveResource(language, resource, apiHostname, credentials) { method: 'GET' }; console.log('[transifex] Fetching ' + options.path); - const request = https.request(options, (res) => { - const xlfBuffer = []; + let request = https.request(options, (res) => { + let xlfBuffer = []; res.on('data', (chunk) => xlfBuffer.push(chunk)); res.on('end', () => { if (res.statusCode === 200) { @@ -993,14 +981,14 @@ function retrieveResource(language, resource, apiHostname, credentials) { })); } function prepareI18nFiles() { - const parsePromises = []; + let parsePromises = []; return (0, event_stream_1.through)(function (xlf) { - const stream = this; - const parsePromise = XLF.parse(xlf.contents.toString()); + let stream = this; + let parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then(resolvedFiles => { resolvedFiles.forEach(file => { - const translatedFile = createI18nFile(file.originalFilePath, file.messages); + let translatedFile = createI18nFile(file.originalFilePath, file.messages); stream.queue(translatedFile); }); }); @@ -1012,7 +1000,7 @@ function prepareI18nFiles() { } exports.prepareI18nFiles = prepareI18nFiles; function createI18nFile(originalFilePath, messages) { - const result = Object.create(null); + let result = Object.create(null); result[''] = [ '--------------------------------------------------------------------------------------------', 'Copyright (c) Microsoft Corporation. All rights reserved.', @@ -1020,7 +1008,7 @@ function createI18nFile(originalFilePath, messages) { '--------------------------------------------------------------------------------------------', 'Do not edit this file. It is machine generated.' ]; - for (const key of Object.keys(messages)) { + for (let key of Object.keys(messages)) { result[key] = messages[key]; } let content = JSON.stringify(result, null, '\t'); @@ -1080,7 +1068,7 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse const translatedMainFile = createI18nFile('./main', mainPack); resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); this.queue(translatedMainFile); - for (const extension in extensionsPacks) { + for (let extension in extensionsPacks) { const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]); this.queue(translatedExtFile); const externalExtensionId = externalExtensions[extension]; @@ -1100,14 +1088,14 @@ function prepareI18nPackFiles(externalExtensions, resultingTranslationPaths, pse } exports.prepareI18nPackFiles = prepareI18nPackFiles; function prepareIslFiles(language, innoSetupConfig) { - const parsePromises = []; + let parsePromises = []; return (0, event_stream_1.through)(function (xlf) { - const stream = this; - const parsePromise = XLF.parse(xlf.contents.toString()); + let stream = this; + let parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then(resolvedFiles => { resolvedFiles.forEach(file => { - const translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig); + let translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig); stream.queue(translatedFile); }); }).catch(reason => { @@ -1123,7 +1111,7 @@ function prepareIslFiles(language, innoSetupConfig) { } exports.prepareIslFiles = prepareIslFiles; function createIslFile(originalFilePath, messages, language, innoSetup) { - const content = []; + let content = []; let originalContent; if (path.basename(originalFilePath) === 'Default') { originalContent = new TextModel(fs.readFileSync(originalFilePath + '.isl', 'utf8')); @@ -1133,16 +1121,16 @@ function createIslFile(originalFilePath, messages, language, innoSetup) { } originalContent.lines.forEach(line => { if (line.length > 0) { - const firstChar = line.charAt(0); + let firstChar = line.charAt(0); if (firstChar === '[' || firstChar === ';') { content.push(line); } else { - const sections = line.split('='); - const key = sections[0]; + let sections = line.split('='); + let key = sections[0]; let translated = line; if (key) { - const translatedMessage = messages[key]; + let translatedMessage = messages[key]; if (translatedMessage) { translated = `${key}=${translatedMessage}`; } @@ -1160,9 +1148,9 @@ function createIslFile(originalFilePath, messages, language, innoSetup) { }); } function encodeEntities(value) { - const result = []; + let result = []; for (let i = 0; i < value.length; i++) { - const ch = value[i]; + let ch = value[i]; switch (ch) { case '<': result.push('<'); diff --git a/build/lib/i18n.resources.json b/build/lib/i18n.resources.json index dd949e618f..06bfbb2b50 100644 --- a/build/lib/i18n.resources.json +++ b/build/lib/i18n.resources.json @@ -119,11 +119,7 @@ "project": "vscode-workbench" }, { - "name": "vs/workbench/contrib/mergeEditor", - "project": "vscode-workbench" - }, - { - "name": "vs/workbench/contrib/localization", + "name": "vs/workbench/contrib/localizations", "project": "vscode-workbench" }, { @@ -278,10 +274,6 @@ "name": "vs/workbench/contrib/userDataSync", "project": "vscode-workbench" }, - { - "name": "vs/workbench/contrib/editSessions", - "project": "vscode-workbench" - }, { "name": "vs/workbench/contrib/views", "project": "vscode-workbench" @@ -294,14 +286,6 @@ "name": "vs/workbench/contrib/audioCues", "project": "vscode-workbench" }, - { - "name": "vs/workbench/contrib/deprecatedExtensionMigrator", - "project": "vscode-workbench" - }, - { - "name": "vs/workbench/contrib/bracketPairColorizer2Telemetry", - "project": "vscode-workbench" - }, { "name": "vs/workbench/contrib/offline", "project": "vscode-workbench" @@ -438,10 +422,6 @@ "name": "vs/workbench/services/userDataSync", "project": "vscode-workbench" }, - { - "name": "vs/workbench/services/editSessions", - "project": "vscode-workbench" - }, { "name": "vs/workbench/services/views", "project": "vscode-workbench" @@ -471,11 +451,11 @@ "project": "vscode-workbench" }, { - "name": "vs/workbench/contrib/userDataProfile", + "name": "vs/workbench/contrib/profiles", "project": "vscode-profiles" }, { - "name": "vs/workbench/services/userDataProfile", + "name": "vs/workbench/services/profiles", "project": "vscode-profiles" } ] diff --git a/build/lib/i18n.ts b/build/lib/i18n.ts index df146393b9..b303820cc2 100644 --- a/build/lib/i18n.ts +++ b/build/lib/i18n.ts @@ -87,7 +87,7 @@ interface LocalizeInfo { module LocalizeInfo { export function is(value: any): value is LocalizeInfo { - const candidate = value as LocalizeInfo; + let candidate = value as LocalizeInfo; return Is.defined(candidate) && Is.string(candidate.key) && (Is.undef(candidate.comment) || (Is.array(candidate.comment) && candidate.comment.every(element => Is.string(element)))); } } @@ -104,8 +104,8 @@ module BundledFormat { return false; } - const candidate = value as BundledFormat; - const length = Object.keys(value).length; + let candidate = value as BundledFormat; + let length = Object.keys(value).length; return length === 3 && Is.defined(candidate.keys) && Is.defined(candidate.messages) && Is.defined(candidate.bundles); } @@ -126,7 +126,7 @@ module PackageJsonFormat { return false; } return Object.keys(value).every(key => { - const element = value[key]; + let element = value[key]; return Is.string(element) || (Is.object(element) && Is.defined(element.message) && Is.defined(element.comment)); }); } @@ -218,9 +218,9 @@ export class XLF { } this.numberOfMessages += keys.length; this.files[original] = []; - const existingKeys = new Set(); + let existingKeys = new Set(); for (let i = 0; i < keys.length; i++) { - const key = keys[i]; + let key = keys[i]; let realKey: string | undefined; let comment: string | undefined; if (Is.string(key)) { @@ -236,7 +236,7 @@ export class XLF { continue; } existingKeys.add(realKey); - const message: string = encodeEntities(messages[i]); + let message: string = encodeEntities(messages[i]); this.files[original].push({ id: realKey, message: message, comment: comment }); } } @@ -269,15 +269,15 @@ export class XLF { } private appendNewLine(content: string, indent?: number): void { - const line = new Line(indent); + let line = new Line(indent); line.append(content); this.buffer.push(line.toString()); } static parsePseudo = function (xlfString: string): Promise { return new Promise((resolve) => { - const parser = new xml2js.Parser(); - const files: { messages: Map; originalFilePath: string; language: string }[] = []; + let parser = new xml2js.Parser(); + let files: { messages: Map; originalFilePath: string; language: string }[] = []; parser.parseString(xlfString, function (_err: any, result: any) { const fileNodes: any[] = result['xliff']['file']; fileNodes.forEach(file => { @@ -302,9 +302,9 @@ export class XLF { static parse = function (xlfString: string): Promise { return new Promise((resolve, reject) => { - const parser = new xml2js.Parser(); + let parser = new xml2js.Parser(); - const files: { messages: Map; originalFilePath: string; language: string }[] = []; + let files: { messages: Map; originalFilePath: string; language: string }[] = []; parser.parseString(xlfString, function (err: any, result: any) { if (err) { @@ -321,7 +321,7 @@ export class XLF { if (!originalFilePath) { reject(new Error(`XLF parsing error: XLIFF file node does not contain original attribute to determine the original location of the resource file.`)); } - const language = file.$['target-language']; + let language = file.$['target-language']; if (!language) { reject(new Error(`XLF parsing error: XLIFF file node does not contain target-language attribute to determine translated language.`)); } @@ -412,10 +412,9 @@ function stripComments(content: string): string { // Second group matches a single quoted string // Third group matches a multi line comment // Forth group matches a single line comment - // Fifth group matches a trailing comma - const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))|(,\s*[}\]])/g; - const result = content.replace(regexp, (match, _m1: string, _m2: string, m3: string, m4: string, m5: string) => { - // Only one of m1, m2, m3, m4, m5 matches + const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; + let result = content.replace(regexp, (match, _m1: string, _m2: string, m3: string, m4: string) => { + // Only one of m1, m2, m3, m4 matches if (m3) { // A block comment. Replace with nothing return ''; @@ -428,9 +427,6 @@ function stripComments(content: string): string { } else { return ''; } - } else if (m5) { - // Remove the trailing comma - return match.substring(1); } else { // We match a string return match; @@ -476,22 +472,22 @@ function escapeCharacters(value: string): string { } function processCoreBundleFormat(fileHeader: string, languages: Language[], json: BundledFormat, emitter: ThroughStream) { - const keysSection = json.keys; - const messageSection = json.messages; - const bundleSection = json.bundles; + let keysSection = json.keys; + let messageSection = json.messages; + let bundleSection = json.bundles; - const statistics: Map = Object.create(null); + let statistics: Map = Object.create(null); - const defaultMessages: Map> = Object.create(null); - const modules = Object.keys(keysSection); + let defaultMessages: Map> = Object.create(null); + let modules = Object.keys(keysSection); modules.forEach((module) => { - const keys = keysSection[module]; - const messages = messageSection[module]; + let keys = keysSection[module]; + let messages = messageSection[module]; if (!messages || keys.length !== messages.length) { emitter.emit('error', `Message for module ${module} corrupted. Mismatch in number of keys and messages.`); return; } - const messageMap: Map = Object.create(null); + let messageMap: Map = Object.create(null); defaultMessages[module] = messageMap; keys.map((key, i) => { if (typeof key === 'string') { @@ -502,28 +498,28 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json }); }); - const languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n'); + let languageDirectory = path.join(__dirname, '..', '..', '..', 'vscode-loc', 'i18n'); if (!fs.existsSync(languageDirectory)) { log(`No VS Code localization repository found. Looking at ${languageDirectory}`); log(`To bundle translations please check out the vscode-loc repository as a sibling of the vscode repository.`); } - const sortedLanguages = sortLanguages(languages); + let sortedLanguages = sortLanguages(languages); sortedLanguages.forEach((language) => { if (process.env['VSCODE_BUILD_VERBOSE']) { log(`Generating nls bundles for: ${language.id}`); } statistics[language.id] = 0; - const localizedModules: Map = Object.create(null); - const languageFolderName = language.translationId || language.id; - const i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); + let localizedModules: Map = Object.create(null); + let languageFolderName = language.translationId || language.id; + let i18nFile = path.join(languageDirectory, `vscode-language-pack-${languageFolderName}`, 'translations', 'main.i18n.json'); let allMessages: I18nFormat | undefined; if (fs.existsSync(i18nFile)) { - const content = stripComments(fs.readFileSync(i18nFile, 'utf8')); + let content = stripComments(fs.readFileSync(i18nFile, 'utf8')); allMessages = JSON.parse(content); } modules.forEach((module) => { - const order = keysSection[module]; + let order = keysSection[module]; let moduleMessage: { [messageKey: string]: string } | undefined; if (allMessages) { moduleMessage = allMessages.contents[module]; @@ -535,7 +531,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json moduleMessage = defaultMessages[module]; statistics[language.id] = statistics[language.id] + Object.keys(moduleMessage).length; } - const localizedMessages: string[] = []; + let localizedMessages: string[] = []; order.forEach((keyInfo) => { let key: string | null = null; if (typeof keyInfo === 'string') { @@ -556,14 +552,14 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json localizedModules[module] = localizedMessages; }); Object.keys(bundleSection).forEach((bundle) => { - const modules = bundleSection[bundle]; - const contents: string[] = [ + let modules = bundleSection[bundle]; + let contents: string[] = [ fileHeader, `define("${bundle}.nls.${language.id}", {` ]; modules.forEach((module, index) => { contents.push(`\t"${module}": [`); - const messages = localizedModules[module]; + let messages = localizedModules[module]; if (!messages) { emitter.emit('error', `Didn't find messages for module ${module}.`); return; @@ -578,11 +574,11 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json }); }); Object.keys(statistics).forEach(key => { - const value = statistics[key]; + let value = statistics[key]; log(`${key} has ${value} untranslated strings.`); }); sortedLanguages.forEach(language => { - const stats = statistics[language.id]; + let stats = statistics[language.id]; if (Is.undef(stats)) { log(`\tNo translations found for language ${language.id}. Using default language instead.`); } @@ -591,7 +587,7 @@ function processCoreBundleFormat(fileHeader: string, languages: Language[], json export function processNlsFiles(opts: { fileHeader: string; languages: Language[] }): ThroughStream { return through(function (this: ThroughStream, file: File) { - const fileName = path.basename(file.path); + let fileName = path.basename(file.path); if (fileName === 'nls.metadata.json') { let json = null; if (file.isBuffer()) { @@ -678,7 +674,7 @@ export function createXlfFilesForCoreBundle(): ThroughStream { xlf.addFile(`src/${coreModule}`, keys, messages); } } - for (const resource in xlfs) { + for (let resource in xlfs) { const xlf = xlfs[resource]; const filePath = `${xlf.project}/${resource.replace(/\//g, '_')}.xlf`; const xlfFile = new File({ @@ -708,7 +704,7 @@ export function createXlfFilesForExtensions(): ThroughStream { if (!stat.isDirectory()) { return; } - const extensionName = path.basename(extensionFolder.path); + let extensionName = path.basename(extensionFolder.path); if (extensionName === 'node_modules') { return; } @@ -726,29 +722,22 @@ export function createXlfFilesForExtensions(): ThroughStream { const basename = path.basename(file.path); if (basename === 'package.nls.json') { const json: PackageJsonFormat = JSON.parse(buffer.toString('utf8')); - const keys: Array = []; - const messages: string[] = []; - Object.keys(json).forEach((key) => { + const keys = Object.keys(json); + const messages = keys.map((key) => { const value = json[key]; if (Is.string(value)) { - keys.push(key); - messages.push(value); + return value; } else if (value) { - keys.push({ - key, - comment: value.comment - }); - messages.push(value.message); + return value.message; } else { - keys.push(key); - messages.push(`Unknown message for key: ${key}`); + return `Unknown message for key: ${key}`; } }); getXlf().addFile(`extensions/${extensionName}/package`, keys, messages); } else if (basename === 'nls.metadata.json') { const json: BundledExtensionFormat = JSON.parse(buffer.toString('utf8')); const relPath = path.relative(`.build/extensions/${extensionName}`, path.dirname(file.path)); - for (const file in json) { + for (let file in json) { const fileContent = json[file]; getXlf().addFile(`extensions/${extensionName}/${relPath}/${file}`, fileContent.keys, fileContent.messages); } @@ -759,7 +748,7 @@ export function createXlfFilesForExtensions(): ThroughStream { } }, function () { if (_xlf) { - const xlfFile = new File({ + let xlfFile = new File({ path: path.join(extensionsProject, extensionName + '.xlf'), contents: Buffer.from(_xlf.toString(), 'utf8') }); @@ -792,17 +781,17 @@ export function createXlfFilesForIsl(): ThroughStream { throw new Error(`Unknown input file ${file.path}`); } - const xlf = new XLF(projectName), + let xlf = new XLF(projectName), keys: string[] = [], messages: string[] = []; - const model = new TextModel(file.contents.toString()); + let model = new TextModel(file.contents.toString()); let inMessageSection = false; model.lines.forEach(line => { if (line.length === 0) { return; } - const firstChar = line.charAt(0); + let firstChar = line.charAt(0); switch (firstChar) { case ';': // Comment line; @@ -814,12 +803,12 @@ export function createXlfFilesForIsl(): ThroughStream { if (!inMessageSection) { return; } - const sections: string[] = line.split('='); + let sections: string[] = line.split('='); if (sections.length !== 2) { throw new Error(`Badly formatted message found: ${line}`); } else { - const key = sections[0]; - const value = sections[1]; + let key = sections[0]; + let value = sections[1]; if (key.length > 0 && value.length > 0) { keys.push(key); messages.push(value); @@ -838,8 +827,8 @@ export function createXlfFilesForIsl(): ThroughStream { } export function pushXlfFiles(apiHostname: string, username: string, password: string): ThroughStream { - const tryGetPromises: Array> = []; - const updateCreatePromises: Array> = []; + let tryGetPromises: Array> = []; + let updateCreatePromises: Array> = []; return through(function (this: ThroughStream, file: File) { const project = path.dirname(file.relative); @@ -880,11 +869,11 @@ function getAllResources(project: string, apiHostname: string, username: string, }; const request = https.request(options, (res) => { - const buffer: Buffer[] = []; + let buffer: Buffer[] = []; res.on('data', (chunk: Buffer) => buffer.push(chunk)); res.on('end', () => { if (res.statusCode === 200) { - const json = JSON.parse(Buffer.concat(buffer).toString()); + let json = JSON.parse(Buffer.concat(buffer).toString()); if (Array.isArray(json)) { resolve(json.map(o => o.slug)); return; @@ -903,7 +892,7 @@ function getAllResources(project: string, apiHostname: string, username: string, } export function findObsoleteResources(apiHostname: string, username: string, password: string): ThroughStream { - const resourcesByProject: Map = Object.create(null); + let resourcesByProject: Map = Object.create(null); resourcesByProject[extensionsProject] = ([] as any[]).concat(externalExtensionsWithTranslations); // clone return through(function (this: ThroughStream, file: File) { @@ -920,10 +909,10 @@ export function findObsoleteResources(apiHostname: string, username: string, pas }, function () { const json = JSON.parse(fs.readFileSync('./build/lib/i18n.resources.json', 'utf8')); - const i18Resources = [...json.editor, ...json.workbench].map((r: Resource) => r.project + '/' + r.name.replace(/\//g, '_')); - const extractedResources: string[] = []; - for (const project of [workbenchProject, editorProject]) { - for (const resource of resourcesByProject[project]) { + let i18Resources = [...json.editor, ...json.workbench].map((r: Resource) => r.project + '/' + r.name.replace(/\//g, '_')); + let extractedResources: string[] = []; + for (let project of [workbenchProject, editorProject]) { + for (let resource of resourcesByProject[project]) { if (resource !== 'setup_messages') { extractedResources.push(project + '/' + resource); } @@ -934,12 +923,12 @@ export function findObsoleteResources(apiHostname: string, username: string, pas console.log(`[i18n] Missing resources in file 'build/lib/i18n.resources.json': JSON.stringify(${extractedResources.filter(p => i18Resources.indexOf(p) === -1)})`); } - const promises: Array> = []; - for (const project in resourcesByProject) { + let promises: Array> = []; + for (let project in resourcesByProject) { promises.push( getAllResources(project, apiHostname, username, password).then(resources => { - const expectedResources = resourcesByProject[project]; - const unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1); + let expectedResources = resourcesByProject[project]; + let unusedResources = resources.filter(resource => resource && expectedResources.indexOf(resource) === -1); if (unusedResources.length) { console.log(`[transifex] Obsolete resources in project '${project}': ${unusedResources.join(', ')}`); } @@ -997,7 +986,7 @@ function createResource(project: string, slug: string, xlfFile: File, apiHostnam method: 'POST' }; - const request = https.request(options, (res) => { + let request = https.request(options, (res) => { if (res.statusCode === 201) { log(`Resource ${project}/${slug} successfully created on Transifex.`); } else { @@ -1031,7 +1020,7 @@ function updateResource(project: string, slug: string, xlfFile: File, apiHostnam method: 'PUT' }; - const request = https.request(options, (res) => { + let request = https.request(options, (res) => { if (res.statusCode === 200) { res.setEncoding('utf8'); @@ -1058,7 +1047,7 @@ function updateResource(project: string, slug: string, xlfFile: File, apiHostnam } export function pullSetupXlfFiles(apiHostname: string, username: string, password: string, language: Language, includeDefault: boolean): NodeJS.ReadableStream { - const setupResources = [{ name: 'setup_messages', project: workbenchProject }]; + let setupResources = [{ name: 'setup_messages', project: workbenchProject }]; if (includeDefault) { setupResources.push({ name: 'setup_default', project: setupProject }); } @@ -1067,7 +1056,7 @@ export function pullSetupXlfFiles(apiHostname: string, username: string, passwor function pullXlfFiles(apiHostname: string, username: string, password: string, language: Language, resources: Resource[]): NodeJS.ReadableStream { const credentials = `${username}:${password}`; - const expectedTranslationsCount = resources.length; + let expectedTranslationsCount = resources.length; let translationsRetrieved = 0, called = false; return readable(function (_count: any, callback: any) { @@ -1098,7 +1087,7 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s return limiter.queue(() => new Promise((resolve, reject) => { const slug = resource.name.replace(/\//g, '_'); const project = resource.project; - const transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id; + let transifexLanguageId = language.id === 'ps' ? 'en' : language.translationId || language.id; const options = { hostname: apiHostname, path: `/api/2/project/${project}/resource/${slug}/translation/${transifexLanguageId}?file&mode=onlyreviewed`, @@ -1108,8 +1097,8 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s }; console.log('[transifex] Fetching ' + options.path); - const request = https.request(options, (res) => { - const xlfBuffer: Buffer[] = []; + let request = https.request(options, (res) => { + let xlfBuffer: Buffer[] = []; res.on('data', (chunk: Buffer) => xlfBuffer.push(chunk)); res.on('end', () => { if (res.statusCode === 200) { @@ -1130,16 +1119,16 @@ function retrieveResource(language: Language, resource: Resource, apiHostname: s } export function prepareI18nFiles(): ThroughStream { - const parsePromises: Promise[] = []; + let parsePromises: Promise[] = []; return through(function (this: ThroughStream, xlf: File) { - const stream = this; - const parsePromise = XLF.parse(xlf.contents.toString()); + let stream = this; + let parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { resolvedFiles.forEach(file => { - const translatedFile = createI18nFile(file.originalFilePath, file.messages); + let translatedFile = createI18nFile(file.originalFilePath, file.messages); stream.queue(translatedFile); }); } @@ -1160,7 +1149,7 @@ export function createI18nFile(originalFilePath: string, messages: any): File { '--------------------------------------------------------------------------------------------', 'Do not edit this file. It is machine generated.' ]; - for (const key of Object.keys(messages)) { + for (let key of Object.keys(messages)) { result[key] = messages[key]; } @@ -1189,16 +1178,16 @@ export interface TranslationPath { } export function prepareI18nPackFiles(externalExtensions: Map, resultingTranslationPaths: TranslationPath[], pseudo = false): NodeJS.ReadWriteStream { - const parsePromises: Promise[] = []; - const mainPack: I18nPack = { version: i18nPackVersion, contents: {} }; - const extensionsPacks: Map = {}; - const errors: any[] = []; + let parsePromises: Promise[] = []; + let mainPack: I18nPack = { version: i18nPackVersion, contents: {} }; + let extensionsPacks: Map = {}; + let errors: any[] = []; return through(function (this: ThroughStream, xlf: File) { - const project = path.basename(path.dirname(path.dirname(xlf.relative))); - const resource = path.basename(xlf.relative, '.xlf'); - const contents = xlf.contents.toString(); + let project = path.basename(path.dirname(path.dirname(xlf.relative))); + let resource = path.basename(xlf.relative, '.xlf'); + let contents = xlf.contents.toString(); log(`Found ${project}: ${resource}`); - const parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents); + let parsePromise = pseudo ? XLF.parsePseudo(contents) : XLF.parse(contents); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { @@ -1236,7 +1225,7 @@ export function prepareI18nPackFiles(externalExtensions: Map, resultingT resultingTranslationPaths.push({ id: 'vscode', resourceName: 'main.i18n.json' }); this.queue(translatedMainFile); - for (const extension in extensionsPacks) { + for (let extension in extensionsPacks) { const translatedExtFile = createI18nFile(`extensions/${extension}`, extensionsPacks[extension]); this.queue(translatedExtFile); @@ -1257,16 +1246,16 @@ export function prepareI18nPackFiles(externalExtensions: Map, resultingT } export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): ThroughStream { - const parsePromises: Promise[] = []; + let parsePromises: Promise[] = []; return through(function (this: ThroughStream, xlf: File) { - const stream = this; - const parsePromise = XLF.parse(xlf.contents.toString()); + let stream = this; + let parsePromise = XLF.parse(xlf.contents.toString()); parsePromises.push(parsePromise); parsePromise.then( resolvedFiles => { resolvedFiles.forEach(file => { - const translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig); + let translatedFile = createIslFile(file.originalFilePath, file.messages, language, innoSetupConfig); stream.queue(translatedFile); }); } @@ -1283,7 +1272,7 @@ export function prepareIslFiles(language: Language, innoSetupConfig: InnoSetup): } function createIslFile(originalFilePath: string, messages: Map, language: Language, innoSetup: InnoSetup): File { - const content: string[] = []; + let content: string[] = []; let originalContent: TextModel; if (path.basename(originalFilePath) === 'Default') { originalContent = new TextModel(fs.readFileSync(originalFilePath + '.isl', 'utf8')); @@ -1292,15 +1281,15 @@ function createIslFile(originalFilePath: string, messages: Map, language } originalContent.lines.forEach(line => { if (line.length > 0) { - const firstChar = line.charAt(0); + let firstChar = line.charAt(0); if (firstChar === '[' || firstChar === ';') { content.push(line); } else { - const sections: string[] = line.split('='); - const key = sections[0]; + let sections: string[] = line.split('='); + let key = sections[0]; let translated = line; if (key) { - const translatedMessage = messages[key]; + let translatedMessage = messages[key]; if (translatedMessage) { translated = `${key}=${translatedMessage}`; } @@ -1322,9 +1311,9 @@ function createIslFile(originalFilePath: string, messages: Map, language } function encodeEntities(value: string): string { - const result: string[] = []; + let result: string[] = []; for (let i = 0; i < value.length; i++) { - const ch = value[i]; + let ch = value[i]; switch (ch) { case '<': result.push('<'); diff --git a/build/lib/layersChecker.js b/build/lib/layersChecker.js index 7d66ceba4f..60d594f494 100644 --- a/build/lib/layersChecker.js +++ b/build/lib/layersChecker.js @@ -72,11 +72,6 @@ const RULES = [ target: '**/{vs,sql}/**/test/**', skip: true // -> skip all test files }, - // TODO@bpasero remove me once electron utility process has landed - { - target: '**/vs/workbench/services/extensions/electron-sandbox/nativeLocalProcessExtensionHost.ts', - skip: true - }, // Common: vs/base/common/platform.ts { target: '**/{vs,sql}/base/common/platform.ts', diff --git a/build/lib/monaco-api.js b/build/lib/monaco-api.js index 7dcdcfbdbb..151b90218e 100644 --- a/build/lib/monaco-api.js +++ b/build/lib/monaco-api.js @@ -27,7 +27,7 @@ function isDeclaration(ts, a) { } function visitTopLevelDeclarations(ts, sourceFile, visitor) { let stop = false; - const visit = (node) => { + let visit = (node) => { if (stop) { return; } @@ -49,19 +49,19 @@ function visitTopLevelDeclarations(ts, sourceFile, visitor) { visit(sourceFile); } function getAllTopLevelDeclarations(ts, sourceFile) { - const all = []; + let all = []; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) { - const interfaceDeclaration = node; - const triviaStart = interfaceDeclaration.pos; - const triviaEnd = interfaceDeclaration.name.pos; - const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); + let interfaceDeclaration = node; + let triviaStart = interfaceDeclaration.pos; + let triviaEnd = interfaceDeclaration.name.pos; + let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); if (triviaText.indexOf('@internal') === -1) { all.push(node); } } else { - const nodeText = getNodeText(sourceFile, node); + let nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { all.push(node); } @@ -95,7 +95,7 @@ function getNodeText(sourceFile, node) { function hasModifier(modifiers, kind) { if (modifiers) { for (let i = 0; i < modifiers.length; i++) { - const mod = modifiers[i]; + let mod = modifiers[i]; if (mod.kind === kind) { return true; } @@ -113,14 +113,14 @@ function isDefaultExport(ts, declaration) { function getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums) { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { - const interfaceDeclaration = declaration; + let interfaceDeclaration = declaration; const staticTypeName = (isDefaultExport(ts, interfaceDeclaration) ? `${importName}.default` : `${importName}.${declaration.name.text}`); let instanceTypeName = staticTypeName; const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); if (typeParametersCnt > 0) { - const arr = []; + let arr = []; for (let i = 0; i < typeParametersCnt; i++) { arr.push('any'); } @@ -129,7 +129,7 @@ function getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importN const members = interfaceDeclaration.members; members.forEach((member) => { try { - const memberText = getNodeText(sourceFile, member); + let memberText = getNodeText(sourceFile, member); if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { result = result.replace(memberText, ''); } @@ -152,7 +152,7 @@ function getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importN result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); result = result.replace(/declare /g, ''); - const lines = result.split(/\r\n|\r|\n/); + let lines = result.split(/\r\n|\r|\n/); for (let i = 0; i < lines.length; i++) { if (/\s*\*/.test(lines[i])) { // very likely a comment @@ -177,9 +177,9 @@ function format(ts, text, endl) { return text; } // Parse the source text - const sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); + let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); // Get the formatting edits on the input sources - const edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); + let edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); // Apply the edits on the input code return applyEdits(text, edits); function countParensCurly(text) { @@ -202,7 +202,7 @@ function format(ts, text, endl) { return r; } function preformat(text, endl) { - const lines = text.split(endl); + let lines = text.split(endl); let inComment = false; let inCommentDeltaIndent = 0; let indent = 0; @@ -282,9 +282,9 @@ function format(ts, text, endl) { // Apply edits in reverse on the existing text let result = text; for (let i = edits.length - 1; i >= 0; i--) { - const change = edits[i]; - const head = result.slice(0, change.span.start); - const tail = result.slice(change.span.start + change.span.length); + let change = edits[i]; + let head = result.slice(0, change.span.start); + let tail = result.slice(change.span.start + change.span.length); result = head + change.newText + tail; } return result; @@ -300,15 +300,15 @@ function createReplacerFromDirectives(directives) { } function createReplacer(data) { data = data || ''; - const rawDirectives = data.split(';'); - const directives = []; + let rawDirectives = data.split(';'); + let directives = []; rawDirectives.forEach((rawDirective) => { if (rawDirective.length === 0) { return; } - const pieces = rawDirective.split('=>'); + let pieces = rawDirective.split('=>'); let findStr = pieces[0]; - const replaceStr = pieces[1]; + let replaceStr = pieces[1]; findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&'); findStr = '\\b' + findStr + '\\b'; directives.push([new RegExp(findStr, 'g'), replaceStr]); @@ -317,32 +317,32 @@ function createReplacer(data) { } function generateDeclarationFile(ts, recipe, sourceFileGetter) { const endl = /\r\n/.test(recipe) ? '\r\n' : '\n'; - const lines = recipe.split(endl); - const result = []; + let lines = recipe.split(endl); + let result = []; let usageCounter = 0; - const usageImports = []; - const usage = []; + let usageImports = []; + let usage = []; let failed = false; usage.push(`var a: any;`); usage.push(`var b: any;`); const generateUsageImport = (moduleId) => { - const importName = 'm' + (++usageCounter); + let importName = 'm' + (++usageCounter); usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`); return importName; }; - const enums = []; + let enums = []; let version = null; lines.forEach(line => { if (failed) { return; } - const m0 = line.match(/^\/\/dtsv=(\d+)$/); + let m0 = line.match(/^\/\/dtsv=(\d+)$/); if (m0) { version = m0[1]; } - const m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); + let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m1) { - const moduleId = m1[1]; + let moduleId = m1[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); @@ -351,14 +351,14 @@ function generateDeclarationFile(ts, recipe, sourceFileGetter) { return; } const importName = generateUsageImport(moduleId); - const replacer = createReplacer(m1[2]); - const typeNames = m1[3].split(/,/); + let replacer = createReplacer(m1[2]); + let typeNames = m1[3].split(/,/); typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } - const declaration = getTopLevelDeclaration(ts, sourceFile, typeName); + let declaration = getTopLevelDeclaration(ts, sourceFile, typeName); if (!declaration) { logErr(`While handling ${line}`); logErr(`Cannot find ${typeName}`); @@ -369,9 +369,9 @@ function generateDeclarationFile(ts, recipe, sourceFileGetter) { }); return; } - const m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); + let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m2) { - const moduleId = m2[1]; + let moduleId = m2[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); @@ -380,10 +380,10 @@ function generateDeclarationFile(ts, recipe, sourceFileGetter) { return; } const importName = generateUsageImport(moduleId); - const replacer = createReplacer(m2[2]); - const typeNames = m2[3].split(/,/); - const typesToExcludeMap = {}; - const typesToExcludeArr = []; + let replacer = createReplacer(m2[2]); + let typeNames = m2[3].split(/,/); + let typesToExcludeMap = {}; + let typesToExcludeArr = []; typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { @@ -400,7 +400,7 @@ function generateDeclarationFile(ts, recipe, sourceFileGetter) { } else { // node is ts.VariableStatement - const nodeText = getNodeText(sourceFile, declaration); + let nodeText = getNodeText(sourceFile, declaration); for (let i = 0; i < typesToExcludeArr.length; i++) { if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) { return; @@ -605,7 +605,7 @@ class TypeScriptLanguageServiceHost { } } function execute() { - const r = run3(new DeclarationResolver(new FSProvider())); + let r = run3(new DeclarationResolver(new FSProvider())); if (!r) { throw new Error(`monaco.d.ts generation error - Cannot continue`); } diff --git a/build/lib/monaco-api.ts b/build/lib/monaco-api.ts index 4f6fce7a42..6bcce808b5 100644 --- a/build/lib/monaco-api.ts +++ b/build/lib/monaco-api.ts @@ -40,7 +40,7 @@ function isDeclaration(ts: typeof import('typescript'), a: TSTopLevelDeclare): a function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile, visitor: (node: TSTopLevelDeclare) => boolean): void { let stop = false; - const visit = (node: ts.Node): void => { + let visit = (node: ts.Node): void => { if (stop) { return; } @@ -67,19 +67,19 @@ function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: function getAllTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TSTopLevelDeclare[] { - const all: TSTopLevelDeclare[] = []; + let all: TSTopLevelDeclare[] = []; visitTopLevelDeclarations(ts, sourceFile, (node) => { if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) { - const interfaceDeclaration = node; - const triviaStart = interfaceDeclaration.pos; - const triviaEnd = interfaceDeclaration.name.pos; - const triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); + let interfaceDeclaration = node; + let triviaStart = interfaceDeclaration.pos; + let triviaEnd = interfaceDeclaration.name.pos; + let triviaText = getNodeText(sourceFile, { pos: triviaStart, end: triviaEnd }); if (triviaText.indexOf('@internal') === -1) { all.push(node); } } else { - const nodeText = getNodeText(sourceFile, node); + let nodeText = getNodeText(sourceFile, node); if (nodeText.indexOf('@internal') === -1) { all.push(node); } @@ -115,10 +115,10 @@ function getNodeText(sourceFile: ts.SourceFile, node: { pos: number; end: number return sourceFile.getFullText().substring(node.pos, node.end); } -function hasModifier(modifiers: ts.NodeArray | undefined, kind: ts.SyntaxKind): boolean { +function hasModifier(modifiers: ts.NodeArray | undefined, kind: ts.SyntaxKind): boolean { if (modifiers) { for (let i = 0; i < modifiers.length; i++) { - const mod = modifiers[i]; + let mod = modifiers[i]; if (mod.kind === kind) { return true; } @@ -141,7 +141,7 @@ function isDefaultExport(ts: typeof import('typescript'), declaration: ts.Interf function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string { let result = getNodeText(sourceFile, declaration); if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) { - const interfaceDeclaration = declaration; + let interfaceDeclaration = declaration; const staticTypeName = ( isDefaultExport(ts, interfaceDeclaration) @@ -152,7 +152,7 @@ function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sou let instanceTypeName = staticTypeName; const typeParametersCnt = (interfaceDeclaration.typeParameters ? interfaceDeclaration.typeParameters.length : 0); if (typeParametersCnt > 0) { - const arr: string[] = []; + let arr: string[] = []; for (let i = 0; i < typeParametersCnt; i++) { arr.push('any'); } @@ -162,7 +162,7 @@ function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sou const members: ts.NodeArray = interfaceDeclaration.members; members.forEach((member) => { try { - const memberText = getNodeText(sourceFile, member); + let memberText = getNodeText(sourceFile, member); if (memberText.indexOf('@internal') >= 0 || memberText.indexOf('private') >= 0) { result = result.replace(memberText, ''); } else { @@ -182,7 +182,7 @@ function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sou result = result.replace(/export default /g, 'export '); result = result.replace(/export declare /g, 'export '); result = result.replace(/declare /g, ''); - const lines = result.split(/\r\n|\r|\n/); + let lines = result.split(/\r\n|\r|\n/); for (let i = 0; i < lines.length; i++) { if (/\s*\*/.test(lines[i])) { // very likely a comment @@ -212,10 +212,10 @@ function format(ts: typeof import('typescript'), text: string, endl: string): st } // Parse the source text - const sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); + let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); // Get the formatting edits on the input sources - const edits = (ts).formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); + let edits = (ts).formatting.formatDocument(sourceFile, getRuleProvider(tsfmt), tsfmt); // Apply the edits on the input code return applyEdits(text, edits); @@ -242,7 +242,7 @@ function format(ts: typeof import('typescript'), text: string, endl: string): st } function preformat(text: string, endl: string): string { - const lines = text.split(endl); + let lines = text.split(endl); let inComment = false; let inCommentDeltaIndent = 0; let indent = 0; @@ -328,9 +328,9 @@ function format(ts: typeof import('typescript'), text: string, endl: string): st // Apply edits in reverse on the existing text let result = text; for (let i = edits.length - 1; i >= 0; i--) { - const change = edits[i]; - const head = result.slice(0, change.span.start); - const tail = result.slice(change.span.start + change.span.length); + let change = edits[i]; + let head = result.slice(0, change.span.start); + let tail = result.slice(change.span.start + change.span.length); result = head + change.newText + tail; } return result; @@ -348,15 +348,15 @@ function createReplacerFromDirectives(directives: [RegExp, string][]): (str: str function createReplacer(data: string): (str: string) => string { data = data || ''; - const rawDirectives = data.split(';'); - const directives: [RegExp, string][] = []; + let rawDirectives = data.split(';'); + let directives: [RegExp, string][] = []; rawDirectives.forEach((rawDirective) => { if (rawDirective.length === 0) { return; } - const pieces = rawDirective.split('=>'); + let pieces = rawDirective.split('=>'); let findStr = pieces[0]; - const replaceStr = pieces[1]; + let replaceStr = pieces[1]; findStr = findStr.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, '\\$&'); findStr = '\\b' + findStr + '\\b'; @@ -380,12 +380,12 @@ interface IEnumEntry { function generateDeclarationFile(ts: typeof import('typescript'), recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null { const endl = /\r\n/.test(recipe) ? '\r\n' : '\n'; - const lines = recipe.split(endl); - const result: string[] = []; + let lines = recipe.split(endl); + let result: string[] = []; let usageCounter = 0; - const usageImports: string[] = []; - const usage: string[] = []; + let usageImports: string[] = []; + let usage: string[] = []; let failed = false; @@ -393,12 +393,12 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string usage.push(`var b: any;`); const generateUsageImport = (moduleId: string) => { - const importName = 'm' + (++usageCounter); + let importName = 'm' + (++usageCounter); usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`); return importName; }; - const enums: IEnumEntry[] = []; + let enums: IEnumEntry[] = []; let version: string | null = null; lines.forEach(line => { @@ -407,14 +407,14 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string return; } - const m0 = line.match(/^\/\/dtsv=(\d+)$/); + let m0 = line.match(/^\/\/dtsv=(\d+)$/); if (m0) { version = m0[1]; } - const m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); + let m1 = line.match(/^\s*#include\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m1) { - const moduleId = m1[1]; + let moduleId = m1[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); @@ -425,15 +425,15 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string const importName = generateUsageImport(moduleId); - const replacer = createReplacer(m1[2]); + let replacer = createReplacer(m1[2]); - const typeNames = m1[3].split(/,/); + let typeNames = m1[3].split(/,/); typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { return; } - const declaration = getTopLevelDeclaration(ts, sourceFile, typeName); + let declaration = getTopLevelDeclaration(ts, sourceFile, typeName); if (!declaration) { logErr(`While handling ${line}`); logErr(`Cannot find ${typeName}`); @@ -445,9 +445,9 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string return; } - const m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); + let m2 = line.match(/^\s*#includeAll\(([^;)]*)(;[^)]*)?\)\:(.*)$/); if (m2) { - const moduleId = m2[1]; + let moduleId = m2[1]; const sourceFile = sourceFileGetter(moduleId); if (!sourceFile) { logErr(`While handling ${line}`); @@ -458,11 +458,11 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string const importName = generateUsageImport(moduleId); - const replacer = createReplacer(m2[2]); + let replacer = createReplacer(m2[2]); - const typeNames = m2[3].split(/,/); - const typesToExcludeMap: { [typeName: string]: boolean } = {}; - const typesToExcludeArr: string[] = []; + let typeNames = m2[3].split(/,/); + let typesToExcludeMap: { [typeName: string]: boolean } = {}; + let typesToExcludeArr: string[] = []; typeNames.forEach((typeName) => { typeName = typeName.trim(); if (typeName.length === 0) { @@ -479,7 +479,7 @@ function generateDeclarationFile(ts: typeof import('typescript'), recipe: string } } else { // node is ts.VariableStatement - const nodeText = getNodeText(sourceFile, declaration); + let nodeText = getNodeText(sourceFile, declaration); for (let i = 0; i < typesToExcludeArr.length; i++) { if (nodeText.indexOf(typesToExcludeArr[i]) >= 0) { return; @@ -732,7 +732,7 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost { } export function execute(): IMonacoDeclarationResult { - const r = run3(new DeclarationResolver(new FSProvider())); + let r = run3(new DeclarationResolver(new FSProvider())); if (!r) { throw new Error(`monaco.d.ts generation error - Cannot continue`); } diff --git a/build/lib/optimize.js b/build/lib/optimize.js index f359028f8d..dfc644dfed 100644 --- a/build/lib/optimize.js +++ b/build/lib/optimize.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.minifyTask = exports.optimizeTask = exports.loaderConfig = void 0; const es = require("event-stream"); @@ -37,58 +37,40 @@ function loaderConfig() { } exports.loaderConfig = loaderConfig; const IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i; -function loaderPlugin(src, base, amdModuleId) { - return (gulp - .src(src, { base }) - .pipe(es.through(function (data) { - if (amdModuleId) { - let contents = data.contents.toString('utf8'); - contents = contents.replace(/^define\(/m, `define("${amdModuleId}",`); - data.contents = Buffer.from(contents); - } - this.emit('data', data); - }))); -} function loader(src, bundledFileHeader, bundleLoader, externalLoaderInfo) { - let loaderStream = gulp.src(`${src}/vs/loader.js`, { base: `${src}` }); + let sources = [ + `${src}/vs/loader.js` + ]; if (bundleLoader) { - loaderStream = es.merge(loaderStream, loaderPlugin(`${src}/vs/css.js`, `${src}`, 'vs/css'), loaderPlugin(`${src}/vs/nls.js`, `${src}`, 'vs/nls')); + sources = sources.concat([ + `${src}/vs/css.js`, + `${src}/vs/nls.js` + ]); } - const files = []; - const order = (f) => { - if (f.path.endsWith('loader.js')) { - return 0; - } - if (f.path.endsWith('css.js')) { - return 1; - } - if (f.path.endsWith('nls.js')) { - return 2; - } - return 3; - }; - return (loaderStream + let isFirst = true; + return (gulp + .src(sources, { base: `${src}` }) .pipe(es.through(function (data) { - files.push(data); + if (isFirst) { + isFirst = false; + this.emit('data', new VinylFile({ + path: 'fake', + base: '.', + contents: Buffer.from(bundledFileHeader) + })); + this.emit('data', data); + } + else { + this.emit('data', data); + } }, function () { - files.sort((a, b) => { - return order(a) - order(b); - }); - files.unshift(new VinylFile({ - path: 'fake', - base: '.', - contents: Buffer.from(bundledFileHeader) - })); if (externalLoaderInfo !== undefined) { - files.push(new VinylFile({ + this.emit('data', new VinylFile({ path: 'fake2', base: '.', contents: Buffer.from(`require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)});`) })); } - for (const file of files) { - this.emit('data', file); - } this.emit('end'); })) .pipe(concat('vs/loader.js'))); diff --git a/build/lib/optimize.ts b/build/lib/optimize.ts index 16ba020199..cfda628c34 100644 --- a/build/lib/optimize.ts +++ b/build/lib/optimize.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as es from 'event-stream'; import * as gulp from 'gulp'; import * as concat from 'gulp-concat'; @@ -41,68 +43,41 @@ export function loaderConfig() { const IS_OUR_COPYRIGHT_REGEXP = /Copyright \(C\) Microsoft Corporation/i; -function loaderPlugin(src: string, base: string, amdModuleId: string | undefined): NodeJS.ReadWriteStream { - return ( - gulp - .src(src, { base }) - .pipe(es.through(function (data: VinylFile) { - if (amdModuleId) { - let contents = data.contents.toString('utf8'); - contents = contents.replace(/^define\(/m, `define("${amdModuleId}",`); - data.contents = Buffer.from(contents); - } - this.emit('data', data); - })) - ); -} - function loader(src: string, bundledFileHeader: string, bundleLoader: boolean, externalLoaderInfo?: any): NodeJS.ReadWriteStream { - let loaderStream = gulp.src(`${src}/vs/loader.js`, { base: `${src}` }); + let sources = [ + `${src}/vs/loader.js` + ]; if (bundleLoader) { - loaderStream = es.merge( - loaderStream, - loaderPlugin(`${src}/vs/css.js`, `${src}`, 'vs/css'), - loaderPlugin(`${src}/vs/nls.js`, `${src}`, 'vs/nls'), - ); + sources = sources.concat([ + `${src}/vs/css.js`, + `${src}/vs/nls.js` + ]); } - const files: VinylFile[] = []; - const order = (f: VinylFile) => { - if (f.path.endsWith('loader.js')) { - return 0; - } - if (f.path.endsWith('css.js')) { - return 1; - } - if (f.path.endsWith('nls.js')) { - return 2; - } - return 3; - }; - + let isFirst = true; return ( - loaderStream + gulp + .src(sources, { base: `${src}` }) .pipe(es.through(function (data) { - files.push(data); + if (isFirst) { + isFirst = false; + this.emit('data', new VinylFile({ + path: 'fake', + base: '.', + contents: Buffer.from(bundledFileHeader) + })); + this.emit('data', data); + } else { + this.emit('data', data); + } }, function () { - files.sort((a, b) => { - return order(a) - order(b); - }); - files.unshift(new VinylFile({ - path: 'fake', - base: '.', - contents: Buffer.from(bundledFileHeader) - })); if (externalLoaderInfo !== undefined) { - files.push(new VinylFile({ + this.emit('data', new VinylFile({ path: 'fake2', base: '.', contents: Buffer.from(`require.config(${JSON.stringify(externalLoaderInfo, undefined, 2)});`) })); } - for (const file of files) { - this.emit('data', file); - } this.emit('end'); })) .pipe(concat('vs/loader.js')) diff --git a/build/lib/policies.js b/build/lib/policies.js deleted file mode 100644 index 7b1bbdf394..0000000000 --- a/build/lib/policies.js +++ /dev/null @@ -1,497 +0,0 @@ -"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 }); -const child_process_1 = require("child_process"); -const fs_1 = require("fs"); -const path = require("path"); -const byline = require("byline"); -const ripgrep_1 = require("@vscode/ripgrep"); -const Parser = require("tree-sitter"); -const node_fetch_1 = require("node-fetch"); -const { typescript } = require('tree-sitter-typescript'); -const product = require('../../product.json'); -function isNlsString(value) { - return value ? typeof value !== 'string' : false; -} -function isStringArray(value) { - return !value.some(s => isNlsString(s)); -} -function isNlsStringArray(value) { - return value.every(s => isNlsString(s)); -} -var PolicyType; -(function (PolicyType) { - PolicyType[PolicyType["StringEnum"] = 0] = "StringEnum"; -})(PolicyType || (PolicyType = {})); -function renderADMLString(prefix, moduleName, nlsString, translations) { - let value; - if (translations) { - const moduleTranslations = translations[moduleName]; - if (moduleTranslations) { - value = moduleTranslations[nlsString.nlsKey]; - } - } - if (!value) { - value = nlsString.value; - } - return `${value}`; -} -class BasePolicy { - constructor(policyType, name, category, minimumVersion, description, moduleName) { - this.policyType = policyType; - this.name = name; - this.category = category; - this.minimumVersion = minimumVersion; - this.description = description; - this.moduleName = moduleName; - } - renderADMLString(nlsString, translations) { - return renderADMLString(this.name, this.moduleName, nlsString, translations); - } - renderADMX(regKey) { - return [ - ``, - ` `, - ` `, - ` `, - ...this.renderADMXElements(), - ` `, - `` - ]; - } - renderADMLStrings(translations) { - return [ - `${this.name}`, - this.renderADMLString(this.description, translations) - ]; - } - renderADMLPresentation() { - return `${this.renderADMLPresentationContents()}`; - } -} -class BooleanPolicy extends BasePolicy { - static from(name, category, minimumVersion, description, moduleName, settingNode) { - const type = getStringProperty(settingNode, 'type'); - if (type !== 'boolean') { - return undefined; - } - return new BooleanPolicy(name, category, minimumVersion, description, moduleName); - } - constructor(name, category, minimumVersion, description, moduleName) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - } - renderADMXElements() { - return [ - ``, - ` `, - `` - ]; - } - renderADMLPresentationContents() { - return `${this.name}`; - } -} -class IntPolicy extends BasePolicy { - constructor(name, category, minimumVersion, description, moduleName, defaultValue) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - this.defaultValue = defaultValue; - } - static from(name, category, minimumVersion, description, moduleName, settingNode) { - const type = getStringProperty(settingNode, 'type'); - if (type !== 'number') { - return undefined; - } - const defaultValue = getIntProperty(settingNode, 'default'); - if (typeof defaultValue === 'undefined') { - throw new Error(`Missing required 'default' property.`); - } - return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue); - } - renderADMXElements() { - return [ - `` - // `` - ]; - } - renderADMLPresentationContents() { - return `${this.name}`; - } -} -class StringPolicy extends BasePolicy { - static from(name, category, minimumVersion, description, moduleName, settingNode) { - const type = getStringProperty(settingNode, 'type'); - if (type !== 'string') { - return undefined; - } - return new StringPolicy(name, category, minimumVersion, description, moduleName); - } - constructor(name, category, minimumVersion, description, moduleName) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - } - renderADMXElements() { - return [``]; - } - renderADMLPresentationContents() { - return ``; - } -} -class StringEnumPolicy extends BasePolicy { - constructor(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - this.enum_ = enum_; - this.enumDescriptions = enumDescriptions; - } - static from(name, category, minimumVersion, description, moduleName, settingNode) { - const type = getStringProperty(settingNode, 'type'); - if (type !== 'string') { - return undefined; - } - const enum_ = getStringArrayProperty(settingNode, 'enum'); - if (!enum_) { - return undefined; - } - if (!isStringArray(enum_)) { - throw new Error(`Property 'enum' should not be localized.`); - } - const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions'); - if (!enumDescriptions) { - throw new Error(`Missing required 'enumDescriptions' property.`); - } - else if (!isNlsStringArray(enumDescriptions)) { - throw new Error(`Property 'enumDescriptions' should be localized.`); - } - return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions); - } - renderADMXElements() { - return [ - ``, - ...this.enum_.map((value, index) => ` ${value}`), - `` - ]; - } - renderADMLStrings(translations) { - return [ - ...super.renderADMLStrings(translations), - ...this.enumDescriptions.map(e => this.renderADMLString(e, translations)) - ]; - } - renderADMLPresentationContents() { - return ``; - } -} -const IntQ = { - Q: `(number) @value`, - value(matches) { - const match = matches[0]; - if (!match) { - return undefined; - } - const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; - if (!value) { - throw new Error(`Missing required 'value' property.`); - } - return parseInt(value); - } -}; -const StringQ = { - Q: `[ - (string (string_fragment) @value) - (call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize)) - ]`, - value(matches) { - const match = matches[0]; - if (!match) { - return undefined; - } - const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; - if (!value) { - throw new Error(`Missing required 'value' property.`); - } - const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text; - if (nlsKey) { - return { value, nlsKey }; - } - else { - return value; - } - } -}; -const StringArrayQ = { - Q: `(array ${StringQ.Q})`, - value(matches) { - if (matches.length === 0) { - return undefined; - } - return matches.map(match => { - return StringQ.value([match]); - }); - } -}; -function getProperty(qtype, node, key) { - const query = new Parser.Query(typescript, `( - (pair - key: [(property_identifier)(string)] @key - value: ${qtype.Q} - ) - (#eq? @key ${key}) - )`); - return qtype.value(query.matches(node)); -} -function getIntProperty(node, key) { - return getProperty(IntQ, node, key); -} -function getStringProperty(node, key) { - return getProperty(StringQ, node, key); -} -function getStringArrayProperty(node, key) { - return getProperty(StringArrayQ, node, key); -} -// TODO: add more policy types -const PolicyTypes = [ - BooleanPolicy, - IntPolicy, - StringEnumPolicy, - StringPolicy, -]; -function getPolicy(moduleName, configurationNode, settingNode, policyNode, categories) { - const name = getStringProperty(policyNode, 'name'); - if (!name) { - throw new Error(`Missing required 'name' property.`); - } - else if (isNlsString(name)) { - throw new Error(`Property 'name' should be a literal string.`); - } - const categoryName = getStringProperty(configurationNode, 'title'); - if (!categoryName) { - throw new Error(`Missing required 'title' property.`); - } - else if (!isNlsString(categoryName)) { - throw new Error(`Property 'title' should be localized.`); - } - const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`; - let category = categories.get(categoryKey); - if (!category) { - category = { moduleName, name: categoryName }; - categories.set(categoryKey, category); - } - const minimumVersion = getStringProperty(policyNode, 'minimumVersion'); - if (!minimumVersion) { - throw new Error(`Missing required 'minimumVersion' property.`); - } - else if (isNlsString(minimumVersion)) { - throw new Error(`Property 'minimumVersion' should be a literal string.`); - } - const description = getStringProperty(settingNode, 'description'); - if (!description) { - throw new Error(`Missing required 'description' property.`); - } - if (!isNlsString(description)) { - throw new Error(`Property 'description' should be localized.`); - } - let result; - for (const policyType of PolicyTypes) { - if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) { - break; - } - } - if (!result) { - throw new Error(`Failed to parse policy '${name}'.`); - } - return result; -} -function getPolicies(moduleName, node) { - const query = new Parser.Query(typescript, ` - ( - (call_expression - function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration) - arguments: (arguments (object (pair - key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties) - value: (object (pair - key: [(property_identifier)(string)] - value: (object (pair - key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy) - value: (object) @policy - )) @setting - )) - )) @configuration) - ) - ) - `); - const categories = new Map(); - return query.matches(node).map(m => { - const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node; - const settingNode = m.captures.filter(c => c.name === 'setting')[0].node; - const policyNode = m.captures.filter(c => c.name === 'policy')[0].node; - return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories); - }); -} -async function getFiles(root) { - return new Promise((c, e) => { - const result = []; - const rg = (0, child_process_1.spawn)(ripgrep_1.rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]); - const stream = byline(rg.stdout.setEncoding('utf8')); - stream.on('data', path => result.push(path)); - stream.on('error', err => e(err)); - stream.on('end', () => c(result)); - }); -} -function renderADMX(regKey, versions, categories, policies) { - versions = versions.map(v => v.replace(/\./g, '_')); - return ` - - - - - - - - ${versions.map(v => ``).join(`\n `)} - - - - - ${categories.map(c => ``).join(`\n `)} - - - ${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)} - - -`; -} -function renderADML(appName, versions, categories, policies, translations) { - return ` - - - - - - ${appName} - ${versions.map(v => `${appName} >= ${v}`)} - ${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))} - ${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)} - - - ${policies.map(p => p.renderADMLPresentation()).join(`\n `)} - - - -`; -} -function renderGP(policies, translations) { - const appName = product.nameLong; - const regKey = product.win32RegValueName; - const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort(); - const categories = [...new Set(policies.map(p => p.category))]; - return { - admx: renderADMX(regKey, versions, categories, policies), - adml: [ - { languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) }, - ...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) })) - ] - }; -} -const Languages = { - 'fr': 'fr-fr', - 'it': 'it-it', - 'de': 'de-de', - 'es': 'es-es', - 'ru': 'ru-ru', - 'zh-hans': 'zh-cn', - 'zh-hant': 'zh-tw', - 'ja': 'ja-jp', - 'ko': 'ko-kr', - 'cs': 'cs-cz', - 'pt-br': 'pt-br', - 'tr': 'tr-tr', - 'pl': 'pl-pl', -}; -async function getLatestStableVersion(updateUrl) { - const res = await (0, node_fetch_1.default)(`${updateUrl}/api/update/darwin/stable/latest`); - const { name: version } = await res.json(); - return version; -} -async function getSpecificNLS(resourceUrlTemplate, languageId, version) { - const resource = { - publisher: 'ms-ceintl', - name: `vscode-language-pack-${languageId}`, - version, - path: 'extension/translations/main.i18n.json' - }; - const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key]); - const res = await (0, node_fetch_1.default)(url); - if (res.status !== 200) { - throw new Error(`[${res.status}] Error downloading language pack ${languageId}@${version}`); - } - const { contents: result } = await res.json(); - return result; -} -function previousVersion(version) { - const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)$/.exec(version); - return `${major}.${parseInt(minor) - 1}.${patch}`; -} -async function getNLS(resourceUrlTemplate, languageId, version) { - try { - return await getSpecificNLS(resourceUrlTemplate, languageId, version); - } - catch (err) { - if (/\[404\]/.test(err.message)) { - console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version...`); - return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(version)); - } - else { - throw err; - } - } -} -async function parsePolicies() { - const parser = new Parser(); - parser.setLanguage(typescript); - const files = await getFiles(process.cwd()); - const base = path.join(process.cwd(), 'src'); - const policies = []; - for (const file of files) { - const moduleName = path.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/'); - const contents = await fs_1.promises.readFile(file, { encoding: 'utf8' }); - const tree = parser.parse(contents); - policies.push(...getPolicies(moduleName, tree.rootNode)); - } - return policies; -} -async function getTranslations() { - const updateUrl = product.updateUrl; - if (!updateUrl) { - console.warn(`Skipping policy localization: No 'updateUrl' found in 'product.json'.`); - return []; - } - const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate; - if (!resourceUrlTemplate) { - console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`); - return []; - } - const version = await getLatestStableVersion(updateUrl); - const languageIds = Object.keys(Languages); - return await Promise.all(languageIds.map(languageId => getNLS(resourceUrlTemplate, languageId, version) - .then(languageTranslations => ({ languageId, languageTranslations })))); -} -async function main() { - const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]); - const { admx, adml } = await renderGP(policies, translations); - const root = '.build/policies/win32'; - await fs_1.promises.rm(root, { recursive: true, force: true }); - await fs_1.promises.mkdir(root, { recursive: true }); - await fs_1.promises.writeFile(path.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n')); - for (const { languageId, contents } of adml) { - const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]); - await fs_1.promises.mkdir(languagePath, { recursive: true }); - await fs_1.promises.writeFile(path.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n')); - } -} -if (require.main === module) { - main().catch(err => { - console.error(err); - process.exit(1); - }); -} diff --git a/build/lib/policies.ts b/build/lib/policies.ts deleted file mode 100644 index 487ef611fb..0000000000 --- a/build/lib/policies.ts +++ /dev/null @@ -1,697 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { spawn } from 'child_process'; -import { promises as fs } from 'fs'; -import * as path from 'path'; -import * as byline from 'byline'; -import { rgPath } from '@vscode/ripgrep'; -import * as Parser from 'tree-sitter'; -import fetch from 'node-fetch'; -const { typescript } = require('tree-sitter-typescript'); -const product = require('../../product.json'); - -type NlsString = { value: string; nlsKey: string }; - -function isNlsString(value: string | NlsString | undefined): value is NlsString { - return value ? typeof value !== 'string' : false; -} - -function isStringArray(value: (string | NlsString)[]): value is string[] { - return !value.some(s => isNlsString(s)); -} - -function isNlsStringArray(value: (string | NlsString)[]): value is NlsString[] { - return value.every(s => isNlsString(s)); -} - -interface Category { - readonly moduleName: string; - readonly name: NlsString; -} - -enum PolicyType { - StringEnum -} - -interface Policy { - readonly category: Category; - readonly minimumVersion: string; - renderADMX(regKey: string): string[]; - renderADMLStrings(translations?: LanguageTranslations): string[]; - renderADMLPresentation(): string; -} - -function renderADMLString(prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string { - let value: string | undefined; - - if (translations) { - const moduleTranslations = translations[moduleName]; - - if (moduleTranslations) { - value = moduleTranslations[nlsString.nlsKey]; - } - } - - if (!value) { - value = nlsString.value; - } - - return `${value}`; -} - -abstract class BasePolicy implements Policy { - constructor( - protected policyType: PolicyType, - protected name: string, - readonly category: Category, - readonly minimumVersion: string, - protected description: NlsString, - protected moduleName: string, - ) { } - - protected renderADMLString(nlsString: NlsString, translations?: LanguageTranslations): string { - return renderADMLString(this.name, this.moduleName, nlsString, translations); - } - - renderADMX(regKey: string) { - return [ - ``, - ` `, - ` `, - ` `, - ...this.renderADMXElements(), - ` `, - `` - ]; - } - - protected abstract renderADMXElements(): string[]; - - renderADMLStrings(translations?: LanguageTranslations) { - return [ - `${this.name}`, - this.renderADMLString(this.description, translations) - ]; - } - - renderADMLPresentation(): string { - return `${this.renderADMLPresentationContents()}`; - } - - protected abstract renderADMLPresentationContents(): string; -} - -class BooleanPolicy extends BasePolicy { - - static from( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - settingNode: Parser.SyntaxNode - ): BooleanPolicy | undefined { - const type = getStringProperty(settingNode, 'type'); - - if (type !== 'boolean') { - return undefined; - } - - return new BooleanPolicy(name, category, minimumVersion, description, moduleName); - } - - private constructor( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - ) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - } - - protected renderADMXElements(): string[] { - return [ - ``, - ` `, - `` - ]; - } - - renderADMLPresentationContents() { - return `${this.name}`; - } -} - -class IntPolicy extends BasePolicy { - - static from( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - settingNode: Parser.SyntaxNode - ): IntPolicy | undefined { - const type = getStringProperty(settingNode, 'type'); - - if (type !== 'number') { - return undefined; - } - - const defaultValue = getIntProperty(settingNode, 'default'); - - if (typeof defaultValue === 'undefined') { - throw new Error(`Missing required 'default' property.`); - } - - return new IntPolicy(name, category, minimumVersion, description, moduleName, defaultValue); - } - - private constructor( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - protected readonly defaultValue: number, - ) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - } - - protected renderADMXElements(): string[] { - return [ - `` - // `` - ]; - } - - renderADMLPresentationContents() { - return `${this.name}`; - } -} - -class StringPolicy extends BasePolicy { - - static from( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - settingNode: Parser.SyntaxNode - ): StringPolicy | undefined { - const type = getStringProperty(settingNode, 'type'); - - if (type !== 'string') { - return undefined; - } - - return new StringPolicy(name, category, minimumVersion, description, moduleName); - } - - private constructor( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - ) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - } - - protected renderADMXElements(): string[] { - return [``]; - } - - renderADMLPresentationContents() { - return ``; - } -} - -class StringEnumPolicy extends BasePolicy { - - static from( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - settingNode: Parser.SyntaxNode - ): StringEnumPolicy | undefined { - const type = getStringProperty(settingNode, 'type'); - - if (type !== 'string') { - return undefined; - } - - const enum_ = getStringArrayProperty(settingNode, 'enum'); - - if (!enum_) { - return undefined; - } - - if (!isStringArray(enum_)) { - throw new Error(`Property 'enum' should not be localized.`); - } - - const enumDescriptions = getStringArrayProperty(settingNode, 'enumDescriptions'); - - if (!enumDescriptions) { - throw new Error(`Missing required 'enumDescriptions' property.`); - } else if (!isNlsStringArray(enumDescriptions)) { - throw new Error(`Property 'enumDescriptions' should be localized.`); - } - - return new StringEnumPolicy(name, category, minimumVersion, description, moduleName, enum_, enumDescriptions); - } - - private constructor( - name: string, - category: Category, - minimumVersion: string, - description: NlsString, - moduleName: string, - protected enum_: string[], - protected enumDescriptions: NlsString[], - ) { - super(PolicyType.StringEnum, name, category, minimumVersion, description, moduleName); - } - - protected renderADMXElements(): string[] { - return [ - ``, - ...this.enum_.map((value, index) => ` ${value}`), - `` - ]; - } - - renderADMLStrings(translations?: LanguageTranslations) { - return [ - ...super.renderADMLStrings(translations), - ...this.enumDescriptions.map(e => this.renderADMLString(e, translations)) - ]; - } - - renderADMLPresentationContents() { - return ``; - } -} - -interface QType { - Q: string; - value(matches: Parser.QueryMatch[]): T | undefined; -} - -const IntQ: QType = { - Q: `(number) @value`, - - value(matches: Parser.QueryMatch[]): number | undefined { - const match = matches[0]; - - if (!match) { - return undefined; - } - - const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; - - if (!value) { - throw new Error(`Missing required 'value' property.`); - } - - return parseInt(value); - } -}; - -const StringQ: QType = { - Q: `[ - (string (string_fragment) @value) - (call_expression function: (identifier) @localizeFn arguments: (arguments (string (string_fragment) @nlsKey) (string (string_fragment) @value)) (#eq? @localizeFn localize)) - ]`, - - value(matches: Parser.QueryMatch[]): string | NlsString | undefined { - const match = matches[0]; - - if (!match) { - return undefined; - } - - const value = match.captures.filter(c => c.name === 'value')[0]?.node.text; - - if (!value) { - throw new Error(`Missing required 'value' property.`); - } - - const nlsKey = match.captures.filter(c => c.name === 'nlsKey')[0]?.node.text; - - if (nlsKey) { - return { value, nlsKey }; - } else { - return value; - } - } -}; - -const StringArrayQ: QType<(string | NlsString)[]> = { - Q: `(array ${StringQ.Q})`, - - value(matches: Parser.QueryMatch[]): (string | NlsString)[] | undefined { - if (matches.length === 0) { - return undefined; - } - - return matches.map(match => { - return StringQ.value([match]) as string | NlsString; - }); - } -}; - -function getProperty(qtype: QType, node: Parser.SyntaxNode, key: string): T | undefined { - const query = new Parser.Query( - typescript, - `( - (pair - key: [(property_identifier)(string)] @key - value: ${qtype.Q} - ) - (#eq? @key ${key}) - )` - ); - - return qtype.value(query.matches(node)); -} - -function getIntProperty(node: Parser.SyntaxNode, key: string): number | undefined { - return getProperty(IntQ, node, key); -} - -function getStringProperty(node: Parser.SyntaxNode, key: string): string | NlsString | undefined { - return getProperty(StringQ, node, key); -} - -function getStringArrayProperty(node: Parser.SyntaxNode, key: string): (string | NlsString)[] | undefined { - return getProperty(StringArrayQ, node, key); -} - -// TODO: add more policy types -const PolicyTypes = [ - BooleanPolicy, - IntPolicy, - StringEnumPolicy, - StringPolicy, -]; - -function getPolicy( - moduleName: string, - configurationNode: Parser.SyntaxNode, - settingNode: Parser.SyntaxNode, - policyNode: Parser.SyntaxNode, - categories: Map -): Policy { - const name = getStringProperty(policyNode, 'name'); - - if (!name) { - throw new Error(`Missing required 'name' property.`); - } else if (isNlsString(name)) { - throw new Error(`Property 'name' should be a literal string.`); - } - - const categoryName = getStringProperty(configurationNode, 'title'); - - if (!categoryName) { - throw new Error(`Missing required 'title' property.`); - } else if (!isNlsString(categoryName)) { - throw new Error(`Property 'title' should be localized.`); - } - - const categoryKey = `${categoryName.nlsKey}:${categoryName.value}`; - let category = categories.get(categoryKey); - - if (!category) { - category = { moduleName, name: categoryName }; - categories.set(categoryKey, category); - } - - const minimumVersion = getStringProperty(policyNode, 'minimumVersion'); - - if (!minimumVersion) { - throw new Error(`Missing required 'minimumVersion' property.`); - } else if (isNlsString(minimumVersion)) { - throw new Error(`Property 'minimumVersion' should be a literal string.`); - } - - const description = getStringProperty(settingNode, 'description'); - - if (!description) { - throw new Error(`Missing required 'description' property.`); - } if (!isNlsString(description)) { - throw new Error(`Property 'description' should be localized.`); - } - - let result: Policy | undefined; - - for (const policyType of PolicyTypes) { - if (result = policyType.from(name, category, minimumVersion, description, moduleName, settingNode)) { - break; - } - } - - if (!result) { - throw new Error(`Failed to parse policy '${name}'.`); - } - - return result; -} - -function getPolicies(moduleName: string, node: Parser.SyntaxNode): Policy[] { - const query = new Parser.Query(typescript, ` - ( - (call_expression - function: (member_expression property: (property_identifier) @registerConfigurationFn) (#eq? @registerConfigurationFn registerConfiguration) - arguments: (arguments (object (pair - key: [(property_identifier)(string)] @propertiesKey (#eq? @propertiesKey properties) - value: (object (pair - key: [(property_identifier)(string)] - value: (object (pair - key: [(property_identifier)(string)] @policyKey (#eq? @policyKey policy) - value: (object) @policy - )) @setting - )) - )) @configuration) - ) - ) - `); - - const categories = new Map(); - - return query.matches(node).map(m => { - const configurationNode = m.captures.filter(c => c.name === 'configuration')[0].node; - const settingNode = m.captures.filter(c => c.name === 'setting')[0].node; - const policyNode = m.captures.filter(c => c.name === 'policy')[0].node; - return getPolicy(moduleName, configurationNode, settingNode, policyNode, categories); - }); -} - -async function getFiles(root: string): Promise { - return new Promise((c, e) => { - const result: string[] = []; - const rg = spawn(rgPath, ['-l', 'registerConfiguration\\(', '-g', 'src/**/*.ts', '-g', '!src/**/test/**', root]); - const stream = byline(rg.stdout.setEncoding('utf8')); - stream.on('data', path => result.push(path)); - stream.on('error', err => e(err)); - stream.on('end', () => c(result)); - }); -} - -function renderADMX(regKey: string, versions: string[], categories: Category[], policies: Policy[]) { - versions = versions.map(v => v.replace(/\./g, '_')); - - return ` - - - - - - - - ${versions.map(v => ``).join(`\n `)} - - - - - ${categories.map(c => ``).join(`\n `)} - - - ${policies.map(p => p.renderADMX(regKey)).flat().join(`\n `)} - - -`; -} - -function renderADML(appName: string, versions: string[], categories: Category[], policies: Policy[], translations?: LanguageTranslations) { - return ` - - - - - - ${appName} - ${versions.map(v => `${appName} >= ${v}`)} - ${categories.map(c => renderADMLString('Category', c.moduleName, c.name, translations))} - ${policies.map(p => p.renderADMLStrings(translations)).flat().join(`\n `)} - - - ${policies.map(p => p.renderADMLPresentation()).join(`\n `)} - - - -`; -} - -function renderGP(policies: Policy[], translations: Translations) { - const appName = product.nameLong; - const regKey = product.win32RegValueName; - - const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort(); - const categories = [...new Set(policies.map(p => p.category))]; - - return { - admx: renderADMX(regKey, versions, categories, policies), - adml: [ - { languageId: 'en-us', contents: renderADML(appName, versions, categories, policies) }, - ...translations.map(({ languageId, languageTranslations }) => - ({ languageId, contents: renderADML(appName, versions, categories, policies, languageTranslations) })) - ] - }; -} - -const Languages = { - 'fr': 'fr-fr', - 'it': 'it-it', - 'de': 'de-de', - 'es': 'es-es', - 'ru': 'ru-ru', - 'zh-hans': 'zh-cn', - 'zh-hant': 'zh-tw', - 'ja': 'ja-jp', - 'ko': 'ko-kr', - 'cs': 'cs-cz', - 'pt-br': 'pt-br', - 'tr': 'tr-tr', - 'pl': 'pl-pl', -}; - -type LanguageTranslations = { [moduleName: string]: { [nlsKey: string]: string } }; -type Translations = { languageId: string; languageTranslations: LanguageTranslations }[]; - -async function getLatestStableVersion(updateUrl: string) { - const res = await fetch(`${updateUrl}/api/update/darwin/stable/latest`); - const { name: version } = await res.json() as { name: string }; - return version; -} - -async function getSpecificNLS(resourceUrlTemplate: string, languageId: string, version: string) { - const resource = { - publisher: 'ms-ceintl', - name: `vscode-language-pack-${languageId}`, - version, - path: 'extension/translations/main.i18n.json' - }; - - const url = resourceUrlTemplate.replace(/\{([^}]+)\}/g, (_, key) => resource[key as keyof typeof resource]); - const res = await fetch(url); - - if (res.status !== 200) { - throw new Error(`[${res.status}] Error downloading language pack ${languageId}@${version}`); - } - - const { contents: result } = await res.json() as { contents: LanguageTranslations }; - return result; -} - -function previousVersion(version: string): string { - const [, major, minor, patch] = /^(\d+)\.(\d+)\.(\d+)$/.exec(version)!; - return `${major}.${parseInt(minor) - 1}.${patch}`; -} - -async function getNLS(resourceUrlTemplate: string, languageId: string, version: string) { - try { - return await getSpecificNLS(resourceUrlTemplate, languageId, version); - } catch (err) { - if (/\[404\]/.test(err.message)) { - console.warn(`Language pack ${languageId}@${version} is missing. Downloading previous version...`); - return await getSpecificNLS(resourceUrlTemplate, languageId, previousVersion(version)); - } else { - throw err; - } - } -} - -async function parsePolicies(): Promise { - const parser = new Parser(); - parser.setLanguage(typescript); - - const files = await getFiles(process.cwd()); - const base = path.join(process.cwd(), 'src'); - const policies = []; - - for (const file of files) { - const moduleName = path.relative(base, file).replace(/\.ts$/i, '').replace(/\\/g, '/'); - const contents = await fs.readFile(file, { encoding: 'utf8' }); - const tree = parser.parse(contents); - policies.push(...getPolicies(moduleName, tree.rootNode)); - } - - return policies; -} - -async function getTranslations(): Promise { - const updateUrl = product.updateUrl; - - if (!updateUrl) { - console.warn(`Skipping policy localization: No 'updateUrl' found in 'product.json'.`); - return []; - } - - const resourceUrlTemplate = product.extensionsGallery?.resourceUrlTemplate; - - if (!resourceUrlTemplate) { - console.warn(`Skipping policy localization: No 'resourceUrlTemplate' found in 'product.json'.`); - return []; - } - - const version = await getLatestStableVersion(updateUrl); - const languageIds = Object.keys(Languages); - - return await Promise.all(languageIds.map( - languageId => getNLS(resourceUrlTemplate, languageId, version) - .then(languageTranslations => ({ languageId, languageTranslations })) - )); -} - -async function main() { - const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]); - const { admx, adml } = await renderGP(policies, translations); - - const root = '.build/policies/win32'; - await fs.rm(root, { recursive: true, force: true }); - await fs.mkdir(root, { recursive: true }); - - await fs.writeFile(path.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n')); - - for (const { languageId, contents } of adml) { - const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId as keyof typeof Languages]); - await fs.mkdir(languagePath, { recursive: true }); - await fs.writeFile(path.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n')); - } -} - -if (require.main === module) { - main().catch(err => { - console.error(err); - process.exit(1); - }); -} diff --git a/build/lib/preLaunch.js b/build/lib/preLaunch.js index 558dda6655..5cfce3e39d 100644 --- a/build/lib/preLaunch.js +++ b/build/lib/preLaunch.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); // @ts-check const path = require("path"); diff --git a/build/lib/preLaunch.ts b/build/lib/preLaunch.ts index 0de0d5fc58..3498e57c70 100644 --- a/build/lib/preLaunch.ts +++ b/build/lib/preLaunch.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + // @ts-check import * as path from 'path'; diff --git a/build/lib/reporter.js b/build/lib/reporter.js index 94df910908..55feaf80ce 100644 --- a/build/lib/reporter.js +++ b/build/lib/reporter.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.createReporter = void 0; const es = require("event-stream"); diff --git a/build/lib/reporter.ts b/build/lib/reporter.ts index 93e300e473..2bf8c6a048 100644 --- a/build/lib/reporter.ts +++ b/build/lib/reporter.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as es from 'event-stream'; import * as _ from 'underscore'; import * as fancyLog from 'fancy-log'; diff --git a/build/lib/snapshotLoader.js b/build/lib/snapshotLoader.js index 70c27a87bf..822b9b2609 100644 --- a/build/lib/snapshotLoader.js +++ b/build/lib/snapshotLoader.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; var snaps; (function (snaps) { const fs = require('fs'); diff --git a/build/lib/snapshotLoader.ts b/build/lib/snapshotLoader.ts index d82217959a..6826711822 100644 --- a/build/lib/snapshotLoader.ts +++ b/build/lib/snapshotLoader.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + namespace snaps { const fs = require('fs'); diff --git a/build/lib/standalone.js b/build/lib/standalone.js index f41b489ddb..027ee9ee63 100644 --- a/build/lib/standalone.js +++ b/build/lib/standalone.js @@ -10,7 +10,7 @@ const path = require("path"); const tss = require("./treeshaking"); const REPO_ROOT = path.join(__dirname, '../../'); const SRC_DIR = path.join(REPO_ROOT, 'src'); -const dirCache = {}; +let dirCache = {}; function writeFile(filePath, contents) { function ensureDirs(dirPath) { if (dirCache[dirPath]) { @@ -54,13 +54,13 @@ function extractEditor(options) { options.typings.push(`../node_modules/@types/${type}/index.d.ts`); }); } - const result = tss.shake(options); - for (const fileName in result) { + let result = tss.shake(options); + for (let fileName in result) { if (result.hasOwnProperty(fileName)) { writeFile(path.join(options.destRoot, fileName), result[fileName]); } } - const copied = {}; + let copied = {}; const copyFile = (fileName) => { if (copied[fileName]) { return; @@ -73,7 +73,7 @@ function extractEditor(options) { const writeOutputFile = (fileName, contents) => { writeFile(path.join(options.destRoot, fileName), contents); }; - for (const fileName in result) { + for (let fileName in result) { if (result.hasOwnProperty(fileName)) { const fileContents = result[fileName]; const info = ts.preProcessFile(fileContents); @@ -103,12 +103,13 @@ function extractEditor(options) { delete tsConfig.compilerOptions.moduleResolution; writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); [ - 'vs/css.build.ts', - 'vs/css.ts', + 'vs/css.build.js', + 'vs/css.d.ts', + 'vs/css.js', 'vs/loader.js', - 'vs/loader.d.ts', - 'vs/nls.build.ts', - 'vs/nls.ts', + 'vs/nls.build.js', + 'vs/nls.d.ts', + 'vs/nls.js', 'vs/nls.mock.ts', ].forEach(copyFile); } @@ -119,7 +120,7 @@ function createESMSourcesAndResources2(options) { const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder); const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); const getDestAbsoluteFilePath = (file) => { - const dest = options.renames[file.replace(/\\/g, '/')] || file; + let dest = options.renames[file.replace(/\\/g, '/')] || file; if (dest === 'tsconfig.json') { return path.join(OUT_FOLDER, `tsconfig.json`); } @@ -193,7 +194,7 @@ function createESMSourcesAndResources2(options) { if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') { dir += '/'; } - const result = []; + let result = []; _walkDirRecursive(dir, result, dir.length); return result; } @@ -215,7 +216,7 @@ function createESMSourcesAndResources2(options) { } writeFile(absoluteFilePath, contents); function toggleComments(fileContents) { - const lines = fileContents.split(/\r\n|\r|\n/); + let lines = fileContents.split(/\r\n|\r|\n/); let mode = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i]; @@ -278,14 +279,14 @@ function transportCSS(module, enqueue, write) { let DATA = ';base64,' + fileContents.toString('base64'); if (!forceBase64 && /\.svg$/.test(url)) { // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris - const newText = fileContents.toString() + let newText = fileContents.toString() .replace(/"/g, '\'') .replace(//g, '%3E') .replace(/&/g, '%26') .replace(/#/g, '%23') .replace(/\s+/g, ' '); - const encodedData = ',' + newText; + let encodedData = ',' + newText; if (encodedData.length < DATA.length) { DATA = encodedData; } diff --git a/build/lib/standalone.ts b/build/lib/standalone.ts index 430785e828..16ab27516c 100644 --- a/build/lib/standalone.ts +++ b/build/lib/standalone.ts @@ -10,7 +10,7 @@ import * as tss from './treeshaking'; const REPO_ROOT = path.join(__dirname, '../../'); const SRC_DIR = path.join(REPO_ROOT, 'src'); -const dirCache: { [dir: string]: boolean } = {}; +let dirCache: { [dir: string]: boolean } = {}; function writeFile(filePath: string, contents: Buffer | string): void { function ensureDirs(dirPath: string): void { @@ -63,13 +63,13 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str }); } - const result = tss.shake(options); - for (const fileName in result) { + let result = tss.shake(options); + for (let fileName in result) { if (result.hasOwnProperty(fileName)) { writeFile(path.join(options.destRoot, fileName), result[fileName]); } } - const copied: { [fileName: string]: boolean } = {}; + let copied: { [fileName: string]: boolean } = {}; const copyFile = (fileName: string) => { if (copied[fileName]) { return; @@ -82,7 +82,7 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str const writeOutputFile = (fileName: string, contents: string | Buffer) => { writeFile(path.join(options.destRoot, fileName), contents); }; - for (const fileName in result) { + for (let fileName in result) { if (result.hasOwnProperty(fileName)) { const fileContents = result[fileName]; const info = ts.preProcessFile(fileContents); @@ -115,12 +115,13 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t')); [ - 'vs/css.build.ts', - 'vs/css.ts', + 'vs/css.build.js', + 'vs/css.d.ts', + 'vs/css.js', 'vs/loader.js', - 'vs/loader.d.ts', - 'vs/nls.build.ts', - 'vs/nls.ts', + 'vs/nls.build.js', + 'vs/nls.d.ts', + 'vs/nls.js', 'vs/nls.mock.ts', ].forEach(copyFile); } @@ -141,7 +142,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder); const getDestAbsoluteFilePath = (file: string): string => { - const dest = options.renames[file.replace(/\\/g, '/')] || file; + let dest = options.renames[file.replace(/\\/g, '/')] || file; if (dest === 'tsconfig.json') { return path.join(OUT_FOLDER, `tsconfig.json`); } @@ -228,7 +229,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { if (dir.charAt(dir.length - 1) !== '/' || dir.charAt(dir.length - 1) !== '\\') { dir += '/'; } - const result: string[] = []; + let result: string[] = []; _walkDirRecursive(dir, result, dir.length); return result; } @@ -252,7 +253,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void { writeFile(absoluteFilePath, contents); function toggleComments(fileContents: string): string { - const lines = fileContents.split(/\r\n|\r|\n/); + let lines = fileContents.split(/\r\n|\r|\n/); let mode = 0; for (let i = 0; i < lines.length; i++) { const line = lines[i]; @@ -324,14 +325,14 @@ function transportCSS(module: string, enqueue: (module: string) => void, write: if (!forceBase64 && /\.svg$/.test(url)) { // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris - const newText = fileContents.toString() + let newText = fileContents.toString() .replace(/"/g, '\'') .replace(//g, '%3E') .replace(/&/g, '%26') .replace(/#/g, '%23') .replace(/\s+/g, ' '); - const encodedData = ',' + newText; + let encodedData = ',' + newText; if (encodedData.length < DATA.length) { DATA = encodedData; } diff --git a/build/lib/task.js b/build/lib/task.js index d844aeb273..f3a3fd8123 100644 --- a/build/lib/task.js +++ b/build/lib/task.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.define = exports.parallel = exports.series = void 0; const fancyLog = require("fancy-log"); diff --git a/build/lib/task.ts b/build/lib/task.ts index 954c2395c5..8b3d072386 100644 --- a/build/lib/task.ts +++ b/build/lib/task.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fancyLog from 'fancy-log'; import * as ansiColors from 'ansi-colors'; diff --git a/build/lib/treeshaking.js b/build/lib/treeshaking.js index b56520bd11..f20782dfc1 100644 --- a/build/lib/treeshaking.js +++ b/build/lib/treeshaking.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.shake = exports.toStringShakeLevel = exports.ShakeLevel = void 0; const fs = require("fs"); @@ -32,7 +32,7 @@ function printDiagnostics(options, diagnostics) { result += `${path.join(options.sourcesRoot, diag.file.fileName)}`; } if (diag.file && diag.start) { - const location = diag.file.getLineAndCharacterOfPosition(diag.start); + let location = diag.file.getLineAndCharacterOfPosition(diag.start); result += `:${location.line + 1}:${location.character}`; } result += ` - ` + JSON.stringify(diag.messageText); @@ -89,8 +89,6 @@ function discoverAndReadFiles(ts, options) { const in_queue = Object.create(null); const queue = []; const enqueue = (moduleId) => { - // To make the treeshaker work on windows... - moduleId = moduleId.replace(/\\/g, '/'); if (in_queue[moduleId]) { return; } @@ -152,7 +150,7 @@ function processLibFiles(ts, options) { result[key] = sourceText; // precess dependencies and "recurse" const info = ts.preProcessFile(sourceText); - for (const ref of info.libReferenceDirectives) { + for (let ref of info.libReferenceDirectives) { stack.push(ref.fileName); } } @@ -228,12 +226,6 @@ function getColor(node) { function setColor(node, color) { node.$$$color = color; } -function markNeededSourceFile(node) { - node.$$$neededSourceFile = true; -} -function isNeededSourceFile(node) { - return Boolean(node.$$$neededSourceFile); -} function nodeOrParentIsBlack(node) { while (node) { const color = getColor(node); @@ -359,19 +351,6 @@ function markNodes(ts, languageService, options) { } }); } - /** - * Return the parent of `node` which is an ImportDeclaration - */ - function findParentImportDeclaration(node) { - let _node = node; - do { - if (ts.isImportDeclaration(_node)) { - return _node; - } - _node = _node.parent; - } while (_node); - return null; - } function enqueue_gray(node) { if (nodeOrParentIsBlack(node) || getColor(node) === 1 /* Gray */) { return; @@ -439,8 +418,6 @@ function markNodes(ts, languageService, options) { console.warn(`Cannot find source file ${filename}`); return; } - // This source file should survive even if it is empty - markNeededSourceFile(sourceFile); enqueue_black(sourceFile); } function enqueueImport(node, importText) { @@ -492,11 +469,7 @@ function markNodes(ts, languageService, options) { const loop = (node) => { const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node); if (symbolImportNode) { - setColor(symbolImportNode, 2 /* NodeColor.Black */); - const importDeclarationNode = findParentImportDeclaration(symbolImportNode); - if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) { - enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text); - } + setColor(symbolImportNode, 2 /* Black */); } if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) { for (let i = 0, len = symbol.declarations.length; i < len; i++) { // {{SQL CARBON EDIT}} Compile fixes @@ -530,7 +503,7 @@ function markNodes(ts, languageService, options) { } // queue the heritage clauses if (declaration.heritageClauses) { - for (const heritageClause of declaration.heritageClauses) { + for (let heritageClause of declaration.heritageClauses) { enqueue_black(heritageClause); } } @@ -578,7 +551,7 @@ function generateResult(ts, languageService, shakeLevel) { if (!program) { throw new Error('Could not get program from language service'); } - const result = {}; + let result = {}; const writeFile = (filePath, contents) => { result[filePath] = contents; }; @@ -594,7 +567,7 @@ function generateResult(ts, languageService, shakeLevel) { } return; } - const text = sourceFile.text; + let text = sourceFile.text; let result = ''; function keep(node) { result += text.substring(node.pos, node.end); @@ -624,7 +597,7 @@ function generateResult(ts, languageService, shakeLevel) { } } else { - const survivingImports = []; + let survivingImports = []; for (const importNode of node.importClause.namedBindings.elements) { if (getColor(importNode) === 2 /* Black */) { survivingImports.push(importNode.getFullText(sourceFile)); @@ -653,7 +626,7 @@ function generateResult(ts, languageService, shakeLevel) { } if (ts.isExportDeclaration(node)) { if (node.exportClause && node.moduleSpecifier && ts.isNamedExports(node.exportClause)) { - const survivingExports = []; + let survivingExports = []; for (const exportSpecifier of node.exportClause.elements) { if (getColor(exportSpecifier) === 2 /* Black */) { survivingExports.push(exportSpecifier.getFullText(sourceFile)); @@ -674,8 +647,8 @@ function generateResult(ts, languageService, shakeLevel) { // keep method continue; } - const pos = member.pos - node.pos; - const end = member.end - node.pos; + let pos = member.pos - node.pos; + let end = member.end - node.pos; toWrite = toWrite.substring(0, pos) + toWrite.substring(end); } return write(toWrite); @@ -688,23 +661,11 @@ function generateResult(ts, languageService, shakeLevel) { } if (getColor(sourceFile) !== 2 /* Black */) { if (!nodeOrChildIsBlack(sourceFile)) { - // none of the elements are reachable - if (isNeededSourceFile(sourceFile)) { - // this source file must be written, even if nothing is used from it - // because there is an import somewhere for it. - // However, TS complains with empty files with the error "x" is not a module, - // so we will export a dummy variable - result = 'export const __dummy = 0;'; - } - else { - // don't write this file at all! - return; - } - } - else { - sourceFile.forEachChild(writeMarkedNodes); - result += sourceFile.endOfFileToken.getFullText(sourceFile); + // none of the elements are reachable => don't write this file at all! + return; } + sourceFile.forEachChild(writeMarkedNodes); + result += sourceFile.endOfFileToken.getFullText(sourceFile); } else { result = text; @@ -878,4 +839,3 @@ function getTokenAtPosition(ts, sourceFile, position, allowPositionInLeadingTriv return current; } } -//#endregion diff --git a/build/lib/treeshaking.ts b/build/lib/treeshaking.ts index 84f8aebbda..e067fd2838 100644 --- a/build/lib/treeshaking.ts +++ b/build/lib/treeshaking.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as fs from 'fs'; import * as path from 'path'; import type * as ts from 'typescript'; @@ -71,7 +73,7 @@ function printDiagnostics(options: ITreeShakingOptions, diagnostics: ReadonlyArr result += `${path.join(options.sourcesRoot, diag.file.fileName)}`; } if (diag.file && diag.start) { - const location = diag.file.getLineAndCharacterOfPosition(diag.start); + let location = diag.file.getLineAndCharacterOfPosition(diag.start); result += `:${location.line + 1}:${location.character}`; } result += ` - ` + JSON.stringify(diag.messageText); @@ -142,8 +144,6 @@ function discoverAndReadFiles(ts: typeof import('typescript'), options: ITreeSha const queue: string[] = []; const enqueue = (moduleId: string) => { - // To make the treeshaker work on windows... - moduleId = moduleId.replace(/\\/g, '/'); if (in_queue[moduleId]) { return; } @@ -216,7 +216,7 @@ function processLibFiles(ts: typeof import('typescript'), options: ITreeShakingO // precess dependencies and "recurse" const info = ts.preProcessFile(sourceText); - for (const ref of info.libReferenceDirectives) { + for (let ref of info.libReferenceDirectives) { stack.push(ref.fileName); } } @@ -307,12 +307,6 @@ function getColor(node: ts.Node): NodeColor { function setColor(node: ts.Node, color: NodeColor): void { (node).$$$color = color; } -function markNeededSourceFile(node: ts.SourceFile): void { - (node).$$$neededSourceFile = true; -} -function isNeededSourceFile(node: ts.SourceFile): boolean { - return Boolean((node).$$$neededSourceFile); -} function nodeOrParentIsBlack(node: ts.Node): boolean { while (node) { const color = getColor(node); @@ -455,20 +449,6 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language }); } - /** - * Return the parent of `node` which is an ImportDeclaration - */ - function findParentImportDeclaration(node: ts.Declaration): ts.ImportDeclaration | null { - let _node: ts.Node = node; - do { - if (ts.isImportDeclaration(_node)) { - return _node; - } - _node = _node.parent; - } while (_node); - return null; - } - function enqueue_gray(node: ts.Node): void { if (nodeOrParentIsBlack(node) || getColor(node) === NodeColor.Gray) { return; @@ -551,8 +531,6 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language console.warn(`Cannot find source file ${filename}`); return; } - // This source file should survive even if it is empty - markNeededSourceFile(sourceFile); enqueue_black(sourceFile); } @@ -612,10 +590,6 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node); if (symbolImportNode) { setColor(symbolImportNode, NodeColor.Black); - const importDeclarationNode = findParentImportDeclaration(symbolImportNode); - if (importDeclarationNode && ts.isStringLiteral(importDeclarationNode.moduleSpecifier)) { - enqueueImport(importDeclarationNode, importDeclarationNode.moduleSpecifier.text); - } } if (isSymbolWithDeclarations(symbol) && !nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol)) { @@ -655,7 +629,7 @@ function markNodes(ts: typeof import('typescript'), languageService: ts.Language // queue the heritage clauses if (declaration.heritageClauses) { - for (const heritageClause of declaration.heritageClauses) { + for (let heritageClause of declaration.heritageClauses) { enqueue_black(heritageClause); } } @@ -708,7 +682,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan throw new Error('Could not get program from language service'); } - const result: ITreeShakingResult = {}; + let result: ITreeShakingResult = {}; const writeFile = (filePath: string, contents: string): void => { result[filePath] = contents; }; @@ -726,7 +700,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan return; } - const text = sourceFile.text; + let text = sourceFile.text; let result = ''; function keep(node: ts.Node): void { @@ -760,7 +734,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan return keep(node); } } else { - const survivingImports: string[] = []; + let survivingImports: string[] = []; for (const importNode of node.importClause.namedBindings.elements) { if (getColor(importNode) === NodeColor.Black) { survivingImports.push(importNode.getFullText(sourceFile)); @@ -788,7 +762,7 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan if (ts.isExportDeclaration(node)) { if (node.exportClause && node.moduleSpecifier && ts.isNamedExports(node.exportClause)) { - const survivingExports: string[] = []; + let survivingExports: string[] = []; for (const exportSpecifier of node.exportClause.elements) { if (getColor(exportSpecifier) === NodeColor.Black) { survivingExports.push(exportSpecifier.getFullText(sourceFile)); @@ -811,8 +785,8 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan continue; } - const pos = member.pos - node.pos; - const end = member.end - node.pos; + let pos = member.pos - node.pos; + let end = member.end - node.pos; toWrite = toWrite.substring(0, pos) + toWrite.substring(end); } return write(toWrite); @@ -828,21 +802,11 @@ function generateResult(ts: typeof import('typescript'), languageService: ts.Lan if (getColor(sourceFile) !== NodeColor.Black) { if (!nodeOrChildIsBlack(sourceFile)) { - // none of the elements are reachable - if (isNeededSourceFile(sourceFile)) { - // this source file must be written, even if nothing is used from it - // because there is an import somewhere for it. - // However, TS complains with empty files with the error "x" is not a module, - // so we will export a dummy variable - result = 'export const __dummy = 0;'; - } else { - // don't write this file at all! - return; - } - } else { - sourceFile.forEachChild(writeMarkedNodes); - result += sourceFile.endOfFileToken.getFullText(sourceFile); + // none of the elements are reachable => don't write this file at all! + return; } + sourceFile.forEachChild(writeMarkedNodes); + result += sourceFile.endOfFileToken.getFullText(sourceFile); } else { result = text; } diff --git a/build/lib/tsb/builder.js b/build/lib/tsb/builder.js deleted file mode 100644 index be74a30a17..0000000000 --- a/build/lib/tsb/builder.js +++ /dev/null @@ -1,491 +0,0 @@ -"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 }); -exports.createTypeScriptBuilder = exports.CancellationToken = void 0; -const fs_1 = require("fs"); -const path = require("path"); -const crypto = require("crypto"); -const utils = require("./utils"); -const colors = require("ansi-colors"); -const ts = require("typescript"); -const Vinyl = require("vinyl"); -var CancellationToken; -(function (CancellationToken) { - CancellationToken.None = { - isCancellationRequested() { return false; } - }; -})(CancellationToken = exports.CancellationToken || (exports.CancellationToken = {})); -function normalize(path) { - return path.replace(/\\/g, '/'); -} -function createTypeScriptBuilder(config, projectFile, cmd) { - const _log = config.logFn; - const host = new LanguageServiceHost(cmd, projectFile, _log); - const service = ts.createLanguageService(host, ts.createDocumentRegistry()); - const lastBuildVersion = Object.create(null); - const lastDtsHash = Object.create(null); - const userWantsDeclarations = cmd.options.declaration; - let oldErrors = Object.create(null); - let headUsed = process.memoryUsage().heapUsed; - let emitSourceMapsInStream = true; - // always emit declaraction files - host.getCompilationSettings().declaration = true; - function file(file) { - // support gulp-sourcemaps - if (file.sourceMap) { - emitSourceMapsInStream = false; - } - if (!file.contents) { - host.removeScriptSnapshot(file.path); - } - else { - host.addScriptSnapshot(file.path, new VinylScriptSnapshot(file)); - } - } - function baseFor(snapshot) { - if (snapshot instanceof VinylScriptSnapshot) { - return cmd.options.outDir || snapshot.getBase(); - } - else { - return ''; - } - } - function isExternalModule(sourceFile) { - return sourceFile.externalModuleIndicator - || /declare\s+module\s+('|")(.+)\1/.test(sourceFile.getText()); - } - function build(out, onError, token = CancellationToken.None) { - function checkSyntaxSoon(fileName) { - return new Promise(resolve => { - process.nextTick(function () { - if (!host.getScriptSnapshot(fileName, false)) { - resolve([]); // no script, no problems - } - else { - resolve(service.getSyntacticDiagnostics(fileName)); - } - }); - }); - } - function checkSemanticsSoon(fileName) { - return new Promise(resolve => { - process.nextTick(function () { - if (!host.getScriptSnapshot(fileName, false)) { - resolve([]); // no script, no problems - } - else { - resolve(service.getSemanticDiagnostics(fileName)); - } - }); - }); - } - function emitSoon(fileName) { - return new Promise(resolve => { - process.nextTick(function () { - if (/\.d\.ts$/.test(fileName)) { - // if it's already a d.ts file just emit it signature - const snapshot = host.getScriptSnapshot(fileName); - const signature = crypto.createHash('md5') - .update(snapshot.getText(0, snapshot.getLength())) - .digest('base64'); - return resolve({ - fileName, - signature, - files: [] - }); - } - const output = service.getEmitOutput(fileName); - const files = []; - let signature; - for (const file of output.outputFiles) { - if (!emitSourceMapsInStream && /\.js\.map$/.test(file.name)) { - continue; - } - if (/\.d\.ts$/.test(file.name)) { - signature = crypto.createHash('md5') - .update(file.text) - .digest('base64'); - if (!userWantsDeclarations) { - // don't leak .d.ts files if users don't want them - continue; - } - } - const vinyl = new Vinyl({ - path: file.name, - contents: Buffer.from(file.text), - base: !config._emitWithoutBasePath && baseFor(host.getScriptSnapshot(fileName)) || undefined - }); - if (!emitSourceMapsInStream && /\.js$/.test(file.name)) { - const sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0]; - if (sourcemapFile) { - const extname = path.extname(vinyl.relative); - const basename = path.basename(vinyl.relative, extname); - const dirname = path.dirname(vinyl.relative); - const tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts'; - const sourceMap = JSON.parse(sourcemapFile.text); - sourceMap.sources[0] = tsname.replace(/\\/g, '/'); - vinyl.sourceMap = sourceMap; - } - } - files.push(vinyl); - } - resolve({ - fileName, - signature, - files - }); - }); - }); - } - const newErrors = Object.create(null); - const t1 = Date.now(); - const toBeEmitted = []; - const toBeCheckedSyntactically = []; - const toBeCheckedSemantically = []; - const filesWithChangedSignature = []; - const dependentFiles = []; - const newLastBuildVersion = new Map(); - for (const fileName of host.getScriptFileNames()) { - if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { - toBeEmitted.push(fileName); - toBeCheckedSyntactically.push(fileName); - toBeCheckedSemantically.push(fileName); - } - } - return new Promise(resolve => { - const semanticCheckInfo = new Map(); - const seenAsDependentFile = new Set(); - function workOnNext() { - let promise; - // let fileName: string; - // someone told us to stop this - if (token.isCancellationRequested()) { - _log('[CANCEL]', '>>This compile run was cancelled<<'); - newLastBuildVersion.clear(); - resolve(); - return; - } - // (1st) emit code - else if (toBeEmitted.length) { - const fileName = toBeEmitted.pop(); - promise = emitSoon(fileName).then(value => { - for (const file of value.files) { - _log('[emit code]', file.path); - out(file); - } - // remember when this was build - newLastBuildVersion.set(fileName, host.getScriptVersion(fileName)); - // remeber the signature - if (value.signature && lastDtsHash[fileName] !== value.signature) { - lastDtsHash[fileName] = value.signature; - filesWithChangedSignature.push(fileName); - } - }).catch(e => { - // can't just skip this or make a result up.. - host.error(`ERROR emitting ${fileName}`); - host.error(e); - }); - } - // (2nd) check syntax - else if (toBeCheckedSyntactically.length) { - const fileName = toBeCheckedSyntactically.pop(); - _log('[check syntax]', fileName); - promise = checkSyntaxSoon(fileName).then(diagnostics => { - delete oldErrors[fileName]; - if (diagnostics.length > 0) { - diagnostics.forEach(d => onError(d)); - newErrors[fileName] = diagnostics; - // stop the world when there are syntax errors - toBeCheckedSyntactically.length = 0; - toBeCheckedSemantically.length = 0; - filesWithChangedSignature.length = 0; - } - }); - } - // (3rd) check semantics - else if (toBeCheckedSemantically.length) { - let fileName = toBeCheckedSemantically.pop(); - while (fileName && semanticCheckInfo.has(fileName)) { - fileName = toBeCheckedSemantically.pop(); - } - if (fileName) { - _log('[check semantics]', fileName); - promise = checkSemanticsSoon(fileName).then(diagnostics => { - delete oldErrors[fileName]; - semanticCheckInfo.set(fileName, diagnostics.length); - if (diagnostics.length > 0) { - diagnostics.forEach(d => onError(d)); - newErrors[fileName] = diagnostics; - } - }); - } - } - // (4th) check dependents - else if (filesWithChangedSignature.length) { - while (filesWithChangedSignature.length) { - const fileName = filesWithChangedSignature.pop(); - if (!isExternalModule(service.getProgram().getSourceFile(fileName))) { - _log('[check semantics*]', fileName + ' is an internal module and it has changed shape -> check whatever hasn\'t been checked yet'); - toBeCheckedSemantically.push(...host.getScriptFileNames()); - filesWithChangedSignature.length = 0; - dependentFiles.length = 0; - break; - } - host.collectDependents(fileName, dependentFiles); - } - } - // (5th) dependents contd - else if (dependentFiles.length) { - let fileName = dependentFiles.pop(); - while (fileName && seenAsDependentFile.has(fileName)) { - fileName = dependentFiles.pop(); - } - if (fileName) { - seenAsDependentFile.add(fileName); - const value = semanticCheckInfo.get(fileName); - if (value === 0) { - // already validated successfully -> look at dependents next - host.collectDependents(fileName, dependentFiles); - } - else if (typeof value === 'undefined') { - // first validate -> look at dependents next - dependentFiles.push(fileName); - toBeCheckedSemantically.push(fileName); - } - } - } - // (last) done - else { - resolve(); - return; - } - if (!promise) { - promise = Promise.resolve(); - } - promise.then(function () { - // change to change - process.nextTick(workOnNext); - }).catch(err => { - console.error(err); - }); - } - workOnNext(); - }).then(() => { - // store the build versions to not rebuilt the next time - newLastBuildVersion.forEach((value, key) => { - lastBuildVersion[key] = value; - }); - // print old errors and keep them - utils.collections.forEach(oldErrors, entry => { - entry.value.forEach(diag => onError(diag)); - newErrors[entry.key] = entry.value; - }); - oldErrors = newErrors; - // print stats - const headNow = process.memoryUsage().heapUsed; - const MB = 1024 * 1024; - _log('[tsb]', `time: ${colors.yellow((Date.now() - t1) + 'ms')} + \nmem: ${colors.cyan(Math.ceil(headNow / MB) + 'MB')} ${colors.bgCyan('delta: ' + Math.ceil((headNow - headUsed) / MB))}`); - headUsed = headNow; - }); - } - return { - file, - build, - languageService: service - }; -} -exports.createTypeScriptBuilder = createTypeScriptBuilder; -class ScriptSnapshot { - constructor(text, mtime) { - this._text = text; - this._mtime = mtime; - } - getVersion() { - return this._mtime.toUTCString(); - } - getText(start, end) { - return this._text.substring(start, end); - } - getLength() { - return this._text.length; - } - getChangeRange(_oldSnapshot) { - return undefined; - } -} -class VinylScriptSnapshot extends ScriptSnapshot { - constructor(file) { - super(file.contents.toString(), file.stat.mtime); - this._base = file.base; - } - getBase() { - return this._base; - } -} -class LanguageServiceHost { - constructor(_cmdLine, _projectPath, _log) { - this._cmdLine = _cmdLine; - this._projectPath = _projectPath; - this._log = _log; - this.directoryExists = ts.sys.directoryExists; - this.getDirectories = ts.sys.getDirectories; - this.fileExists = ts.sys.fileExists; - this.readFile = ts.sys.readFile; - this.readDirectory = ts.sys.readDirectory; - this._snapshots = Object.create(null); - this._filesInProject = new Set(_cmdLine.fileNames); - this._filesAdded = new Set(); - this._dependencies = new utils.graph.Graph(s => s); - this._dependenciesRecomputeList = []; - this._fileNameToDeclaredModule = Object.create(null); - this._projectVersion = 1; - } - log(_s) { - // console.log(s); - } - trace(_s) { - // console.log(s); - } - error(s) { - console.error(s); - } - getCompilationSettings() { - return this._cmdLine.options; - } - getProjectVersion() { - return String(this._projectVersion); - } - getScriptFileNames() { - const res = Object.keys(this._snapshots).filter(path => this._filesInProject.has(path) || this._filesAdded.has(path)); - return res; - } - getScriptVersion(filename) { - filename = normalize(filename); - const result = this._snapshots[filename]; - if (result) { - return result.getVersion(); - } - return 'UNKNWON_FILE_' + Math.random().toString(16).slice(2); - } - getScriptSnapshot(filename, resolve = true) { - filename = normalize(filename); - let result = this._snapshots[filename]; - if (!result && resolve) { - try { - result = new VinylScriptSnapshot(new Vinyl({ - path: filename, - contents: (0, fs_1.readFileSync)(filename), - base: this.getCompilationSettings().outDir, - stat: (0, fs_1.statSync)(filename) - })); - this.addScriptSnapshot(filename, result); - } - catch (e) { - // ignore - } - } - return result; - } - addScriptSnapshot(filename, snapshot) { - this._projectVersion++; - filename = normalize(filename); - const old = this._snapshots[filename]; - if (!old && !this._filesInProject.has(filename) && !filename.endsWith('.d.ts')) { - // ^^^^^^^^^^^^^^^^^^^^^^^^^^ - // not very proper! - this._filesAdded.add(filename); - } - if (!old || old.getVersion() !== snapshot.getVersion()) { - this._dependenciesRecomputeList.push(filename); - const node = this._dependencies.lookup(filename); - if (node) { - node.outgoing = Object.create(null); - } - // (cheap) check for declare module - LanguageServiceHost._declareModule.lastIndex = 0; - let match; - while ((match = LanguageServiceHost._declareModule.exec(snapshot.getText(0, snapshot.getLength())))) { - let declaredModules = this._fileNameToDeclaredModule[filename]; - if (!declaredModules) { - this._fileNameToDeclaredModule[filename] = declaredModules = []; - } - declaredModules.push(match[2]); - } - } - this._snapshots[filename] = snapshot; - return old; - } - removeScriptSnapshot(filename) { - this._filesInProject.delete(filename); - this._filesAdded.delete(filename); - this._projectVersion++; - filename = normalize(filename); - delete this._fileNameToDeclaredModule[filename]; - return delete this._snapshots[filename]; - } - getCurrentDirectory() { - return path.dirname(this._projectPath); - } - getDefaultLibFileName(options) { - return ts.getDefaultLibFilePath(options); - } - // ---- dependency management - collectDependents(filename, target) { - while (this._dependenciesRecomputeList.length) { - this._processFile(this._dependenciesRecomputeList.pop()); - } - filename = normalize(filename); - const node = this._dependencies.lookup(filename); - if (node) { - utils.collections.forEach(node.incoming, entry => target.push(entry.key)); - } - } - _processFile(filename) { - if (filename.match(/.*\.d\.ts$/)) { - return; - } - filename = normalize(filename); - const snapshot = this.getScriptSnapshot(filename); - if (!snapshot) { - this._log('processFile', `Missing snapshot for: ${filename}`); - return; - } - const info = ts.preProcessFile(snapshot.getText(0, snapshot.getLength()), true); - // (1) ///-references - info.referencedFiles.forEach(ref => { - const resolvedPath = path.resolve(path.dirname(filename), ref.fileName); - const normalizedPath = normalize(resolvedPath); - this._dependencies.inertEdge(filename, normalizedPath); - }); - // (2) import-require statements - info.importedFiles.forEach(ref => { - const stopDirname = normalize(this.getCurrentDirectory()); - let dirname = filename; - let found = false; - while (!found && dirname.indexOf(stopDirname) === 0) { - dirname = path.dirname(dirname); - const resolvedPath = path.resolve(dirname, ref.fileName); - const normalizedPath = normalize(resolvedPath); - if (this.getScriptSnapshot(normalizedPath + '.ts')) { - this._dependencies.inertEdge(filename, normalizedPath + '.ts'); - found = true; - } - else if (this.getScriptSnapshot(normalizedPath + '.d.ts')) { - this._dependencies.inertEdge(filename, normalizedPath + '.d.ts'); - found = true; - } - } - if (!found) { - for (const key in this._fileNameToDeclaredModule) { - if (this._fileNameToDeclaredModule[key] && ~this._fileNameToDeclaredModule[key].indexOf(ref.fileName)) { - this._dependencies.inertEdge(filename, key); - } - } - } - }); - } -} -LanguageServiceHost._declareModule = /declare\s+module\s+('|")(.+)\1/g; diff --git a/build/lib/tsb/builder.ts b/build/lib/tsb/builder.ts deleted file mode 100644 index f36fd1195e..0000000000 --- a/build/lib/tsb/builder.ts +++ /dev/null @@ -1,608 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { statSync, readFileSync } from 'fs'; -import * as path from 'path'; -import * as crypto from 'crypto'; -import * as utils from './utils'; -import * as colors from 'ansi-colors'; -import * as ts from 'typescript'; -import * as Vinyl from 'vinyl'; - -export interface IConfiguration { - logFn: (topic: string, message: string) => void; - _emitWithoutBasePath?: boolean; -} - -export interface CancellationToken { - isCancellationRequested(): boolean; -} - -export namespace CancellationToken { - export const None: CancellationToken = { - isCancellationRequested() { return false; } - }; -} - -export interface ITypeScriptBuilder { - build(out: (file: Vinyl) => void, onError: (err: ts.Diagnostic) => void, token?: CancellationToken): Promise; - file(file: Vinyl): void; - languageService: ts.LanguageService; -} - -function normalize(path: string): string { - return path.replace(/\\/g, '/'); -} - -export function createTypeScriptBuilder(config: IConfiguration, projectFile: string, cmd: ts.ParsedCommandLine): ITypeScriptBuilder { - - const _log = config.logFn; - - const host = new LanguageServiceHost(cmd, projectFile, _log); - const service = ts.createLanguageService(host, ts.createDocumentRegistry()); - const lastBuildVersion: { [path: string]: string } = Object.create(null); - const lastDtsHash: { [path: string]: string } = Object.create(null); - const userWantsDeclarations = cmd.options.declaration; - let oldErrors: { [path: string]: ts.Diagnostic[] } = Object.create(null); - let headUsed = process.memoryUsage().heapUsed; - let emitSourceMapsInStream = true; - - // always emit declaraction files - host.getCompilationSettings().declaration = true; - - function file(file: Vinyl): void { - // support gulp-sourcemaps - if ((file).sourceMap) { - emitSourceMapsInStream = false; - } - - if (!file.contents) { - host.removeScriptSnapshot(file.path); - } else { - host.addScriptSnapshot(file.path, new VinylScriptSnapshot(file)); - } - } - - function baseFor(snapshot: ScriptSnapshot): string { - if (snapshot instanceof VinylScriptSnapshot) { - return cmd.options.outDir || snapshot.getBase(); - } else { - return ''; - } - } - - function isExternalModule(sourceFile: ts.SourceFile): boolean { - return (sourceFile).externalModuleIndicator - || /declare\s+module\s+('|")(.+)\1/.test(sourceFile.getText()); - } - - function build(out: (file: Vinyl) => void, onError: (err: any) => void, token = CancellationToken.None): Promise { - - function checkSyntaxSoon(fileName: string): Promise { - return new Promise(resolve => { - process.nextTick(function () { - if (!host.getScriptSnapshot(fileName, false)) { - resolve([]); // no script, no problems - } else { - resolve(service.getSyntacticDiagnostics(fileName)); - } - }); - }); - } - - function checkSemanticsSoon(fileName: string): Promise { - return new Promise(resolve => { - process.nextTick(function () { - if (!host.getScriptSnapshot(fileName, false)) { - resolve([]); // no script, no problems - } else { - resolve(service.getSemanticDiagnostics(fileName)); - } - }); - }); - } - - function emitSoon(fileName: string): Promise<{ fileName: string; signature?: string; files: Vinyl[] }> { - - return new Promise(resolve => { - process.nextTick(function () { - - if (/\.d\.ts$/.test(fileName)) { - // if it's already a d.ts file just emit it signature - const snapshot = host.getScriptSnapshot(fileName); - const signature = crypto.createHash('md5') - .update(snapshot.getText(0, snapshot.getLength())) - .digest('base64'); - - return resolve({ - fileName, - signature, - files: [] - }); - } - - const output = service.getEmitOutput(fileName); - const files: Vinyl[] = []; - let signature: string | undefined; - - for (const file of output.outputFiles) { - if (!emitSourceMapsInStream && /\.js\.map$/.test(file.name)) { - continue; - } - - if (/\.d\.ts$/.test(file.name)) { - signature = crypto.createHash('md5') - .update(file.text) - .digest('base64'); - - if (!userWantsDeclarations) { - // don't leak .d.ts files if users don't want them - continue; - } - } - - const vinyl = new Vinyl({ - path: file.name, - contents: Buffer.from(file.text), - base: !config._emitWithoutBasePath && baseFor(host.getScriptSnapshot(fileName)) || undefined - }); - - if (!emitSourceMapsInStream && /\.js$/.test(file.name)) { - const sourcemapFile = output.outputFiles.filter(f => /\.js\.map$/.test(f.name))[0]; - - if (sourcemapFile) { - const extname = path.extname(vinyl.relative); - const basename = path.basename(vinyl.relative, extname); - const dirname = path.dirname(vinyl.relative); - const tsname = (dirname === '.' ? '' : dirname + '/') + basename + '.ts'; - - const sourceMap = JSON.parse(sourcemapFile.text); - sourceMap.sources[0] = tsname.replace(/\\/g, '/'); - (vinyl).sourceMap = sourceMap; - } - } - - files.push(vinyl); - } - - resolve({ - fileName, - signature, - files - }); - }); - }); - } - - const newErrors: { [path: string]: ts.Diagnostic[] } = Object.create(null); - const t1 = Date.now(); - - const toBeEmitted: string[] = []; - const toBeCheckedSyntactically: string[] = []; - const toBeCheckedSemantically: string[] = []; - const filesWithChangedSignature: string[] = []; - const dependentFiles: string[] = []; - const newLastBuildVersion = new Map(); - - for (const fileName of host.getScriptFileNames()) { - if (lastBuildVersion[fileName] !== host.getScriptVersion(fileName)) { - - toBeEmitted.push(fileName); - toBeCheckedSyntactically.push(fileName); - toBeCheckedSemantically.push(fileName); - } - } - - return new Promise(resolve => { - - const semanticCheckInfo = new Map(); - const seenAsDependentFile = new Set(); - - function workOnNext() { - - let promise: Promise | undefined; - // let fileName: string; - - // someone told us to stop this - if (token.isCancellationRequested()) { - _log('[CANCEL]', '>>This compile run was cancelled<<'); - newLastBuildVersion.clear(); - resolve(); - return; - } - - // (1st) emit code - else if (toBeEmitted.length) { - const fileName = toBeEmitted.pop()!; - promise = emitSoon(fileName).then(value => { - - for (const file of value.files) { - _log('[emit code]', file.path); - out(file); - } - - // remember when this was build - newLastBuildVersion.set(fileName, host.getScriptVersion(fileName)); - - // remeber the signature - if (value.signature && lastDtsHash[fileName] !== value.signature) { - lastDtsHash[fileName] = value.signature; - filesWithChangedSignature.push(fileName); - } - }).catch(e => { - // can't just skip this or make a result up.. - host.error(`ERROR emitting ${fileName}`); - host.error(e); - }); - } - - // (2nd) check syntax - else if (toBeCheckedSyntactically.length) { - const fileName = toBeCheckedSyntactically.pop()!; - _log('[check syntax]', fileName); - promise = checkSyntaxSoon(fileName).then(diagnostics => { - delete oldErrors[fileName]; - if (diagnostics.length > 0) { - diagnostics.forEach(d => onError(d)); - newErrors[fileName] = diagnostics; - - // stop the world when there are syntax errors - toBeCheckedSyntactically.length = 0; - toBeCheckedSemantically.length = 0; - filesWithChangedSignature.length = 0; - } - }); - } - - // (3rd) check semantics - else if (toBeCheckedSemantically.length) { - - let fileName = toBeCheckedSemantically.pop(); - while (fileName && semanticCheckInfo.has(fileName)) { - fileName = toBeCheckedSemantically.pop()!; - } - - if (fileName) { - _log('[check semantics]', fileName); - promise = checkSemanticsSoon(fileName).then(diagnostics => { - delete oldErrors[fileName!]; - semanticCheckInfo.set(fileName!, diagnostics.length); - if (diagnostics.length > 0) { - diagnostics.forEach(d => onError(d)); - newErrors[fileName!] = diagnostics; - } - }); - } - } - - // (4th) check dependents - else if (filesWithChangedSignature.length) { - while (filesWithChangedSignature.length) { - const fileName = filesWithChangedSignature.pop()!; - - if (!isExternalModule(service.getProgram()!.getSourceFile(fileName)!)) { - _log('[check semantics*]', fileName + ' is an internal module and it has changed shape -> check whatever hasn\'t been checked yet'); - toBeCheckedSemantically.push(...host.getScriptFileNames()); - filesWithChangedSignature.length = 0; - dependentFiles.length = 0; - break; - } - - host.collectDependents(fileName, dependentFiles); - } - } - - // (5th) dependents contd - else if (dependentFiles.length) { - let fileName = dependentFiles.pop(); - while (fileName && seenAsDependentFile.has(fileName)) { - fileName = dependentFiles.pop(); - } - if (fileName) { - seenAsDependentFile.add(fileName); - const value = semanticCheckInfo.get(fileName); - if (value === 0) { - // already validated successfully -> look at dependents next - host.collectDependents(fileName, dependentFiles); - - } else if (typeof value === 'undefined') { - // first validate -> look at dependents next - dependentFiles.push(fileName); - toBeCheckedSemantically.push(fileName); - } - } - } - - // (last) done - else { - resolve(); - return; - } - - if (!promise) { - promise = Promise.resolve(); - } - - promise.then(function () { - // change to change - process.nextTick(workOnNext); - }).catch(err => { - console.error(err); - }); - } - - workOnNext(); - - }).then(() => { - // store the build versions to not rebuilt the next time - newLastBuildVersion.forEach((value, key) => { - lastBuildVersion[key] = value; - }); - - // print old errors and keep them - utils.collections.forEach(oldErrors, entry => { - entry.value.forEach(diag => onError(diag)); - newErrors[entry.key] = entry.value; - }); - oldErrors = newErrors; - - // print stats - const headNow = process.memoryUsage().heapUsed; - const MB = 1024 * 1024; - _log( - '[tsb]', - `time: ${colors.yellow((Date.now() - t1) + 'ms')} + \nmem: ${colors.cyan(Math.ceil(headNow / MB) + 'MB')} ${colors.bgCyan('delta: ' + Math.ceil((headNow - headUsed) / MB))}` - ); - headUsed = headNow; - }); - } - - return { - file, - build, - languageService: service - }; -} - -class ScriptSnapshot implements ts.IScriptSnapshot { - - private readonly _text: string; - private readonly _mtime: Date; - - constructor(text: string, mtime: Date) { - this._text = text; - this._mtime = mtime; - } - - getVersion(): string { - return this._mtime.toUTCString(); - } - - getText(start: number, end: number): string { - return this._text.substring(start, end); - } - - getLength(): number { - return this._text.length; - } - - getChangeRange(_oldSnapshot: ts.IScriptSnapshot): ts.TextChangeRange | undefined { - return undefined; - } -} - -class VinylScriptSnapshot extends ScriptSnapshot { - - private readonly _base: string; - - constructor(file: Vinyl) { - super(file.contents!.toString(), file.stat!.mtime); - this._base = file.base; - } - - getBase(): string { - return this._base; - } -} - -class LanguageServiceHost implements ts.LanguageServiceHost { - - private readonly _snapshots: { [path: string]: ScriptSnapshot }; - private readonly _filesInProject: Set; - private readonly _filesAdded: Set; - private readonly _dependencies: utils.graph.Graph; - private readonly _dependenciesRecomputeList: string[]; - private readonly _fileNameToDeclaredModule: { [path: string]: string[] }; - - private _projectVersion: number; - - constructor( - private readonly _cmdLine: ts.ParsedCommandLine, - private readonly _projectPath: string, - private readonly _log: (topic: string, message: string) => void - ) { - this._snapshots = Object.create(null); - this._filesInProject = new Set(_cmdLine.fileNames); - this._filesAdded = new Set(); - this._dependencies = new utils.graph.Graph(s => s); - this._dependenciesRecomputeList = []; - this._fileNameToDeclaredModule = Object.create(null); - - this._projectVersion = 1; - } - - log(_s: string): void { - // console.log(s); - } - - trace(_s: string): void { - // console.log(s); - } - - error(s: string): void { - console.error(s); - } - - getCompilationSettings(): ts.CompilerOptions { - return this._cmdLine.options; - } - - getProjectVersion(): string { - return String(this._projectVersion); - } - - getScriptFileNames(): string[] { - const res = Object.keys(this._snapshots).filter(path => this._filesInProject.has(path) || this._filesAdded.has(path)); - return res; - } - - getScriptVersion(filename: string): string { - filename = normalize(filename); - const result = this._snapshots[filename]; - if (result) { - return result.getVersion(); - } - return 'UNKNWON_FILE_' + Math.random().toString(16).slice(2); - } - - getScriptSnapshot(filename: string, resolve: boolean = true): ScriptSnapshot { - filename = normalize(filename); - let result = this._snapshots[filename]; - if (!result && resolve) { - try { - result = new VinylScriptSnapshot(new Vinyl({ - path: filename, - contents: readFileSync(filename), - base: this.getCompilationSettings().outDir, - stat: statSync(filename) - })); - this.addScriptSnapshot(filename, result); - } catch (e) { - // ignore - } - } - return result; - } - - private static _declareModule = /declare\s+module\s+('|")(.+)\1/g; - - addScriptSnapshot(filename: string, snapshot: ScriptSnapshot): ScriptSnapshot { - this._projectVersion++; - filename = normalize(filename); - const old = this._snapshots[filename]; - if (!old && !this._filesInProject.has(filename) && !filename.endsWith('.d.ts')) { - // ^^^^^^^^^^^^^^^^^^^^^^^^^^ - // not very proper! - this._filesAdded.add(filename); - } - if (!old || old.getVersion() !== snapshot.getVersion()) { - this._dependenciesRecomputeList.push(filename); - const node = this._dependencies.lookup(filename); - if (node) { - node.outgoing = Object.create(null); - } - - // (cheap) check for declare module - LanguageServiceHost._declareModule.lastIndex = 0; - let match: RegExpExecArray | null | undefined; - while ((match = LanguageServiceHost._declareModule.exec(snapshot.getText(0, snapshot.getLength())))) { - let declaredModules = this._fileNameToDeclaredModule[filename]; - if (!declaredModules) { - this._fileNameToDeclaredModule[filename] = declaredModules = []; - } - declaredModules.push(match[2]); - } - } - this._snapshots[filename] = snapshot; - return old; - } - - removeScriptSnapshot(filename: string): boolean { - this._filesInProject.delete(filename); - this._filesAdded.delete(filename); - this._projectVersion++; - filename = normalize(filename); - delete this._fileNameToDeclaredModule[filename]; - return delete this._snapshots[filename]; - } - - getCurrentDirectory(): string { - return path.dirname(this._projectPath); - } - - getDefaultLibFileName(options: ts.CompilerOptions): string { - return ts.getDefaultLibFilePath(options); - } - - readonly directoryExists = ts.sys.directoryExists; - readonly getDirectories = ts.sys.getDirectories; - readonly fileExists = ts.sys.fileExists; - readonly readFile = ts.sys.readFile; - readonly readDirectory = ts.sys.readDirectory; - - // ---- dependency management - - collectDependents(filename: string, target: string[]): void { - while (this._dependenciesRecomputeList.length) { - this._processFile(this._dependenciesRecomputeList.pop()!); - } - filename = normalize(filename); - const node = this._dependencies.lookup(filename); - if (node) { - utils.collections.forEach(node.incoming, entry => target.push(entry.key)); - } - } - - _processFile(filename: string): void { - if (filename.match(/.*\.d\.ts$/)) { - return; - } - filename = normalize(filename); - const snapshot = this.getScriptSnapshot(filename); - if (!snapshot) { - this._log('processFile', `Missing snapshot for: ${filename}`); - return; - } - const info = ts.preProcessFile(snapshot.getText(0, snapshot.getLength()), true); - - // (1) ///-references - info.referencedFiles.forEach(ref => { - const resolvedPath = path.resolve(path.dirname(filename), ref.fileName); - const normalizedPath = normalize(resolvedPath); - - this._dependencies.inertEdge(filename, normalizedPath); - }); - - // (2) import-require statements - info.importedFiles.forEach(ref => { - const stopDirname = normalize(this.getCurrentDirectory()); - let dirname = filename; - let found = false; - - while (!found && dirname.indexOf(stopDirname) === 0) { - dirname = path.dirname(dirname); - const resolvedPath = path.resolve(dirname, ref.fileName); - const normalizedPath = normalize(resolvedPath); - - if (this.getScriptSnapshot(normalizedPath + '.ts')) { - this._dependencies.inertEdge(filename, normalizedPath + '.ts'); - found = true; - - } else if (this.getScriptSnapshot(normalizedPath + '.d.ts')) { - this._dependencies.inertEdge(filename, normalizedPath + '.d.ts'); - found = true; - } - } - - if (!found) { - for (const key in this._fileNameToDeclaredModule) { - if (this._fileNameToDeclaredModule[key] && ~this._fileNameToDeclaredModule[key].indexOf(ref.fileName)) { - this._dependencies.inertEdge(filename, key); - } - } - } - }); - } -} diff --git a/build/lib/tsb/index.js b/build/lib/tsb/index.js deleted file mode 100644 index a0b6423bb6..0000000000 --- a/build/lib/tsb/index.js +++ /dev/null @@ -1,130 +0,0 @@ -"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 }); -exports.create = void 0; -const Vinyl = require("vinyl"); -const through = require("through"); -const builder = require("./builder"); -const ts = require("typescript"); -const stream_1 = require("stream"); -const path_1 = require("path"); -const utils_1 = require("./utils"); -const fs_1 = require("fs"); -const log = require("fancy-log"); -const colors = require("ansi-colors"); -const transpiler_1 = require("./transpiler"); -class EmptyDuplex extends stream_1.Duplex { - _write(_chunk, _encoding, callback) { callback(); } - _read() { this.push(null); } -} -function createNullCompiler() { - const result = function () { return new EmptyDuplex(); }; - result.src = () => new EmptyDuplex(); - return result; -} -const _defaultOnError = (err) => console.log(JSON.stringify(err, null, 4)); -function create(projectPath, existingOptions, config, onError = _defaultOnError) { - function printDiagnostic(diag) { - if (!diag.file || !diag.start) { - onError(ts.flattenDiagnosticMessageText(diag.messageText, '\n')); - } - else { - const lineAndCh = diag.file.getLineAndCharacterOfPosition(diag.start); - onError(utils_1.strings.format('{0}({1},{2}): {3}', diag.file.fileName, lineAndCh.line + 1, lineAndCh.character + 1, ts.flattenDiagnosticMessageText(diag.messageText, '\n'))); - } - } - const parsed = ts.readConfigFile(projectPath, ts.sys.readFile); - if (parsed.error) { - printDiagnostic(parsed.error); - return createNullCompiler(); - } - const cmdLine = ts.parseJsonConfigFileContent(parsed.config, ts.sys, (0, path_1.dirname)(projectPath), existingOptions); - if (cmdLine.errors.length > 0) { - cmdLine.errors.forEach(printDiagnostic); - return createNullCompiler(); - } - function logFn(topic, message) { - if (config.verbose) { - log(colors.cyan(topic), message); - } - } - // FULL COMPILE stream doing transpile, syntax and semantic diagnostics - function createCompileStream(builder, token) { - return through(function (file) { - // give the file to the compiler - if (file.isStream()) { - this.emit('error', 'no support for streams'); - return; - } - builder.file(file); - }, function () { - // start the compilation process - builder.build(file => this.queue(file), printDiagnostic, token).catch(e => console.error(e)).then(() => this.queue(null)); - }); - } - // TRANSPILE ONLY stream doing just TS to JS conversion - function createTranspileStream(transpiler) { - return through(function (file) { - // give the file to the compiler - if (file.isStream()) { - this.emit('error', 'no support for streams'); - return; - } - if (!file.contents) { - return; - } - if (!config.transpileOnlyIncludesDts && file.path.endsWith('.d.ts')) { - return; - } - if (!transpiler.onOutfile) { - transpiler.onOutfile = file => this.queue(file); - } - transpiler.transpile(file); - }, function () { - transpiler.join().then(() => { - this.queue(null); - transpiler.onOutfile = undefined; - }); - }); - } - let result; - if (config.transpileOnly) { - const transpiler = new transpiler_1.Transpiler(logFn, printDiagnostic, projectPath, cmdLine); - result = (() => createTranspileStream(transpiler)); - } - else { - const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine); - result = ((token) => createCompileStream(_builder, token)); - } - result.src = (opts) => { - let _pos = 0; - const _fileNames = cmdLine.fileNames.slice(0); - return new class extends stream_1.Readable { - constructor() { - super({ objectMode: true }); - } - _read() { - let more = true; - let path; - for (; more && _pos < _fileNames.length; _pos++) { - path = _fileNames[_pos]; - more = this.push(new Vinyl({ - path, - contents: (0, fs_1.readFileSync)(path), - stat: (0, fs_1.statSync)(path), - cwd: opts && opts.cwd, - base: opts && opts.base || (0, path_1.dirname)(projectPath) - })); - } - if (_pos >= _fileNames.length) { - this.push(null); - } - } - }; - }; - return result; -} -exports.create = create; diff --git a/build/lib/tsb/index.ts b/build/lib/tsb/index.ts deleted file mode 100644 index 5c9175d8ab..0000000000 --- a/build/lib/tsb/index.ts +++ /dev/null @@ -1,164 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as Vinyl from 'vinyl'; -import * as through from 'through'; -import * as builder from './builder'; -import * as ts from 'typescript'; -import { Readable, Writable, Duplex } from 'stream'; -import { dirname } from 'path'; -import { strings } from './utils'; -import { readFileSync, statSync } from 'fs'; -import * as log from 'fancy-log'; -import colors = require('ansi-colors'); -import { Transpiler } from './transpiler'; - -export interface IncrementalCompiler { - (token?: any): Readable & Writable; - src(opts?: { cwd?: string; base?: string }): Readable; -} - -class EmptyDuplex extends Duplex { - _write(_chunk: any, _encoding: string, callback: (err?: Error) => void): void { callback(); } - _read() { this.push(null); } -} - -function createNullCompiler(): IncrementalCompiler { - const result: IncrementalCompiler = function () { return new EmptyDuplex(); }; - result.src = () => new EmptyDuplex(); - return result; -} - -const _defaultOnError = (err: string) => console.log(JSON.stringify(err, null, 4)); - -export function create( - projectPath: string, - existingOptions: Partial, - config: { verbose?: boolean; transpileOnly?: boolean; transpileOnlyIncludesDts?: boolean }, - onError: (message: string) => void = _defaultOnError -): IncrementalCompiler { - - function printDiagnostic(diag: ts.Diagnostic): void { - - if (!diag.file || !diag.start) { - onError(ts.flattenDiagnosticMessageText(diag.messageText, '\n')); - } else { - const lineAndCh = diag.file.getLineAndCharacterOfPosition(diag.start); - onError(strings.format('{0}({1},{2}): {3}', - diag.file.fileName, - lineAndCh.line + 1, - lineAndCh.character + 1, - ts.flattenDiagnosticMessageText(diag.messageText, '\n')) - ); - } - } - - const parsed = ts.readConfigFile(projectPath, ts.sys.readFile); - if (parsed.error) { - printDiagnostic(parsed.error); - return createNullCompiler(); - } - - const cmdLine = ts.parseJsonConfigFileContent(parsed.config, ts.sys, dirname(projectPath), existingOptions); - if (cmdLine.errors.length > 0) { - cmdLine.errors.forEach(printDiagnostic); - return createNullCompiler(); - } - - function logFn(topic: string, message: string): void { - if (config.verbose) { - log(colors.cyan(topic), message); - } - } - - // FULL COMPILE stream doing transpile, syntax and semantic diagnostics - function createCompileStream(builder: builder.ITypeScriptBuilder, token?: builder.CancellationToken): Readable & Writable { - - return through(function (this: through.ThroughStream, file: Vinyl) { - // give the file to the compiler - if (file.isStream()) { - this.emit('error', 'no support for streams'); - return; - } - builder.file(file); - - }, function (this: { queue(a: any): void }) { - // start the compilation process - builder.build( - file => this.queue(file), - printDiagnostic, - token - ).catch(e => console.error(e)).then(() => this.queue(null)); - }); - } - - // TRANSPILE ONLY stream doing just TS to JS conversion - function createTranspileStream(transpiler: Transpiler): Readable & Writable { - return through(function (this: through.ThroughStream & { queue(a: any): void }, file: Vinyl) { - // give the file to the compiler - if (file.isStream()) { - this.emit('error', 'no support for streams'); - return; - } - if (!file.contents) { - return; - } - if (!config.transpileOnlyIncludesDts && file.path.endsWith('.d.ts')) { - return; - } - - if (!transpiler.onOutfile) { - transpiler.onOutfile = file => this.queue(file); - } - - transpiler.transpile(file); - - }, function (this: { queue(a: any): void }) { - transpiler.join().then(() => { - this.queue(null); - transpiler.onOutfile = undefined; - }); - }); - } - - - let result: IncrementalCompiler; - if (config.transpileOnly) { - const transpiler = new Transpiler(logFn, printDiagnostic, projectPath, cmdLine); - result = (() => createTranspileStream(transpiler)); - } else { - const _builder = builder.createTypeScriptBuilder({ logFn }, projectPath, cmdLine); - result = ((token: builder.CancellationToken) => createCompileStream(_builder, token)); - } - - result.src = (opts?: { cwd?: string; base?: string }) => { - let _pos = 0; - const _fileNames = cmdLine.fileNames.slice(0); - return new class extends Readable { - constructor() { - super({ objectMode: true }); - } - _read() { - let more: boolean = true; - let path: string; - for (; more && _pos < _fileNames.length; _pos++) { - path = _fileNames[_pos]; - more = this.push(new Vinyl({ - path, - contents: readFileSync(path), - stat: statSync(path), - cwd: opts && opts.cwd, - base: opts && opts.base || dirname(projectPath) - })); - } - if (_pos >= _fileNames.length) { - this.push(null); - } - } - }; - }; - - return result; -} diff --git a/build/lib/tsb/transpiler.js b/build/lib/tsb/transpiler.js deleted file mode 100644 index 38e6b5c00e..0000000000 --- a/build/lib/tsb/transpiler.js +++ /dev/null @@ -1,220 +0,0 @@ -"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 }); -exports.Transpiler = void 0; -const ts = require("typescript"); -const threads = require("node:worker_threads"); -const Vinyl = require("vinyl"); -const node_os_1 = require("node:os"); -function transpile(tsSrc, options) { - const isAmd = /\n(import|export)/m.test(tsSrc); - if (!isAmd && options.compilerOptions?.module === ts.ModuleKind.AMD) { - // enforce NONE module-system for not-amd cases - options = { ...options, ...{ compilerOptions: { ...options.compilerOptions, module: ts.ModuleKind.None } } }; - } - const out = ts.transpileModule(tsSrc, options); - return { - jsSrc: out.outputText, - diag: out.diagnostics ?? [] - }; -} -if (!threads.isMainThread) { - // WORKER - threads.parentPort?.addListener('message', (req) => { - const res = { - jsSrcs: [], - diagnostics: [] - }; - for (const tsSrc of req.tsSrcs) { - const out = transpile(tsSrc, req.options); - res.jsSrcs.push(out.jsSrc); - res.diagnostics.push(out.diag); - } - threads.parentPort.postMessage(res); - }); -} -class TranspileWorker { - constructor(outFileFn) { - this.id = TranspileWorker.pool++; - this._worker = new threads.Worker(__filename); - this._durations = []; - this._worker.addListener('message', (res) => { - if (!this._pending) { - console.error('RECEIVING data WITHOUT request'); - return; - } - const [resolve, reject, files, options, t1] = this._pending; - const outFiles = []; - const diag = []; - for (let i = 0; i < res.jsSrcs.length; i++) { - // inputs and outputs are aligned across the arrays - const file = files[i]; - const jsSrc = res.jsSrcs[i]; - const diag = res.diagnostics[i]; - if (diag.length > 0) { - diag.push(...diag); - continue; - } - let SuffixTypes; - (function (SuffixTypes) { - SuffixTypes[SuffixTypes["Dts"] = 5] = "Dts"; - SuffixTypes[SuffixTypes["Ts"] = 3] = "Ts"; - SuffixTypes[SuffixTypes["Unknown"] = 0] = "Unknown"; - })(SuffixTypes || (SuffixTypes = {})); - const suffixLen = file.path.endsWith('.d.ts') ? 5 /* SuffixTypes.Dts */ - : file.path.endsWith('.ts') ? 3 /* SuffixTypes.Ts */ - : 0 /* SuffixTypes.Unknown */; - // check if output of a DTS-files isn't just "empty" and iff so - // skip this file - if (suffixLen === 5 /* SuffixTypes.Dts */ && _isDefaultEmpty(jsSrc)) { - continue; - } - const outBase = options.compilerOptions?.outDir ?? file.base; - const outPath = outFileFn(file.path); - outFiles.push(new Vinyl({ - path: outPath, - base: outBase, - contents: Buffer.from(jsSrc), - })); - } - this._pending = undefined; - this._durations.push(Date.now() - t1); - if (diag.length > 0) { - reject(diag); - } - else { - resolve(outFiles); - } - }); - } - terminate() { - // console.log(`Worker#${this.id} ENDS after ${this._durations.length} jobs (total: ${this._durations.reduce((p, c) => p + c, 0)}, avg: ${this._durations.reduce((p, c) => p + c, 0) / this._durations.length})`); - this._worker.terminate(); - } - get isBusy() { - return this._pending !== undefined; - } - next(files, options) { - if (this._pending !== undefined) { - throw new Error('BUSY'); - } - return new Promise((resolve, reject) => { - this._pending = [resolve, reject, files, options, Date.now()]; - const req = { - options, - tsSrcs: files.map(file => String(file.contents)) - }; - this._worker.postMessage(req); - }); - } -} -TranspileWorker.pool = 1; -class Transpiler { - constructor(logFn, _onError, configFilePath, _cmdLine) { - this._onError = _onError; - this._cmdLine = _cmdLine; - this._workerPool = []; - this._queue = []; - this._allJobs = []; - logFn('Transpile', `will use ${Transpiler.P} transpile worker`); - this._getOutputFileName = (file) => { - try { - // windows: path-sep normalizing - file = ts.normalizePath(file); - if (!_cmdLine.options.configFilePath) { - // this is needed for the INTERNAL getOutputFileNames-call below... - _cmdLine.options.configFilePath = configFilePath; - } - const isDts = file.endsWith('.d.ts'); - if (isDts) { - file = file.slice(0, -5) + '.ts'; - _cmdLine.fileNames.push(file); - } - const outfile = ts.getOutputFileNames(_cmdLine, file, true)[0]; - if (isDts) { - _cmdLine.fileNames.pop(); - } - return outfile; - } - catch (err) { - console.error(file, _cmdLine.fileNames); - console.error(err); - throw new err; - } - }; - } - async join() { - // wait for all penindg jobs - this._consumeQueue(); - await Promise.allSettled(this._allJobs); - this._allJobs.length = 0; - // terminate all worker - this._workerPool.forEach(w => w.terminate()); - this._workerPool.length = 0; - } - transpile(file) { - if (this._cmdLine.options.noEmit) { - // not doing ANYTHING here - return; - } - const newLen = this._queue.push(file); - if (newLen > Transpiler.P ** 2) { - this._consumeQueue(); - } - } - _consumeQueue() { - if (this._queue.length === 0) { - // no work... - return; - } - // kinda LAZYily create workers - if (this._workerPool.length === 0) { - for (let i = 0; i < Transpiler.P; i++) { - this._workerPool.push(new TranspileWorker(file => this._getOutputFileName(file))); - } - } - const freeWorker = this._workerPool.filter(w => !w.isBusy); - if (freeWorker.length === 0) { - // OK, they will pick up work themselves - return; - } - for (const worker of freeWorker) { - if (this._queue.length === 0) { - break; - } - const job = new Promise(resolve => { - const consume = () => { - const files = this._queue.splice(0, Transpiler.P); - if (files.length === 0) { - // DONE - resolve(undefined); - return; - } - // work on the NEXT file - // const [inFile, outFn] = req; - worker.next(files, { compilerOptions: this._cmdLine.options }).then(outFiles => { - if (this.onOutfile) { - outFiles.map(this.onOutfile, this); - } - consume(); - }).catch(err => { - this._onError(err); - }); - }; - consume(); - }); - this._allJobs.push(job); - } - } -} -exports.Transpiler = Transpiler; -Transpiler.P = Math.floor((0, node_os_1.cpus)().length * .5); -function _isDefaultEmpty(src) { - return src - .replace('"use strict";', '') - .replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1') - .trim().length === 0; -} diff --git a/build/lib/tsb/transpiler.ts b/build/lib/tsb/transpiler.ts deleted file mode 100644 index 267fef97ae..0000000000 --- a/build/lib/tsb/transpiler.ts +++ /dev/null @@ -1,285 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as ts from 'typescript'; -import * as threads from 'node:worker_threads'; -import * as Vinyl from 'vinyl'; -import { cpus } from 'node:os'; - -interface TranspileReq { - readonly tsSrcs: string[]; - readonly options: ts.TranspileOptions; -} - -interface TranspileRes { - readonly jsSrcs: string[]; - readonly diagnostics: ts.Diagnostic[][]; -} - -function transpile(tsSrc: string, options: ts.TranspileOptions): { jsSrc: string; diag: ts.Diagnostic[] } { - - const isAmd = /\n(import|export)/m.test(tsSrc); - if (!isAmd && options.compilerOptions?.module === ts.ModuleKind.AMD) { - // enforce NONE module-system for not-amd cases - options = { ...options, ...{ compilerOptions: { ...options.compilerOptions, module: ts.ModuleKind.None } } }; - } - const out = ts.transpileModule(tsSrc, options); - return { - jsSrc: out.outputText, - diag: out.diagnostics ?? [] - }; -} - -if (!threads.isMainThread) { - // WORKER - threads.parentPort?.addListener('message', (req: TranspileReq) => { - const res: TranspileRes = { - jsSrcs: [], - diagnostics: [] - }; - for (const tsSrc of req.tsSrcs) { - const out = transpile(tsSrc, req.options); - res.jsSrcs.push(out.jsSrc); - res.diagnostics.push(out.diag); - } - threads.parentPort!.postMessage(res); - }); -} - -class TranspileWorker { - - private static pool = 1; - - readonly id = TranspileWorker.pool++; - - private _worker = new threads.Worker(__filename); - private _pending?: [resolve: Function, reject: Function, file: Vinyl[], options: ts.TranspileOptions, t1: number]; - private _durations: number[] = []; - - constructor(outFileFn: (fileName: string) => string) { - - this._worker.addListener('message', (res: TranspileRes) => { - if (!this._pending) { - console.error('RECEIVING data WITHOUT request'); - return; - } - - const [resolve, reject, files, options, t1] = this._pending; - - const outFiles: Vinyl[] = []; - const diag: ts.Diagnostic[] = []; - - for (let i = 0; i < res.jsSrcs.length; i++) { - // inputs and outputs are aligned across the arrays - const file = files[i]; - const jsSrc = res.jsSrcs[i]; - const diag = res.diagnostics[i]; - - if (diag.length > 0) { - diag.push(...diag); - continue; - } - const enum SuffixTypes { - Dts = 5, - Ts = 3, - Unknown = 0 - } - const suffixLen = file.path.endsWith('.d.ts') ? SuffixTypes.Dts - : file.path.endsWith('.ts') ? SuffixTypes.Ts - : SuffixTypes.Unknown; - - // check if output of a DTS-files isn't just "empty" and iff so - // skip this file - if (suffixLen === SuffixTypes.Dts && _isDefaultEmpty(jsSrc)) { - continue; - } - - const outBase = options.compilerOptions?.outDir ?? file.base; - const outPath = outFileFn(file.path); - - outFiles.push(new Vinyl({ - path: outPath, - base: outBase, - contents: Buffer.from(jsSrc), - })); - } - - this._pending = undefined; - this._durations.push(Date.now() - t1); - - if (diag.length > 0) { - reject(diag); - } else { - resolve(outFiles); - } - }); - } - - terminate() { - // console.log(`Worker#${this.id} ENDS after ${this._durations.length} jobs (total: ${this._durations.reduce((p, c) => p + c, 0)}, avg: ${this._durations.reduce((p, c) => p + c, 0) / this._durations.length})`); - this._worker.terminate(); - } - - get isBusy() { - return this._pending !== undefined; - } - - next(files: Vinyl[], options: ts.TranspileOptions) { - if (this._pending !== undefined) { - throw new Error('BUSY'); - } - return new Promise((resolve, reject) => { - this._pending = [resolve, reject, files, options, Date.now()]; - const req: TranspileReq = { - options, - tsSrcs: files.map(file => String(file.contents)) - }; - this._worker.postMessage(req); - }); - } -} - - -export class Transpiler { - - static P = Math.floor(cpus().length * .5); - - private readonly _getOutputFileName: (name: string) => string; - - public onOutfile?: (file: Vinyl) => void; - - private _workerPool: TranspileWorker[] = []; - private _queue: Vinyl[] = []; - private _allJobs: Promise[] = []; - - constructor( - logFn: (topic: string, message: string) => void, - private readonly _onError: (err: any) => void, - configFilePath: string, - private readonly _cmdLine: ts.ParsedCommandLine - ) { - logFn('Transpile', `will use ${Transpiler.P} transpile worker`); - - - // very complicated logic to re-use TS internal functions to know the output path - // given a TS input path and its config - type InternalTsApi = typeof ts & { - normalizePath(path: string): string; - getOutputFileNames(commandLine: ts.ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; - }; - this._getOutputFileName = (file) => { - try { - - // windows: path-sep normalizing - file = (ts).normalizePath(file); - - if (!_cmdLine.options.configFilePath) { - // this is needed for the INTERNAL getOutputFileNames-call below... - _cmdLine.options.configFilePath = configFilePath; - } - const isDts = file.endsWith('.d.ts'); - if (isDts) { - file = file.slice(0, -5) + '.ts'; - _cmdLine.fileNames.push(file); - } - const outfile = (ts).getOutputFileNames(_cmdLine, file, true)[0]; - if (isDts) { - _cmdLine.fileNames.pop(); - } - return outfile; - - } catch (err) { - console.error(file, _cmdLine.fileNames); - console.error(err); - throw new err; - } - }; - } - - async join() { - // wait for all penindg jobs - this._consumeQueue(); - await Promise.allSettled(this._allJobs); - this._allJobs.length = 0; - - // terminate all worker - this._workerPool.forEach(w => w.terminate()); - this._workerPool.length = 0; - } - - - transpile(file: Vinyl) { - - if (this._cmdLine.options.noEmit) { - // not doing ANYTHING here - return; - } - - const newLen = this._queue.push(file); - if (newLen > Transpiler.P ** 2) { - this._consumeQueue(); - } - } - - private _consumeQueue(): void { - - if (this._queue.length === 0) { - // no work... - return; - } - - // kinda LAZYily create workers - if (this._workerPool.length === 0) { - for (let i = 0; i < Transpiler.P; i++) { - this._workerPool.push(new TranspileWorker(file => this._getOutputFileName(file))); - } - } - - const freeWorker = this._workerPool.filter(w => !w.isBusy); - if (freeWorker.length === 0) { - // OK, they will pick up work themselves - return; - } - - for (const worker of freeWorker) { - if (this._queue.length === 0) { - break; - } - - const job = new Promise(resolve => { - - const consume = () => { - const files = this._queue.splice(0, Transpiler.P); - if (files.length === 0) { - // DONE - resolve(undefined); - return; - } - // work on the NEXT file - // const [inFile, outFn] = req; - worker.next(files, { compilerOptions: this._cmdLine.options }).then(outFiles => { - if (this.onOutfile) { - outFiles.map(this.onOutfile, this); - } - consume(); - }).catch(err => { - this._onError(err); - }); - }; - - consume(); - }); - - this._allJobs.push(job); - } - } -} - -function _isDefaultEmpty(src: string): boolean { - return src - .replace('"use strict";', '') - .replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1') - .trim().length === 0; -} diff --git a/build/lib/tsb/utils.js b/build/lib/tsb/utils.js deleted file mode 100644 index cc8605758c..0000000000 --- a/build/lib/tsb/utils.js +++ /dev/null @@ -1,124 +0,0 @@ -"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 }); -exports.graph = exports.strings = exports.collections = void 0; -var collections; -(function (collections) { - const hasOwnProperty = Object.prototype.hasOwnProperty; - function lookup(collection, key) { - if (hasOwnProperty.call(collection, key)) { - return collection[key]; - } - return null; - } - collections.lookup = lookup; - function insert(collection, key, value) { - collection[key] = value; - } - collections.insert = insert; - function lookupOrInsert(collection, key, value) { - if (hasOwnProperty.call(collection, key)) { - return collection[key]; - } - else { - collection[key] = value; - return value; - } - } - collections.lookupOrInsert = lookupOrInsert; - function forEach(collection, callback) { - for (const key in collection) { - if (hasOwnProperty.call(collection, key)) { - callback({ - key: key, - value: collection[key] - }); - } - } - } - collections.forEach = forEach; - function contains(collection, key) { - return hasOwnProperty.call(collection, key); - } - collections.contains = contains; -})(collections = exports.collections || (exports.collections = {})); -var strings; -(function (strings) { - /** - * The empty string. The one and only. - */ - strings.empty = ''; - strings.eolUnix = '\r\n'; - function format(value, ...rest) { - return value.replace(/({\d+})/g, function (match) { - const index = Number(match.substring(1, match.length - 1)); - return String(rest[index]) || match; - }); - } - strings.format = format; -})(strings = exports.strings || (exports.strings = {})); -var graph; -(function (graph) { - function newNode(data) { - return { - data: data, - incoming: {}, - outgoing: {} - }; - } - graph.newNode = newNode; - class Graph { - constructor(_hashFn) { - this._hashFn = _hashFn; - this._nodes = {}; - // empty - } - traverse(start, inwards, callback) { - const startNode = this.lookup(start); - if (!startNode) { - return; - } - this._traverse(startNode, inwards, {}, callback); - } - _traverse(node, inwards, seen, callback) { - const key = this._hashFn(node.data); - if (collections.contains(seen, key)) { - return; - } - seen[key] = true; - callback(node.data); - const nodes = inwards ? node.outgoing : node.incoming; - collections.forEach(nodes, (entry) => this._traverse(entry.value, inwards, seen, callback)); - } - inertEdge(from, to) { - const fromNode = this.lookupOrInsertNode(from); - const toNode = this.lookupOrInsertNode(to); - fromNode.outgoing[this._hashFn(to)] = toNode; - toNode.incoming[this._hashFn(from)] = fromNode; - } - removeNode(data) { - const key = this._hashFn(data); - delete this._nodes[key]; - collections.forEach(this._nodes, (entry) => { - delete entry.value.outgoing[key]; - delete entry.value.incoming[key]; - }); - } - lookupOrInsertNode(data) { - const key = this._hashFn(data); - let node = collections.lookup(this._nodes, key); - if (!node) { - node = newNode(data); - this._nodes[key] = node; - } - return node; - } - lookup(data) { - return collections.lookup(this._nodes, this._hashFn(data)); - } - } - graph.Graph = Graph; -})(graph = exports.graph || (exports.graph = {})); diff --git a/build/lib/tsb/utils.ts b/build/lib/tsb/utils.ts deleted file mode 100644 index edeaa48cdf..0000000000 --- a/build/lib/tsb/utils.ts +++ /dev/null @@ -1,140 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export module collections { - - const hasOwnProperty = Object.prototype.hasOwnProperty; - - export function lookup(collection: { [keys: string]: T }, key: string): T | null { - if (hasOwnProperty.call(collection, key)) { - return collection[key]; - } - return null; - } - - export function insert(collection: { [keys: string]: T }, key: string, value: T): void { - collection[key] = value; - } - - export function lookupOrInsert(collection: { [keys: string]: T }, key: string, value: T): T { - if (hasOwnProperty.call(collection, key)) { - return collection[key]; - } else { - collection[key] = value; - return value; - } - } - - export function forEach(collection: { [keys: string]: T }, callback: (entry: { key: string; value: T }) => void): void { - for (const key in collection) { - if (hasOwnProperty.call(collection, key)) { - callback({ - key: key, - value: collection[key] - }); - } - } - } - - export function contains(collection: { [keys: string]: any }, key: string): boolean { - return hasOwnProperty.call(collection, key); - } -} - -export module strings { - - /** - * The empty string. The one and only. - */ - export const empty = ''; - - export const eolUnix = '\r\n'; - - export function format(value: string, ...rest: any[]): string { - return value.replace(/({\d+})/g, function (match) { - const index = Number(match.substring(1, match.length - 1)); - return String(rest[index]) || match; - }); - } -} - -export module graph { - - export interface Node { - data: T; - incoming: { [key: string]: Node }; - outgoing: { [key: string]: Node }; - } - - export function newNode(data: T): Node { - return { - data: data, - incoming: {}, - outgoing: {} - }; - } - - export class Graph { - - private _nodes: { [key: string]: Node } = {}; - - constructor(private _hashFn: (element: T) => string) { - // empty - } - - traverse(start: T, inwards: boolean, callback: (data: T) => void): void { - const startNode = this.lookup(start); - if (!startNode) { - return; - } - this._traverse(startNode, inwards, {}, callback); - } - - private _traverse(node: Node, inwards: boolean, seen: { [key: string]: boolean }, callback: (data: T) => void): void { - const key = this._hashFn(node.data); - if (collections.contains(seen, key)) { - return; - } - seen[key] = true; - callback(node.data); - const nodes = inwards ? node.outgoing : node.incoming; - collections.forEach(nodes, (entry) => this._traverse(entry.value, inwards, seen, callback)); - } - - inertEdge(from: T, to: T): void { - const fromNode = this.lookupOrInsertNode(from); - const toNode = this.lookupOrInsertNode(to); - - fromNode.outgoing[this._hashFn(to)] = toNode; - toNode.incoming[this._hashFn(from)] = fromNode; - } - - removeNode(data: T): void { - const key = this._hashFn(data); - delete this._nodes[key]; - collections.forEach(this._nodes, (entry) => { - delete entry.value.outgoing[key]; - delete entry.value.incoming[key]; - }); - } - - lookupOrInsertNode(data: T): Node { - const key = this._hashFn(data); - let node = collections.lookup(this._nodes, key); - - if (!node) { - node = newNode(data); - this._nodes[key] = node; - } - - return node; - } - - lookup(data: T): Node | null { - return collections.lookup(this._nodes, this._hashFn(data)); - } - } - -} diff --git a/build/lib/typings/gulp-tsb.d.ts b/build/lib/typings/gulp-tsb.d.ts new file mode 100644 index 0000000000..df9bb34d3f --- /dev/null +++ b/build/lib/typings/gulp-tsb.d.ts @@ -0,0 +1,18 @@ + + +declare module "gulp-tsb" { + + export interface ICancellationToken { + isCancellationRequested(): boolean; + } + + export interface IncrementalCompiler { + (token?: ICancellationToken): NodeJS.ReadWriteStream; + src(opts?: { + cwd?: string; + base?: string; + }): NodeJS.ReadStream; + } + export function create(projectPath: string, existingOptions: any, verbose?: boolean, onError?: (message: any) => void): IncrementalCompiler; + +} diff --git a/build/lib/util.js b/build/lib/util.js index d790efd354..fa2a6b9561 100644 --- a/build/lib/util.js +++ b/build/lib/util.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildWebNodePaths = exports.createExternalLoaderConfig = exports.acquireWebNodePaths = exports.getElectronVersion = exports.streamToPromise = exports.versionStringToNumber = exports.filter = exports.rebase = exports.getVersion = exports.ensureDir = exports.rreddir = exports.rimraf = exports.rewriteSourceMappingURL = exports.stripSourceMappingURL = exports.loadSourcemaps = exports.cleanNodeModules = exports.skipDirectories = exports.toFileUri = exports.setExecutableBit = exports.fixWin32DirectoryPermissions = exports.debounce = exports.incremental = void 0; const es = require("event-stream"); @@ -240,7 +240,7 @@ function _rreaddir(dirPath, prepend, result) { } } function rreddir(dirPath) { - const result = []; + let result = []; _rreaddir(dirPath, '', result); return result; } @@ -337,13 +337,6 @@ function acquireWebNodePaths() { } nodePaths[key] = entryPoint; } - // @TODO lramos15 can we make this dynamic like the rest of the node paths - // Add these paths as well for 1DS SDK dependencies. - // Not sure why given the 1DS entrypoint then requires these modules - // they are not fetched from the right location and instead are fetched from out/ - nodePaths['@microsoft/dynamicproto-js'] = 'lib/dist/umd/dynamicproto-js.min.js'; - nodePaths['@microsoft/applicationinsights-shims'] = 'dist/umd/applicationinsights-shims.min.js'; - nodePaths['@microsoft/applicationinsights-core-js'] = 'browser/applicationinsights-core-js.min.js'; return nodePaths; } exports.acquireWebNodePaths = acquireWebNodePaths; @@ -352,7 +345,7 @@ function createExternalLoaderConfig(webEndpoint, commit, quality) { return undefined; } webEndpoint = webEndpoint + `/${quality}/${commit}`; - const nodePaths = acquireWebNodePaths(); + let nodePaths = acquireWebNodePaths(); Object.keys(nodePaths).map(function (key, _) { nodePaths[key] = `${webEndpoint}/node_modules/${key}/${nodePaths[key]}`; }); diff --git a/build/lib/util.ts b/build/lib/util.ts index f0e9e0c634..e5ce6c26f1 100644 --- a/build/lib/util.ts +++ b/build/lib/util.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import * as es from 'event-stream'; import _debounce = require('debounce'); import * as _filter from 'gulp-filter'; @@ -304,7 +306,7 @@ function _rreaddir(dirPath: string, prepend: string, result: string[]): void { } export function rreddir(dirPath: string): string[] { - const result: string[] = []; + let result: string[] = []; _rreaddir(dirPath, '', result); return result; } @@ -412,13 +414,6 @@ export function acquireWebNodePaths() { nodePaths[key] = entryPoint; } - // @TODO lramos15 can we make this dynamic like the rest of the node paths - // Add these paths as well for 1DS SDK dependencies. - // Not sure why given the 1DS entrypoint then requires these modules - // they are not fetched from the right location and instead are fetched from out/ - nodePaths['@microsoft/dynamicproto-js'] = 'lib/dist/umd/dynamicproto-js.min.js'; - nodePaths['@microsoft/applicationinsights-shims'] = 'dist/umd/applicationinsights-shims.min.js'; - nodePaths['@microsoft/applicationinsights-core-js'] = 'browser/applicationinsights-core-js.min.js'; return nodePaths; } @@ -427,7 +422,7 @@ export function createExternalLoaderConfig(webEndpoint?: string, commit?: string return undefined; } webEndpoint = webEndpoint + `/${quality}/${commit}`; - const nodePaths = acquireWebNodePaths(); + let nodePaths = acquireWebNodePaths(); Object.keys(nodePaths).map(function (key, _) { nodePaths[key] = `${webEndpoint}/node_modules/${key}/${nodePaths[key]}`; }); diff --git a/build/lib/watch/.gitignore b/build/lib/watch/.gitignore new file mode 100644 index 0000000000..d777dcaa9d --- /dev/null +++ b/build/lib/watch/.gitignore @@ -0,0 +1 @@ +.yarnrc \ No newline at end of file diff --git a/build/lib/watch/package.json b/build/lib/watch/package.json new file mode 100644 index 0000000000..e2e4f55202 --- /dev/null +++ b/build/lib/watch/package.json @@ -0,0 +1,12 @@ +{ + "name": "watch", + "version": "1.0.0", + "description": "", + "author": "Microsoft ", + "private": true, + "license": "MIT", + "devDependencies": {}, + "dependencies": { + "vscode-gulp-watch": "^5.0.3" + } +} diff --git a/build/lib/watch/yarn.lock b/build/lib/watch/yarn.lock new file mode 100644 index 0000000000..258c0edada --- /dev/null +++ b/build/lib/watch/yarn.lock @@ -0,0 +1,400 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +anymatch@^3.1.1, anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +chokidar@3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.3.1" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +fancy-log@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +first-chunk-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" + integrity sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA= + dependencies: + readable-stream "^2.0.2" + +fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== + +glob-parent@^5.1.1, glob-parent@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +graceful-fs@^4.1.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +plugin-error@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +readable-stream@^2.0.2, readable-stream@^2.3.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-bom-buf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" + integrity sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI= + dependencies: + is-utf8 "^0.2.1" + +strip-bom-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca" + integrity sha1-+H217yYT9paKpUWr/h7HKLaoKco= + dependencies: + first-chunk-stream "^2.0.0" + strip-bom "^2.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +vinyl-file@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-3.0.0.tgz#b104d9e4409ffa325faadd520642d0a3b488b365" + integrity sha1-sQTZ5ECf+jJfqt1SBkLQo7SIs2U= + dependencies: + graceful-fs "^4.1.2" + pify "^2.3.0" + strip-bom-buf "^1.0.0" + strip-bom-stream "^2.0.0" + vinyl "^2.0.1" + +vinyl@^2.0.1, vinyl@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vscode-gulp-watch@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/vscode-gulp-watch/-/vscode-gulp-watch-5.0.3.tgz#1ca1c03581d43692ecb1fe0b9afd4256faeb701b" + integrity sha512-MTUp2yLE9CshhkNSNV58EQNxQSeF8lIj3mkXZX9a1vAk+EQNM2PAYdPUDSd/P/08W3PMHGznEiZyfK7JAjLosg== + dependencies: + ansi-colors "4.1.1" + anymatch "^3.1.1" + chokidar "3.5.1" + fancy-log "^1.3.3" + glob-parent "^5.1.1" + normalize-path "^3.0.0" + object-assign "^4.1.1" + plugin-error "1.0.1" + readable-stream "^3.6.0" + vinyl "^2.2.0" + vinyl-file "^3.0.0" diff --git a/build/linux/debian/dep-lists.js b/build/linux/debian/dep-lists.js deleted file mode 100644 index 3db2ef1abf..0000000000 --- a/build/linux/debian/dep-lists.js +++ /dev/null @@ -1,156 +0,0 @@ -"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 }); -exports.referenceGeneratedDepsByArch = exports.bundledDeps = exports.recommendedDeps = exports.additionalDeps = void 0; -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/additional_deps -// Additional dependencies not in the dpkg-shlibdeps output. -exports.additionalDeps = [ - 'ca-certificates', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnss3 (>= 3.26)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'xdg-utils (>= 1.0.2)' // OS integration -]; -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends -// Dependencies that we can only recommend -// for now since some of the older distros don't support them. -exports.recommendedDeps = [ - 'libvulkan1' // Move to additionalDeps once support for Trusty and Jessie are dropped. -]; -// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/98.0.4758.109:chrome/installer/linux/BUILD.gn;l=64-80 -// and the Linux Archive build -// Shared library dependencies that we already bundle. -exports.bundledDeps = [ - 'libEGL.so', - 'libGLESv2.so', - 'libvulkan.so.1', - 'swiftshader_libEGL.so', - 'swiftshader_libGLESv2.so', - 'libvk_swiftshader.so', - 'libffmpeg.so' -]; -exports.referenceGeneratedDepsByArch = { - 'amd64': [ - 'ca-certificates', - 'libasound2 (>= 1.0.16)', - 'libatk-bridge2.0-0 (>= 2.5.3)', - 'libatk1.0-0 (>= 2.2.0)', - 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.14)', - 'libc6 (>= 2.17)', - 'libc6 (>= 2.2.5)', - 'libcairo2 (>= 1.6.0)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.38)', - 'libexpat1 (>= 2.0.1)', - 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', - 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', - 'libgtk-3-0 (>= 3.9.10)', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', - 'libnss3 (>= 3.26)', - 'libpango-1.0-0 (>= 1.14.0)', - 'libsecret-1-0 (>= 0.18)', - 'libx11-6', - 'libx11-6 (>= 2:1.4.99.1)', - 'libxcb1 (>= 1.9.2)', - 'libxcomposite1 (>= 1:0.4.4-1)', - 'libxdamage1 (>= 1:1.1)', - 'libxext6', - 'libxfixes3', - 'libxkbcommon0 (>= 0.4.1)', - 'libxkbfile1', - 'libxrandr2', - 'xdg-utils (>= 1.0.2)' - ], - 'armhf': [ - 'ca-certificates', - 'libasound2 (>= 1.0.16)', - 'libatk-bridge2.0-0 (>= 2.5.3)', - 'libatk1.0-0 (>= 2.2.0)', - 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.17)', - 'libc6 (>= 2.4)', - 'libc6 (>= 2.9)', - 'libcairo2 (>= 1.6.0)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.38)', - 'libexpat1 (>= 2.0.1)', - 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', - 'libgcc1 (>= 1:3.5)', - 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', - 'libgtk-3-0 (>= 3.9.10)', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', - 'libnss3 (>= 3.26)', - 'libpango-1.0-0 (>= 1.14.0)', - 'libsecret-1-0 (>= 0.18)', - 'libstdc++6 (>= 4.1.1)', - 'libstdc++6 (>= 5)', - 'libstdc++6 (>= 5.2)', - 'libstdc++6 (>= 6)', - 'libx11-6', - 'libx11-6 (>= 2:1.4.99.1)', - 'libxcb1 (>= 1.9.2)', - 'libxcomposite1 (>= 1:0.4.4-1)', - 'libxdamage1 (>= 1:1.1)', - 'libxext6', - 'libxfixes3', - 'libxkbcommon0 (>= 0.4.1)', - 'libxkbfile1', - 'libxrandr2', - 'xdg-utils (>= 1.0.2)' - ], - 'arm64': [ - 'ca-certificates', - 'libasound2 (>= 1.0.16)', - 'libatk-bridge2.0-0 (>= 2.5.3)', - 'libatk1.0-0 (>= 2.2.0)', - 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.17)', - 'libcairo2 (>= 1.6.0)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'libdbus-1-3 (>= 1.0.2)', - 'libdrm2 (>= 2.4.38)', - 'libexpat1 (>= 2.0.1)', - 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', - 'libgcc1 (>= 1:4.2)', - 'libgcc1 (>= 1:4.5)', - 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', - 'libgtk-3-0 (>= 3.9.10)', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', - 'libnss3 (>= 3.26)', - 'libpango-1.0-0 (>= 1.14.0)', - 'libsecret-1-0 (>= 0.18)', - 'libstdc++6 (>= 4.1.1)', - 'libstdc++6 (>= 5)', - 'libstdc++6 (>= 5.2)', - 'libstdc++6 (>= 6)', - 'libx11-6', - 'libx11-6 (>= 2:1.4.99.1)', - 'libxcb1 (>= 1.9.2)', - 'libxcomposite1 (>= 1:0.4.4-1)', - 'libxdamage1 (>= 1:1.1)', - 'libxext6', - 'libxfixes3', - 'libxkbcommon0 (>= 0.4.1)', - 'libxkbfile1', - 'libxrandr2', - 'xdg-utils (>= 1.0.2)' - ] -}; diff --git a/build/linux/debian/dep-lists.ts b/build/linux/debian/dep-lists.ts deleted file mode 100644 index b86b5609e2..0000000000 --- a/build/linux/debian/dep-lists.ts +++ /dev/null @@ -1,157 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/additional_deps -// Additional dependencies not in the dpkg-shlibdeps output. -export const additionalDeps = [ - 'ca-certificates', // Make sure users have SSL certificates. - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnss3 (>= 3.26)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', // For Breakpad crash reports. - 'xdg-utils (>= 1.0.2)' // OS integration -]; - -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/manual_recommends -// Dependencies that we can only recommend -// for now since some of the older distros don't support them. -export const recommendedDeps = [ - 'libvulkan1' // Move to additionalDeps once support for Trusty and Jessie are dropped. -]; - -// Based on https://source.chromium.org/chromium/chromium/src/+/refs/tags/98.0.4758.109:chrome/installer/linux/BUILD.gn;l=64-80 -// and the Linux Archive build -// Shared library dependencies that we already bundle. -export const bundledDeps = [ - 'libEGL.so', - 'libGLESv2.so', - 'libvulkan.so.1', - 'swiftshader_libEGL.so', - 'swiftshader_libGLESv2.so', - 'libvk_swiftshader.so', - 'libffmpeg.so' -]; - -export const referenceGeneratedDepsByArch = { - 'amd64': [ - 'ca-certificates', - 'libasound2 (>= 1.0.16)', - 'libatk-bridge2.0-0 (>= 2.5.3)', - 'libatk1.0-0 (>= 2.2.0)', - 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.14)', - 'libc6 (>= 2.17)', - 'libc6 (>= 2.2.5)', - 'libcairo2 (>= 1.6.0)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.38)', - 'libexpat1 (>= 2.0.1)', - 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', - 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', - 'libgtk-3-0 (>= 3.9.10)', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', - 'libnss3 (>= 3.26)', - 'libpango-1.0-0 (>= 1.14.0)', - 'libsecret-1-0 (>= 0.18)', - 'libx11-6', - 'libx11-6 (>= 2:1.4.99.1)', - 'libxcb1 (>= 1.9.2)', - 'libxcomposite1 (>= 1:0.4.4-1)', - 'libxdamage1 (>= 1:1.1)', - 'libxext6', - 'libxfixes3', - 'libxkbcommon0 (>= 0.4.1)', - 'libxkbfile1', - 'libxrandr2', - 'xdg-utils (>= 1.0.2)' - ], - 'armhf': [ - 'ca-certificates', - 'libasound2 (>= 1.0.16)', - 'libatk-bridge2.0-0 (>= 2.5.3)', - 'libatk1.0-0 (>= 2.2.0)', - 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.17)', - 'libc6 (>= 2.4)', - 'libc6 (>= 2.9)', - 'libcairo2 (>= 1.6.0)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'libdbus-1-3 (>= 1.5.12)', - 'libdrm2 (>= 2.4.38)', - 'libexpat1 (>= 2.0.1)', - 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', - 'libgcc1 (>= 1:3.5)', - 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', - 'libgtk-3-0 (>= 3.9.10)', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', - 'libnss3 (>= 3.26)', - 'libpango-1.0-0 (>= 1.14.0)', - 'libsecret-1-0 (>= 0.18)', - 'libstdc++6 (>= 4.1.1)', - 'libstdc++6 (>= 5)', - 'libstdc++6 (>= 5.2)', - 'libstdc++6 (>= 6)', - 'libx11-6', - 'libx11-6 (>= 2:1.4.99.1)', - 'libxcb1 (>= 1.9.2)', - 'libxcomposite1 (>= 1:0.4.4-1)', - 'libxdamage1 (>= 1:1.1)', - 'libxext6', - 'libxfixes3', - 'libxkbcommon0 (>= 0.4.1)', - 'libxkbfile1', - 'libxrandr2', - 'xdg-utils (>= 1.0.2)' - ], - 'arm64': [ - 'ca-certificates', - 'libasound2 (>= 1.0.16)', - 'libatk-bridge2.0-0 (>= 2.5.3)', - 'libatk1.0-0 (>= 2.2.0)', - 'libatspi2.0-0 (>= 2.9.90)', - 'libc6 (>= 2.17)', - 'libcairo2 (>= 1.6.0)', - 'libcurl3-gnutls | libcurl3-nss | libcurl4 | libcurl3', - 'libdbus-1-3 (>= 1.0.2)', - 'libdrm2 (>= 2.4.38)', - 'libexpat1 (>= 2.0.1)', - 'libgbm1 (>= 8.1~0)', - 'libgcc1 (>= 1:3.0)', - 'libgcc1 (>= 1:4.2)', - 'libgcc1 (>= 1:4.5)', - 'libglib2.0-0 (>= 2.16.0)', - 'libglib2.0-0 (>= 2.39.4)', - 'libgtk-3-0 (>= 3.9.10)', - 'libgtk-3-0 (>= 3.9.10) | libgtk-4-1', - 'libnspr4 (>= 2:4.9-2~)', - 'libnss3 (>= 2:3.22)', - 'libnss3 (>= 3.26)', - 'libpango-1.0-0 (>= 1.14.0)', - 'libsecret-1-0 (>= 0.18)', - 'libstdc++6 (>= 4.1.1)', - 'libstdc++6 (>= 5)', - 'libstdc++6 (>= 5.2)', - 'libstdc++6 (>= 6)', - 'libx11-6', - 'libx11-6 (>= 2:1.4.99.1)', - 'libxcb1 (>= 1.9.2)', - 'libxcomposite1 (>= 1:0.4.4-1)', - 'libxdamage1 (>= 1:1.1)', - 'libxext6', - 'libxfixes3', - 'libxkbcommon0 (>= 0.4.1)', - 'libxkbfile1', - 'libxrandr2', - 'xdg-utils (>= 1.0.2)' - ] -}; diff --git a/build/linux/debian/dependencies-generator.js b/build/linux/debian/dependencies-generator.js deleted file mode 100644 index 235ca26853..0000000000 --- a/build/linux/debian/dependencies-generator.js +++ /dev/null @@ -1,129 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getDependencies = void 0; -const child_process_1 = require("child_process"); -const fs_1 = require("fs"); -const os_1 = require("os"); -const path = require("path"); -const dep_lists_1 = require("./dep-lists"); -// A flag that can easily be toggled. -// Make sure to compile the build directory after toggling the value. -// If false, we warn about new dependencies if they show up -// while running the Debian prepare package task for a release. -// If true, we fail the build if there are new dependencies found during that task. -// The reference dependencies, which one has to update when the new dependencies -// are valid, are in dep-lists.ts -const FAIL_BUILD_FOR_NEW_DEPENDENCIES = true; -function getDependencies(buildDir, applicationName, arch, sysroot) { - // Get the files for which we want to find dependencies. - const nativeModulesPath = path.join(buildDir, 'resources', 'app', 'node_modules.asar.unpacked'); - const findResult = (0, child_process_1.spawnSync)('find', [nativeModulesPath, '-name', '*.node']); - if (findResult.status) { - console.error('Error finding files:'); - console.error(findResult.stderr.toString()); - return []; - } - const files = findResult.stdout.toString().trimEnd().split('\n'); - const appPath = path.join(buildDir, applicationName); - files.push(appPath); - // Add chrome sandbox and crashpad handler. - files.push(path.join(buildDir, 'chrome-sandbox')); - files.push(path.join(buildDir, 'chrome_crashpad_handler')); - // Generate the dependencies. - const dependencies = files.map((file) => calculatePackageDeps(file, arch, sysroot)); - // Add additional dependencies. - const additionalDepsSet = new Set(dep_lists_1.additionalDeps); - dependencies.push(additionalDepsSet); - // Merge all the dependencies. - const mergedDependencies = mergePackageDeps(dependencies); - let sortedDependencies = []; - for (const dependency of mergedDependencies) { - sortedDependencies.push(dependency); - } - sortedDependencies.sort(); - // Exclude bundled dependencies - sortedDependencies = sortedDependencies.filter(dependency => { - return !dep_lists_1.bundledDeps.some(bundledDep => dependency.startsWith(bundledDep)); - }); - const referenceGeneratedDeps = dep_lists_1.referenceGeneratedDepsByArch[arch]; - if (JSON.stringify(sortedDependencies) !== JSON.stringify(referenceGeneratedDeps)) { - const failMessage = 'The dependencies list has changed.' - + '\nOld:\n' + referenceGeneratedDeps.join('\n') - + '\nNew:\n' + sortedDependencies.join('\n'); - if (FAIL_BUILD_FOR_NEW_DEPENDENCIES) { - throw new Error(failMessage); - } - else { - console.warn(failMessage); - } - } - return sortedDependencies; -} -exports.getDependencies = getDependencies; -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py. -function calculatePackageDeps(binaryPath, arch, sysroot) { - try { - if (!((0, fs_1.statSync)(binaryPath).mode & fs_1.constants.S_IXUSR)) { - throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); - } - } - catch (e) { - // The package might not exist. Don't re-throw the error here. - console.error('Tried to stat ' + binaryPath + ' but failed.'); - } - // Get the Chromium dpkg-shlibdeps file. - const dpkgShlibdepsUrl = 'https://raw.githubusercontent.com/chromium/chromium/100.0.4896.160/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl'; - const dpkgShlibdepsScriptLocation = `${(0, os_1.tmpdir)()}/dpkg-shlibdeps.pl`; - const result = (0, child_process_1.spawnSync)('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]); - if (result.status !== 0) { - throw new Error('Cannot retrieve dpkg-shlibdeps. Stderr:\n' + result.stderr); - } - const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined']; - switch (arch) { - case 'amd64': - cmd.push(`-l${sysroot}/usr/lib/x86_64-linux-gnu`, `-l${sysroot}/lib/x86_64-linux-gnu`); - break; - case 'armhf': - cmd.push(`-l${sysroot}/usr/lib/arm-linux-gnueabihf`, `-l${sysroot}/lib/arm-linux-gnueabihf`); - break; - case 'arm64': - cmd.push(`-l${sysroot}/usr/lib/aarch64-linux-gnu`, `-l${sysroot}/lib/aarch64-linux-gnu`); - break; - default: - throw new Error('Unsupported architecture ' + arch); - } - cmd.push(`-l${sysroot}/usr/lib`); - cmd.push('-O', '-e', path.resolve(binaryPath)); - const dpkgShlibdepsResult = (0, child_process_1.spawnSync)('perl', cmd, { cwd: sysroot }); - if (dpkgShlibdepsResult.status !== 0) { - throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `); - } - const shlibsDependsPrefix = 'shlibs:Depends='; - const requiresList = dpkgShlibdepsResult.stdout.toString('utf-8').trimEnd().split('\n'); - let depsStr = ''; - for (const line of requiresList) { - if (line.startsWith(shlibsDependsPrefix)) { - depsStr = line.substring(shlibsDependsPrefix.length); - } - } - const requires = new Set(depsStr.split(', ').sort()); - return requires; -} -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py. -function mergePackageDeps(inputDeps) { - // For now, see if directly appending the dependencies helps. - const requires = new Set(); - for (const depSet of inputDeps) { - for (const dep of depSet) { - const trimmedDependency = dep.trim(); - if (trimmedDependency.length && !trimmedDependency.startsWith('#')) { - requires.add(trimmedDependency); - } - } - } - return requires; -} diff --git a/build/linux/debian/dependencies-generator.ts b/build/linux/debian/dependencies-generator.ts deleted file mode 100644 index ec23cb7229..0000000000 --- a/build/linux/debian/dependencies-generator.ts +++ /dev/null @@ -1,145 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -import { spawnSync } from 'child_process'; -import { constants, statSync } from 'fs'; -import { tmpdir } from 'os'; -import path = require('path'); -import { additionalDeps, bundledDeps, referenceGeneratedDepsByArch } from './dep-lists'; -import { ArchString } from './types'; - -// A flag that can easily be toggled. -// Make sure to compile the build directory after toggling the value. -// If false, we warn about new dependencies if they show up -// while running the Debian prepare package task for a release. -// If true, we fail the build if there are new dependencies found during that task. -// The reference dependencies, which one has to update when the new dependencies -// are valid, are in dep-lists.ts -const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = true; - -export function getDependencies(buildDir: string, applicationName: string, arch: ArchString, sysroot: string): string[] { - // Get the files for which we want to find dependencies. - const nativeModulesPath = path.join(buildDir, 'resources', 'app', 'node_modules.asar.unpacked'); - const findResult = spawnSync('find', [nativeModulesPath, '-name', '*.node']); - if (findResult.status) { - console.error('Error finding files:'); - console.error(findResult.stderr.toString()); - return []; - } - - const files = findResult.stdout.toString().trimEnd().split('\n'); - - const appPath = path.join(buildDir, applicationName); - files.push(appPath); - - // Add chrome sandbox and crashpad handler. - files.push(path.join(buildDir, 'chrome-sandbox')); - files.push(path.join(buildDir, 'chrome_crashpad_handler')); - - // Generate the dependencies. - const dependencies: Set[] = files.map((file) => calculatePackageDeps(file, arch, sysroot)); - // Add additional dependencies. - const additionalDepsSet = new Set(additionalDeps); - dependencies.push(additionalDepsSet); - - // Merge all the dependencies. - const mergedDependencies = mergePackageDeps(dependencies); - let sortedDependencies: string[] = []; - for (const dependency of mergedDependencies) { - sortedDependencies.push(dependency); - } - sortedDependencies.sort(); - - // Exclude bundled dependencies - sortedDependencies = sortedDependencies.filter(dependency => { - return !bundledDeps.some(bundledDep => dependency.startsWith(bundledDep)); - }); - - const referenceGeneratedDeps = referenceGeneratedDepsByArch[arch]; - if (JSON.stringify(sortedDependencies) !== JSON.stringify(referenceGeneratedDeps)) { - const failMessage = 'The dependencies list has changed.' - + '\nOld:\n' + referenceGeneratedDeps.join('\n') - + '\nNew:\n' + sortedDependencies.join('\n'); - if (FAIL_BUILD_FOR_NEW_DEPENDENCIES) { - throw new Error(failMessage); - } else { - console.warn(failMessage); - } - } - - return sortedDependencies; -} - -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/calculate_package_deps.py. -function calculatePackageDeps(binaryPath: string, arch: ArchString, sysroot: string): Set { - try { - if (!(statSync(binaryPath).mode & constants.S_IXUSR)) { - throw new Error(`Binary ${binaryPath} needs to have an executable bit set.`); - } - } catch (e) { - // The package might not exist. Don't re-throw the error here. - console.error('Tried to stat ' + binaryPath + ' but failed.'); - } - - // Get the Chromium dpkg-shlibdeps file. - const dpkgShlibdepsUrl = 'https://raw.githubusercontent.com/chromium/chromium/100.0.4896.160/third_party/dpkg-shlibdeps/dpkg-shlibdeps.pl'; - const dpkgShlibdepsScriptLocation = `${tmpdir()}/dpkg-shlibdeps.pl`; - const result = spawnSync('curl', [dpkgShlibdepsUrl, '-o', dpkgShlibdepsScriptLocation]); - if (result.status !== 0) { - throw new Error('Cannot retrieve dpkg-shlibdeps. Stderr:\n' + result.stderr); - } - const cmd = [dpkgShlibdepsScriptLocation, '--ignore-weak-undefined']; - switch (arch) { - case 'amd64': - cmd.push(`-l${sysroot}/usr/lib/x86_64-linux-gnu`, - `-l${sysroot}/lib/x86_64-linux-gnu`); - break; - case 'armhf': - cmd.push(`-l${sysroot}/usr/lib/arm-linux-gnueabihf`, - `-l${sysroot}/lib/arm-linux-gnueabihf`); - break; - case 'arm64': - cmd.push(`-l${sysroot}/usr/lib/aarch64-linux-gnu`, - `-l${sysroot}/lib/aarch64-linux-gnu`); - break; - default: - throw new Error('Unsupported architecture ' + arch); - } - cmd.push(`-l${sysroot}/usr/lib`); - cmd.push('-O', '-e', path.resolve(binaryPath)); - - const dpkgShlibdepsResult = spawnSync('perl', cmd, { cwd: sysroot }); - if (dpkgShlibdepsResult.status !== 0) { - throw new Error(`dpkg-shlibdeps failed with exit code ${dpkgShlibdepsResult.status}. stderr:\n${dpkgShlibdepsResult.stderr} `); - } - - const shlibsDependsPrefix = 'shlibs:Depends='; - const requiresList = dpkgShlibdepsResult.stdout.toString('utf-8').trimEnd().split('\n'); - let depsStr = ''; - for (const line of requiresList) { - if (line.startsWith(shlibsDependsPrefix)) { - depsStr = line.substring(shlibsDependsPrefix.length); - } - } - const requires = new Set(depsStr.split(', ').sort()); - return requires; -} - -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py. -function mergePackageDeps(inputDeps: Set[]): Set { - // For now, see if directly appending the dependencies helps. - const requires = new Set(); - for (const depSet of inputDeps) { - for (const dep of depSet) { - const trimmedDependency = dep.trim(); - if (trimmedDependency.length && !trimmedDependency.startsWith('#')) { - requires.add(trimmedDependency); - } - } - } - return requires; -} diff --git a/build/linux/debian/install-sysroot.js b/build/linux/debian/install-sysroot.js deleted file mode 100644 index c6b57a7b8a..0000000000 --- a/build/linux/debian/install-sysroot.js +++ /dev/null @@ -1,81 +0,0 @@ -"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 }); -exports.getSysroot = void 0; -const child_process_1 = require("child_process"); -const crypto_1 = require("crypto"); -const os_1 = require("os"); -const fs = require("fs"); -const https = require("https"); -const path = require("path"); -const sysroots_1 = require("./sysroots"); -// Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. -const URL_PREFIX = 'https://msftelectron.blob.core.windows.net'; -const URL_PATH = 'sysroots/toolchain'; -function getSha(filename) { - const hash = (0, crypto_1.createHash)('sha1'); - // Read file 1 MB at a time - const fd = fs.openSync(filename, 'r'); - const buffer = Buffer.alloc(1024 * 1024); - let position = 0; - let bytesRead = 0; - while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, position)) === buffer.length) { - hash.update(buffer); - position += bytesRead; - } - hash.update(buffer.slice(0, bytesRead)); - return hash.digest('hex'); -} -async function getSysroot(arch) { - const sysrootDict = sysroots_1.sysrootInfo[arch]; - const tarballFilename = sysrootDict['Tarball']; - const tarballSha = sysrootDict['Sha1Sum']; - const sysroot = path.join((0, os_1.tmpdir)(), sysrootDict['SysrootDir']); - const url = [URL_PREFIX, URL_PATH, tarballSha, tarballFilename].join('/'); - const stamp = path.join(sysroot, '.stamp'); - if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === url) { - return sysroot; - } - console.log(`Installing Debian ${arch} root image: ${sysroot}`); - fs.rmSync(sysroot, { recursive: true, force: true }); - fs.mkdirSync(sysroot); - const tarball = path.join(sysroot, tarballFilename); - console.log(`Downloading ${url}`); - let downloadSuccess = false; - for (let i = 0; i < 3 && !downloadSuccess; i++) { - await new Promise((c) => { - https.get(url, (res) => { - const chunks = []; - res.on('data', (chunk) => { - chunks.push(chunk); - }); - res.on('end', () => { - fs.writeFileSync(tarball, Buffer.concat(chunks)); - downloadSuccess = true; - c(); - }); - }).on('error', (err) => { - console.error('Encountered an error during the download attempt: ' + err.message); - c(); - }); - }); - } - if (!downloadSuccess) { - throw new Error('Failed to download ' + url); - } - const sha = getSha(tarball); - if (sha !== tarballSha) { - throw new Error(`Tarball sha1sum is wrong. Expected ${tarballSha}, actual ${sha}`); - } - const proc = (0, child_process_1.spawnSync)('tar', ['xf', tarball, '-C', sysroot]); - if (proc.status) { - throw new Error('Tarball extraction failed with code ' + proc.status); - } - fs.rmSync(tarball); - fs.writeFileSync(stamp, url); - return sysroot; -} -exports.getSysroot = getSysroot; diff --git a/build/linux/debian/install-sysroot.ts b/build/linux/debian/install-sysroot.ts deleted file mode 100644 index 0f170fc2be..0000000000 --- a/build/linux/debian/install-sysroot.ts +++ /dev/null @@ -1,90 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { spawnSync } from 'child_process'; -import { createHash } from 'crypto'; -import { tmpdir } from 'os'; -import * as fs from 'fs'; -import * as https from 'https'; -import * as path from 'path'; -import { sysrootInfo } from './sysroots'; -import { ArchString } from './types'; - -// Based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/install-sysroot.py. -const URL_PREFIX = 'https://msftelectron.blob.core.windows.net'; -const URL_PATH = 'sysroots/toolchain'; - -function getSha(filename: fs.PathLike): string { - const hash = createHash('sha1'); - // Read file 1 MB at a time - const fd = fs.openSync(filename, 'r'); - const buffer = Buffer.alloc(1024 * 1024); - let position = 0; - let bytesRead = 0; - while ((bytesRead = fs.readSync(fd, buffer, 0, buffer.length, position)) === buffer.length) { - hash.update(buffer); - position += bytesRead; - } - hash.update(buffer.slice(0, bytesRead)); - return hash.digest('hex'); -} - -type SysrootDictEntry = { - Sha1Sum: string; - SysrootDir: string; - Tarball: string; -}; - -export async function getSysroot(arch: ArchString): Promise { - const sysrootDict: SysrootDictEntry = sysrootInfo[arch]; - const tarballFilename = sysrootDict['Tarball']; - const tarballSha = sysrootDict['Sha1Sum']; - const sysroot = path.join(tmpdir(), sysrootDict['SysrootDir']); - const url = [URL_PREFIX, URL_PATH, tarballSha, tarballFilename].join('/'); - const stamp = path.join(sysroot, '.stamp'); - if (fs.existsSync(stamp) && fs.readFileSync(stamp).toString() === url) { - return sysroot; - } - - console.log(`Installing Debian ${arch} root image: ${sysroot}`); - fs.rmSync(sysroot, { recursive: true, force: true }); - fs.mkdirSync(sysroot); - const tarball = path.join(sysroot, tarballFilename); - console.log(`Downloading ${url}`); - let downloadSuccess = false; - for (let i = 0; i < 3 && !downloadSuccess; i++) { - await new Promise((c) => { - https.get(url, (res) => { - const chunks: Uint8Array[] = []; - res.on('data', (chunk) => { - chunks.push(chunk); - }); - res.on('end', () => { - fs.writeFileSync(tarball, Buffer.concat(chunks)); - downloadSuccess = true; - c(); - }); - }).on('error', (err) => { - console.error('Encountered an error during the download attempt: ' + err.message); - c(); - }); - }); - } - if (!downloadSuccess) { - throw new Error('Failed to download ' + url); - } - const sha = getSha(tarball); - if (sha !== tarballSha) { - throw new Error(`Tarball sha1sum is wrong. Expected ${tarballSha}, actual ${sha}`); - } - - const proc = spawnSync('tar', ['xf', tarball, '-C', sysroot]); - if (proc.status) { - throw new Error('Tarball extraction failed with code ' + proc.status); - } - fs.rmSync(tarball); - fs.writeFileSync(stamp, url); - return sysroot; -} diff --git a/build/linux/debian/sysroots.js b/build/linux/debian/sysroots.js deleted file mode 100644 index 3825de4402..0000000000 --- a/build/linux/debian/sysroots.js +++ /dev/null @@ -1,26 +0,0 @@ -"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 }); -exports.sysrootInfo = void 0; -// Based on https://github.com/electron/electron/blob/main/script/sysroots.json, -// which itself is based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/sysroots.json. -exports.sysrootInfo = { - 'amd64': { - 'Sha1Sum': '7e008cea9eae822d80d55c67fbb5ef4204678e74', - 'SysrootDir': 'debian_sid_amd64-sysroot', - 'Tarball': 'debian_sid_amd64_sysroot.tar.xz' - }, - 'armhf': { - 'Sha1Sum': 'b6f4bb07817bea91b06514a9c1e3832df5a90dbf', - 'SysrootDir': 'debian_sid_arm-sysroot', - 'Tarball': 'debian_sid_arm_sysroot.tar.xz' - }, - 'arm64': { - 'Sha1Sum': '5a56c1ef714154ea5003bcafb16f21b0f8dde023', - 'SysrootDir': 'debian_sid_arm64-sysroot', - 'Tarball': 'debian_sid_arm64_sysroot.tar.xz' - } -}; diff --git a/build/linux/debian/sysroots.ts b/build/linux/debian/sysroots.ts deleted file mode 100644 index 8b21431f7e..0000000000 --- a/build/linux/debian/sysroots.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -// Based on https://github.com/electron/electron/blob/main/script/sysroots.json, -// which itself is based on https://source.chromium.org/chromium/chromium/src/+/main:build/linux/sysroot_scripts/sysroots.json. -export const sysrootInfo = { - 'amd64': { - 'Sha1Sum': '7e008cea9eae822d80d55c67fbb5ef4204678e74', - 'SysrootDir': 'debian_sid_amd64-sysroot', - 'Tarball': 'debian_sid_amd64_sysroot.tar.xz' - }, - 'armhf': { - 'Sha1Sum': 'b6f4bb07817bea91b06514a9c1e3832df5a90dbf', - 'SysrootDir': 'debian_sid_arm-sysroot', - 'Tarball': 'debian_sid_arm_sysroot.tar.xz' - }, - 'arm64': { - 'Sha1Sum': '5a56c1ef714154ea5003bcafb16f21b0f8dde023', - 'SysrootDir': 'debian_sid_arm64-sysroot', - 'Tarball': 'debian_sid_arm64_sysroot.tar.xz' - } -}; diff --git a/build/linux/debian/types.js b/build/linux/debian/types.js deleted file mode 100644 index 56d4e6c56c..0000000000 --- a/build/linux/debian/types.js +++ /dev/null @@ -1,6 +0,0 @@ -"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 }); diff --git a/build/linux/libcxx-fetcher.js b/build/linux/libcxx-fetcher.js index 7877f82679..b2a3e6556b 100644 --- a/build/linux/libcxx-fetcher.js +++ b/build/linux/libcxx-fetcher.js @@ -1,11 +1,11 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +// Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available. +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.downloadLibcxxObjects = exports.downloadLibcxxHeaders = void 0; -// Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available. const debug = require("debug"); const extract = require("extract-zip"); const fs = require("fs-extra"); diff --git a/build/linux/libcxx-fetcher.ts b/build/linux/libcxx-fetcher.ts index 82be5a4727..677c88c5cc 100644 --- a/build/linux/libcxx-fetcher.ts +++ b/build/linux/libcxx-fetcher.ts @@ -5,6 +5,8 @@ // Can be removed once https://github.com/electron/electron-rebuild/pull/703 is available. +'use strict'; + import * as debug from 'debug'; import * as extract from 'extract-zip'; import * as fs from 'fs-extra'; diff --git a/build/linux/rpm/dep-lists.js b/build/linux/rpm/dep-lists.js index b912865c2c..bc77d0936d 100644 --- a/build/linux/rpm/dep-lists.js +++ b/build/linux/rpm/dep-lists.js @@ -75,8 +75,10 @@ exports.referenceGeneratedDepsByArch = { 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', + 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', + 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', @@ -158,8 +160,10 @@ exports.referenceGeneratedDepsByArch = { 'libgcc_s.so.1(GCC_3.0)', 'libgcc_s.so.1(GCC_3.4)', 'libgcc_s.so.1(GCC_3.5)', + 'libgdk_pixbuf-2.0.so.0', 'libgio-2.0.so.0', 'libglib-2.0.so.0', + 'libgmodule-2.0.so.0', 'libgobject-2.0.so.0', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', @@ -248,8 +252,10 @@ exports.referenceGeneratedDepsByArch = { 'libgcc_s.so.1(GCC_3.0)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgcc_s.so.1(GCC_4.5.0)(64bit)', + 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', + 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', diff --git a/build/linux/rpm/dep-lists.ts b/build/linux/rpm/dep-lists.ts index 0edd4758c0..07747a2723 100644 --- a/build/linux/rpm/dep-lists.ts +++ b/build/linux/rpm/dep-lists.ts @@ -75,8 +75,10 @@ export const referenceGeneratedDepsByArch = { 'libgbm.so.1()(64bit)', 'libgcc_s.so.1()(64bit)', 'libgcc_s.so.1(GCC_3.0)(64bit)', + 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', + 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', @@ -158,8 +160,10 @@ export const referenceGeneratedDepsByArch = { 'libgcc_s.so.1(GCC_3.0)', 'libgcc_s.so.1(GCC_3.4)', 'libgcc_s.so.1(GCC_3.5)', + 'libgdk_pixbuf-2.0.so.0', 'libgio-2.0.so.0', 'libglib-2.0.so.0', + 'libgmodule-2.0.so.0', 'libgobject-2.0.so.0', 'libgtk-3.so.0', 'libgtk-3.so.0()(64bit)', @@ -248,8 +252,10 @@ export const referenceGeneratedDepsByArch = { 'libgcc_s.so.1(GCC_3.0)(64bit)', 'libgcc_s.so.1(GCC_4.2.0)(64bit)', 'libgcc_s.so.1(GCC_4.5.0)(64bit)', + 'libgdk_pixbuf-2.0.so.0()(64bit)', 'libgio-2.0.so.0()(64bit)', 'libglib-2.0.so.0()(64bit)', + 'libgmodule-2.0.so.0()(64bit)', 'libgobject-2.0.so.0()(64bit)', 'libgtk-3.so.0()(64bit)', 'libm.so.6()(64bit)', diff --git a/build/linux/rpm/dependencies-generator.js b/build/linux/rpm/dependencies-generator.js index 6b63258373..1d39b14287 100644 --- a/build/linux/rpm/dependencies-generator.js +++ b/build/linux/rpm/dependencies-generator.js @@ -1,8 +1,8 @@ -"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDependencies = void 0; const child_process_1 = require("child_process"); @@ -81,7 +81,7 @@ function calculatePackageDeps(binaryPath) { const requires = new Set(findRequiresResult.stdout.toString('utf-8').trimEnd().split('\n')); return requires; } -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py. +// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py function mergePackageDeps(inputDeps) { const requires = new Set(); for (const depSet of inputDeps) { diff --git a/build/linux/rpm/dependencies-generator.ts b/build/linux/rpm/dependencies-generator.ts index bb7db403be..de41da6259 100644 --- a/build/linux/rpm/dependencies-generator.ts +++ b/build/linux/rpm/dependencies-generator.ts @@ -3,6 +3,8 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +'use strict'; + import { spawnSync } from 'child_process'; import { constants, statSync } from 'fs'; import path = require('path'); @@ -92,7 +94,7 @@ function calculatePackageDeps(binaryPath: string): Set { return requires; } -// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py. +// Based on https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/rpm/merge_package_deps.py function mergePackageDeps(inputDeps: Set[]): Set { const requires = new Set(); for (const depSet of inputDeps) { diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index c2524ec0a2..f1ef829459 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -63,7 +63,7 @@ declare namespace monaco.editor { export interface ICommandHandler { (...args: any[]): void; } -#include(vs/platform/contextkey/common/contextkey): IContextKey, ContextKeyValue +#include(vs/platform/contextkey/common/contextkey): IContextKey #include(vs/editor/standalone/browser/standaloneServices): IEditorOverrideServices #include(vs/platform/markers/common/markers): IMarker, IMarkerData, IRelatedInformation #include(vs/editor/standalone/browser/colorizer): IColorizerOptions, IColorizerElementOptions diff --git a/build/npm/dirs.js b/build/npm/dirs.js index a45c19be8e..65fd2e1ea4 100644 --- a/build/npm/dirs.js +++ b/build/npm/dirs.js @@ -7,6 +7,7 @@ exports.dirs = [ '', 'build', + 'build/lib/watch', 'extensions', // {{SQL CARBON EDIT}} Add ADS extensions and remove VSCode ones 'extensions/admin-tool-ext-win', @@ -33,7 +34,6 @@ exports.dirs = [ 'extensions/json-language-features/server', 'extensions/kusto', 'extensions/machine-learning', - 'extensions/markdown-language-features/server', 'extensions/markdown-language-features', 'extensions/markdown-math', 'extensions/merge-conflict', diff --git a/build/npm/postinstall.js b/build/npm/postinstall.js index 82b77bf5b5..21882f74ac 100644 --- a/build/npm/postinstall.js +++ b/build/npm/postinstall.js @@ -2,10 +2,10 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - const cp = require('child_process'); +const path = require('path'); +const fs = require('fs'); const { dirs } = require('./dirs'); -const { setupBuildYarnrc } = require('./setupBuildYarnrc'); const yarn = process.platform === 'win32' ? 'yarn.cmd' : 'yarn'; /** @@ -47,9 +47,9 @@ for (let dir of dirs) { continue; } - if (dir === 'build') { - setupBuildYarnrc(); - yarnInstall('build'); + if (dir === 'build/lib/watch') { + // node modules for watching, specific to host node version, not electron + yarnInstallBuildDependencies(); continue; } @@ -73,5 +73,23 @@ for (let dir of dirs) { yarnInstall(dir, opts); } +function yarnInstallBuildDependencies() { + // make sure we install the deps of build/lib/watch for the system installed + // node, since that is the driver of gulp + const watchPath = path.join(path.dirname(__dirname), 'lib', 'watch'); + const yarnrcPath = path.join(watchPath, '.yarnrc'); + + const disturl = 'https://nodejs.org/download/release'; + const target = process.versions.node; + const runtime = 'node'; + + const yarnrc = `disturl "${disturl}" +target "${target}" +runtime "${runtime}"`; + + fs.writeFileSync(yarnrcPath, yarnrc, 'utf8'); + yarnInstall(watchPath); +} + cp.execSync('git config pull.rebase merges'); cp.execSync('git config blame.ignoreRevsFile .git-blame-ignore'); diff --git a/build/npm/preinstall.js b/build/npm/preinstall.js index 880f02d362..3a151261d4 100644 --- a/build/npm/preinstall.js +++ b/build/npm/preinstall.js @@ -9,13 +9,10 @@ const majorNodeVersion = parseInt(nodeVersion[1]); const minorNodeVersion = parseInt(nodeVersion[2]); const patchNodeVersion = parseInt(nodeVersion[3]); -if (majorNodeVersion < 16 || (majorNodeVersion === 16 && minorNodeVersion < 14)) { - console.error('\033[1;31m*** Please use node.js versions >=16.14.x and <17.\033[0;0m'); +if (majorNodeVersion < 14 || (majorNodeVersion === 14 && minorNodeVersion < 17) || (majorNodeVersion === 14 && minorNodeVersion === 17 && patchNodeVersion < 4) || majorNodeVersion >= 17) { + console.error('\033[1;31m*** Please use node.js versions >=14.17.4 and <17.\033[0;0m'); err = true; } -if (majorNodeVersion >= 17) { - console.warn('\033[1;31m*** Warning: Versions of node.js >= 17 have not been tested.\033[0;0m') -} const path = require('path'); const fs = require('fs'); diff --git a/build/npm/setupBuildYarnrc.js b/build/npm/setupBuildYarnrc.js deleted file mode 100644 index 4e35564e7c..0000000000 --- a/build/npm/setupBuildYarnrc.js +++ /dev/null @@ -1,25 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -const path = require('path'); -const fs = require('fs'); - -// make sure we install the deps of build for the system installed -// node, since that is the driver of gulp -function setupBuildYarnrc() { - const yarnrcPath = path.join(path.dirname(__dirname), '.yarnrc'); - const yarnrc = `disturl "https://nodejs.org/download/release" -target "${process.versions.node}" -runtime "node" -arch "${process.arch}"`; - - fs.writeFileSync(yarnrcPath, yarnrc, 'utf8'); -} - -exports.setupBuildYarnrc = setupBuildYarnrc; - -if (require.main === module) { - setupBuildYarnrc(); -} diff --git a/build/package-lock.json b/build/package-lock.json deleted file mode 100644 index 6177bbf591..0000000000 --- a/build/package-lock.json +++ /dev/null @@ -1,7877 +0,0 @@ -{ - "name": "azuredatastudio-oss-dev-build", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "azuredatastudio-oss-dev-build", - "version": "1.0.0", - "license": "MIT", - "devDependencies": { - "@azure/cosmos": "^3.14.1", - "@azure/identity": "^2.1.0", - "@azure/storage-blob": "^12.8.0", - "@electron/get": "^1.12.4", - "@types/ansi-colors": "^3.2.0", - "@types/azure": "0.9.19", - "@types/byline": "^4.2.32", - "@types/cssnano": "^4.0.0", - "@types/debounce": "^1.0.0", - "@types/debug": "4.1.5", - "@types/documentdb": "^1.10.5", - "@types/eslint": "4.16.1", - "@types/eslint-visitor-keys": "^1.0.0", - "@types/fancy-log": "^1.3.1", - "@types/fs-extra": "^9.0.12", - "@types/glob": "^7.1.1", - "@types/gulp": "^4.0.10", - "@types/gulp-concat": "^0.0.32", - "@types/gulp-filter": "^3.0.35", - "@types/gulp-gzip": "^0.0.31", - "@types/gulp-json-editor": "^2.2.31", - "@types/gulp-postcss": "^8.0.0", - "@types/gulp-rename": "^0.0.33", - "@types/gulp-sourcemaps": "^0.0.32", - "@types/mime": "0.0.29", - "@types/minimatch": "^3.0.3", - "@types/minimist": "^1.2.1", - "@types/mkdirp": "^1.0.1", - "@types/mocha": "^9.1.1", - "@types/node": "16.x", - "@types/p-limit": "^2.2.0", - "@types/plist": "^3.0.2", - "@types/pump": "^1.0.1", - "@types/request": "^2.47.0", - "@types/rimraf": "^2.0.4", - "@types/through": "^0.0.29", - "@types/through2": "^2.0.34", - "@types/tmp": "^0.2.1", - "@types/underscore": "^1.8.9", - "@types/webpack": "^4.41.25", - "@types/xml2js": "0.0.33", - "@typescript-eslint/experimental-utils": "~2.13.0", - "@typescript-eslint/parser": "^5.10.0", - "@vscode/iconv-lite-umd": "0.7.0", - "applicationinsights": "1.0.8", - "azure-storage": "^2.1.0", - "byline": "^5.0.0", - "colors": "^1.4.0", - "commander": "^7.0.0", - "debug": "^4.3.2", - "documentdb": "1.13.0", - "electron-osx-sign": "^0.4.16", - "esbuild": "^0.12.6", - "extract-zip": "^2.0.1", - "fs-extra": "^9.1.0", - "got": "11.8.5", - "gulp-merge-json": "^2.1.1", - "iconv-lite-umd": "0.6.8", - "jsonc-parser": "^2.3.0", - "mime": "^1.4.1", - "mkdirp": "^1.0.4", - "node-fetch": "2", - "p-limit": "^3.1.0", - "plist": "^3.0.5", - "rollup": "^1.20.3", - "rollup-plugin-commonjs": "^10.1.0", - "rollup-plugin-node-resolve": "^5.2.0", - "source-map": "0.6.1", - "tmp": "^0.2.1", - "typescript": "^4.5.0-dev.20210817", - "vsce": "2.8.0", - "vscode-universal-bundler": "^0.0.2" - }, - "optionalDependencies": { - "tree-sitter": "https://github.com/joaomoreno/node-tree-sitter/releases/download/v0.20.0/tree-sitter-0.20.0.tgz", - "tree-sitter-typescript": "^0.20.1", - "vscode-gulp-watch": "^5.0.3" - } - }, - "node_modules/@azure/abort-controller": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.2.tgz", - "integrity": "sha512-XUyTo+bcyxHEf+jlN2MXA7YU9nxVehaubngHV1MIZZaqYmZqykkoeAz/JMMEeR7t3TcyDwbFa3Zw8BZywmIx4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@azure/abort-controller/node_modules/tslib": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", - "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@azure/core-asynciterator-polyfill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz", - "integrity": "sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@azure/core-auth": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.4.0.tgz", - "integrity": "sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-client": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.6.1.tgz", - "integrity": "sha512-mZ1MSKhZBYoV8GAWceA+PEJFWV2VpdNSpxxcj1wjIAOi00ykRuIQChT99xlQGZWLY3/NApWhSImlFwsmCEs4vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.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.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-http": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/@azure/core-http/-/core-http-2.2.7.tgz", - "integrity": "sha512-TyGMeDm90mkRS8XzSQbSMD+TqnWL1XKGCh0x0QVGMD8COH2yU0q5SaHm/IBEBkzcq0u73NhS/p57T3KVSgUFqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/core-util": "^1.1.0", - "@azure/logger": "^1.0.0", - "@types/node-fetch": "^2.5.0", - "@types/tunnel": "^0.0.3", - "form-data": "^4.0.0", - "node-fetch": "^2.6.7", - "process": "^0.11.10", - "tough-cookie": "^4.0.0", - "tslib": "^2.2.0", - "tunnel": "^0.0.6", - "uuid": "^8.3.0", - "xml2js": "^0.4.19" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-http/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-lro": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.3.1.tgz", - "integrity": "sha512-nQ+Xnm9g1EWcmbqgxJGmkNHfOHRUmrbYIlRT4KjluzhHQooaGO55m/h6wCX0ho3Jte2ZNBzZPJRmi6yBWeb3yA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/logger": "^1.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-paging": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.1.3.tgz", - "integrity": "sha512-his7Ah40ThEYORSpIAwuh6B8wkGwO/zG7gqVtmSE4WAJ46e36zUDXTKReUCLBDc6HmjjApQQxxcRFy5FruG79A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/core-asynciterator-polyfill": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@azure/core-rest-pipeline": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.9.2.tgz", - "integrity": "sha512-8rXI6ircjenaLp+PkOFpo37tQ1PQfztZkfVj97BIF3RPxHAsoVSgkJtu3IK/bUEWcb7HzXSoyBe06M7ODRkRyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.4.0", - "@azure/core-tracing": "^1.0.1", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "form-data": "^4.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-tracing": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz", - "integrity": "sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/core-util": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.0.tgz", - "integrity": "sha512-+i93lNJNA3Pl3KSuC6xKP2jTL4YFeDfO6VNOaYdk0cppZcLCxt811gS878VsqsCisaltdhl9lhMzK5kbxCiF4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/cosmos": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.17.1.tgz", - "integrity": "sha512-3pgPwNwAiTgiH/OgcntDLzrANy+roaaDFYoLOhC4bxoDC94nPCjpLYRRwueIpisZAdopPVrxQloNs9fEjVlL0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/core-auth": "^1.3.0", - "@azure/core-rest-pipeline": "^1.2.0", - "@azure/core-tracing": "^1.0.0", - "debug": "^4.1.1", - "fast-json-stable-stringify": "^2.1.0", - "jsbi": "^3.1.3", - "node-abort-controller": "^3.0.0", - "priorityqueuejs": "^1.0.0", - "semaphore": "^1.0.5", - "tslib": "^2.2.0", - "universal-user-agent": "^6.0.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/cosmos/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@azure/cosmos/node_modules/semaphore": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", - "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@azure/identity": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-2.1.0.tgz", - "integrity": "sha512-BPDz1sK7Ul9t0l9YKLEa8PHqWU4iCfhGJ+ELJl6c8CP3TpJt2urNCbm0ZHsthmxRsYoMPbz2Dvzj30zXZVmAFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-auth": "^1.3.0", - "@azure/core-client": "^1.4.0", - "@azure/core-rest-pipeline": "^1.1.0", - "@azure/core-tracing": "^1.0.0", - "@azure/core-util": "^1.0.0", - "@azure/logger": "^1.0.0", - "@azure/msal-browser": "^2.26.0", - "@azure/msal-common": "^7.0.0", - "@azure/msal-node": "^1.10.0", - "events": "^3.0.0", - "jws": "^4.0.0", - "open": "^8.0.0", - "stoppable": "^1.1.0", - "tslib": "^2.2.0", - "uuid": "^8.3.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/logger": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.0.1.tgz", - "integrity": "sha512-QYQeaJ+A5x6aMNu8BG5qdsVBnYBop9UMwgUvGihSjf1PdZZXB+c/oMdM2ajKwzobLBh9e9QuMQkN9iL+IxLBLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@azure/logger/node_modules/tslib": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", - "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@azure/msal-browser": { - "version": "2.28.3", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.28.3.tgz", - "integrity": "sha512-2SdyH2el3s8BzPURf9RK17BvvXvaMEGpLc3D9WilZcmjJqP4nStVH7Ogwr/SNTuGV48FUhqEkP0RxDvzuFJSIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/msal-common": "^7.4.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@azure/msal-common": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-7.4.1.tgz", - "integrity": "sha512-zxcxg9pRdgGTS5mrRJeQvwA8aIjD8qSGzaAiz5SeTVkyhtjB0AeFnAcvBOKHv/TkswWNfYKpERxsXOAKXkXk0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@azure/msal-node": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.0.tgz", - "integrity": "sha512-3XB7FuHLhmGBjw7bxuz1LCHOXQgmNIO3J56tlbOjuJcyJtd4aBCgnYIXNKLed3uRcQNHEO0mlg24I4iGxAV/UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/msal-common": "^7.4.1", - "jsonwebtoken": "^8.5.1", - "uuid": "^8.3.0" - }, - "engines": { - "node": "10 || 12 || 14 || 16 || 18" - } - }, - "node_modules/@azure/msal-node/node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "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": "^5.6.0" - }, - "engines": { - "node": ">=4", - "npm": ">=1.4.28" - } - }, - "node_modules/@azure/msal-node/node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dev": true, - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/@azure/msal-node/node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dev": true, - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/@azure/storage-blob": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.11.0.tgz", - "integrity": "sha512-na+FisoARuaOWaHWpmdtk3FeuTWf2VWamdJ9/TJJzj5ZdXPLC3juoDgFs6XVuJIoK30yuBpyFBEDXVRK4pB7Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@azure/abort-controller": "^1.0.0", - "@azure/core-http": "^2.0.0", - "@azure/core-lro": "^2.2.0", - "@azure/core-paging": "^1.1.1", - "@azure/core-tracing": "1.0.0-preview.13", - "@azure/logger": "^1.0.0", - "events": "^3.0.0", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@azure/storage-blob/node_modules/@azure/core-tracing": { - "version": "1.0.0-preview.13", - "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz", - "integrity": "sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@opentelemetry/api": "^1.0.1", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@electron/get": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.4.tgz", - "integrity": "sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^9.6.0", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=8.6" - }, - "optionalDependencies": { - "global-agent": "^2.0.2", - "global-tunnel-ng": "^2.7.1" - } - }, - "node_modules/@electron/get/node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@electron/get/node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "defer-to-connect": "^1.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@electron/get/node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/get/node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@electron/get/node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/get/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@electron/get/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=", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@electron/get/node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@electron/get/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@electron/get/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, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@electron/get/node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@electron/get/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, - "license": "MIT" - }, - "node_modules/@electron/get/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/get/node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.0" - } - }, - "node_modules/@electron/get/node_modules/lowercase-keys": { - "version": "1.0.1", - "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" - } - }, - "node_modules/@electron/get/node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/get/node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@electron/get/node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", - "dev": true, - "peer": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "peer": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true, - "peer": true - }, - "node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "license": "Apache-2.0", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@opentelemetry/api": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.2.0.tgz", - "integrity": "sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz", - "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", - "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/ansi-colors": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@types/ansi-colors/-/ansi-colors-3.2.0.tgz", - "integrity": "sha512-0caWAhXht9N2lOdMzJLXybsSkYCx1QOdxx6pae48tswI9QV3DFX26AoOpy0JxwhCb+zISTqmd6H8t9Zby9BoZg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/azure": { - "version": "0.9.19", - "resolved": "https://registry.npmjs.org/@types/azure/-/azure-0.9.19.tgz", - "integrity": "sha1-Gmqb2Fa0N93s8/n8hAemg8hpugI=", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/azure/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/byline": { - "version": "4.2.32", - "resolved": "https://registry.npmjs.org/@types/byline/-/byline-4.2.32.tgz", - "integrity": "sha512-qtlm/J6XOO9p+Ep/ZB5+mCFEDhzWDDHWU4a1eReN7lkPZXW9rkloq2jcAhvKKmlO5tL2GSvKROb+PTsNVhBiyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/byline/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", - "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "node_modules/@types/cacheable-request/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/caseless": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz", - "integrity": "sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/cssnano": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/cssnano/-/cssnano-4.0.1.tgz", - "integrity": "sha512-hGOroxRTBkYl5gSBRJOffhV4+io+Y2bFX1VP7LgKEVHJt/LPPJaWUIuDAz74Vlp7l7hCDZfaDi7iPxwNwuVA4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss": "5 - 7" - } - }, - "node_modules/@types/debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.0.0.tgz", - "integrity": "sha1-QXVgIAMx4buE1y2oU5EQLC/NYbc=", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/debug": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", - "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/documentdb": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@types/documentdb/-/documentdb-1.10.8.tgz", - "integrity": "sha512-GkOXovVMlMVTYkPomq9rOI79DmVOMZ0TDziL3H3TSlhUSm1/txi5qA49H/qZRDFsExagjnf5Cd/4xF8mXVxubw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/documentdb/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/eslint": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-4.16.1.tgz", - "integrity": "sha512-lRUXQAULl5geixTiP2K0iYvMUbCkEnuOwvLGjwff12I4ECxoW5QaWML5UUOZ1CvpQLILkddBdMPMZz4ByQizsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "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, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "0.0.41", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.41.tgz", - "integrity": "sha512-rIAmXyJlqw4KEBO7+u9gxZZSQHaCNnIzYrnNmYVpgfJhxTqO0brCX0SYpqUTkVI5mwwUwzmtspLBGBKroMeynA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/events": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/fancy-log": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/fancy-log/-/fancy-log-1.3.1.tgz", - "integrity": "sha512-31Dt9JaGfHretvwVxCBrCFL5iC9MQ3zOXpu+8C4qzW0cxc5rJJVGxB5c/vZ+wmeTk/JjPz/D0gv8BZ+Ip6iCqQ==", - "dev": true - }, - "node_modules/@types/form-data": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", - "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/fs-extra": { - "version": "9.0.12", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", - "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/fs-extra/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-RHv6ZQjcTncXo3thYZrsbAVwoy4vSKosSWhuhuQxLOTv74OJuFQxXkmUuZCr3q9uNBEVCvIzmZL/FeRNbHZGUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "*", - "@types/node": "*" - } - }, - "node_modules/@types/glob-stream/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/glob/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/gulp": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-4.0.10.tgz", - "integrity": "sha512-spgZHJFqiEJGwqGlf7T/k4nkBpBcLgP7T0EfN6G2vvnhUfvd4uO1h8RwpXOE8x/54DVYUs1XCAtBHkX/R3axAQ==", - "dev": true, - "dependencies": { - "@types/undertaker": ">=1.2.6", - "@types/vinyl-fs": "*", - "chokidar": "^3.3.1" - } - }, - "node_modules/@types/gulp-concat": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/gulp-concat/-/gulp-concat-0.0.32.tgz", - "integrity": "sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/gulp-concat/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/gulp-filter": { - "version": "3.0.35", - "resolved": "https://registry.npmjs.org/@types/gulp-filter/-/gulp-filter-3.0.35.tgz", - "integrity": "sha512-xBdmHVMnPvAdwyLDFD2Yi8lYXXhYlMWnsWxvMPiinj8b7LJmzNKloI4TQyod+WXEfbiUsHULp0q0qdCIXBVRDQ==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*", - "@types/vinyl": "*" - } - }, - "node_modules/@types/gulp-gzip": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/@types/gulp-gzip/-/gulp-gzip-0.0.31.tgz", - "integrity": "sha512-KQjHz1FTqLse8/EiktfhN/vo33vamX4gVAQhMTp55STDBA7UToW5CJqYyP7iRorkHK9/aJ2nL2hLkNZkY4M8+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/gulp-gzip/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/gulp-json-editor": { - "version": "2.2.31", - "resolved": "https://registry.npmjs.org/@types/gulp-json-editor/-/gulp-json-editor-2.2.31.tgz", - "integrity": "sha512-piis0ImYAy0dt18R4EtTbAY+RV8jwTq5VisnUV6OfP8kD4743aHGkAdAd08No4NY3rFa5mD6ytIu8L0YU7nL9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/js-beautify": "*", - "@types/node": "*" - } - }, - "node_modules/@types/gulp-json-editor/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/gulp-postcss": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@types/gulp-postcss/-/gulp-postcss-8.0.0.tgz", - "integrity": "sha512-AVgjA03bpkYONKZpzuJviB9PzaNbDzrovYPbenj8/XxivUc35C/dIzJanyaQv7CFqfLLPLsqSalmtP3GLq6iag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/vinyl": "*" - } - }, - "node_modules/@types/gulp-postcss/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/gulp-rename": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/gulp-rename/-/gulp-rename-0.0.33.tgz", - "integrity": "sha512-FIZQvbZJj6V1gHPTzO+g/BCWpDur7fJrroae4gwV3LaoHBQ+MrR9sB+2HssK8fHv4WdY6hVNxkcft9bYatuPIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/gulp-rename/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/gulp-sourcemaps": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/gulp-sourcemaps/-/gulp-sourcemaps-0.0.32.tgz", - "integrity": "sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/gulp-sourcemaps/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", - "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/js-beautify": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@types/js-beautify/-/js-beautify-1.8.0.tgz", - "integrity": "sha512-/siF86XrwDKLuHe8l7h6NhrAWgLdgqbxmjZv9NvGWmgYRZoTipkjKiWb0SQHy/jcR+ee0GvbG6uGd+LEBMGNvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/keyv": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", - "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/keyv/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-0.0.29.tgz", - "integrity": "sha1-+8/TMFc7kS71nu7hRgK/rOYwdUs=", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", - "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mkdirp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.1.tgz", - "integrity": "sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/mkdirp/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mocha": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", - "integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "16.11.62", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.62.tgz", - "integrity": "sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node-fetch": { - "version": "2.5.8", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.8.tgz", - "integrity": "sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, - "node_modules/@types/node-fetch/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node-fetch/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@types/p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@types/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-fGFbybl1r0oE9mqgfc2EHHUin9ZL5rbQIexWI6jYRU1ADVn4I3LHzT+g/kpPpZsfp8PB94CQ655pfAjNF8LP6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "*" - } - }, - "node_modules/@types/plist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", - "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, - "node_modules/@types/plist/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/plist/node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/@types/pump": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/pump/-/pump-1.0.1.tgz", - "integrity": "sha1-roFXzv7wTRpNJMHMkdQDwvXaXNA=", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/pump/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/request": { - "version": "2.47.0", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.0.tgz", - "integrity": "sha512-/KXM5oev+nNCLIgBjkwbk8VqxmzI56woD4VUxn95O+YeQ8hJzcSmIZ1IN3WexiqBb6srzDo2bdMbsXxgXNkz5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/caseless": "*", - "@types/form-data": "*", - "@types/node": "*", - "@types/tough-cookie": "*" - } - }, - "node_modules/@types/request/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/resolve/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/responselike/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/rimraf": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz", - "integrity": "sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "*", - "@types/node": "*" - } - }, - "node_modules/@types/rimraf/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tapable": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz", - "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/through": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.29.tgz", - "integrity": "sha512-9a7C5VHh+1BKblaYiq+7Tfc+EOmjMdZaD1MYtkQjSoxgB69tBjW98ry6SKsi4zEIWztLOMRuL87A3bdT/Fc/4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/through/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/through2": { - "version": "2.0.34", - "resolved": "https://registry.npmjs.org/@types/through2/-/through2-2.0.34.tgz", - "integrity": "sha512-nhRG8+RuG/L+0fAZBQYaRflXKjTrHOKH8MFTChnf+dNVMxA3wHYYrfj0tztK0W51ABXjGfRCDc0vRkecCOrsow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/through2/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-7cTXwKP/HLOPVgjg+YhBdQ7bMiobGMuoBmrGmqwIWJv8elC6t1DfVc/mn4fD9UE1IjhwmhaQ5pGVXkmXbH0rhg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha512-vOVmaruQG5EatOU/jM6yU2uCp3Lz6mK1P5Ztu4iJjfM4SVHU9XYktPUQtKlIXuahqXHdEyUarMrBEwg5Cwu+bA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/tunnel": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz", - "integrity": "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/tunnel/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/uglify-js": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz", - "integrity": "sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "^0.6.1" - } - }, - "node_modules/@types/underscore": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz", - "integrity": "sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/undertaker": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.8.tgz", - "integrity": "sha512-gW3PRqCHYpo45XFQHJBhch7L6hytPsIe0QeLujlnFsjHPnXLhJcPdN6a9368d7aIQgH2I/dUTPFBlGeSNA3qOg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/undertaker-registry": "*", - "async-done": "~1.3.2" - } - }, - "node_modules/@types/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ==", - "dev": true - }, - "node_modules/@types/vinyl": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz", - "integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/vinyl-fs": { - "version": "2.4.9", - "resolved": "https://registry.npmjs.org/@types/vinyl-fs/-/vinyl-fs-2.4.9.tgz", - "integrity": "sha512-Q0EXd6c1fORjiOuK4ZaKdfFcMyFzJlTi56dqktwaWVLIDAzE49wUs3bKnYbZwzyMWoH+NcMWnRuR73S9A0jnRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/events": "*", - "@types/glob-stream": "*", - "@types/node": "*", - "@types/vinyl": "*" - } - }, - "node_modules/@types/vinyl-fs/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/vinyl/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/webpack": { - "version": "4.41.30", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.30.tgz", - "integrity": "sha512-GUHyY+pfuQ6haAfzu4S14F+R5iGRwN6b2FRNJY7U0NilmFAqbsOfK6j1HwuLBAqwRIT+pVdNDJGJ6e8rpp0KHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/tapable": "^1", - "@types/uglify-js": "*", - "@types/webpack-sources": "*", - "anymatch": "^3.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/@types/webpack-sources": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz", - "integrity": "sha512-MjM1R6iuw8XaVbtkCBz0N349cyqBjJHCbQiOeppe3VBeFvxqs74RKHAVt9LkxTnUWc7YLZOEsUfPUnmK6SBPKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.7.3" - } - }, - "node_modules/@types/webpack-sources/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/webpack-sources/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@types/webpack/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/webpack/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, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@types/xml2js": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.0.33.tgz", - "integrity": "sha1-IMXdZGAkUoTWSlVpABW5XkCft94=", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yauzl/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.13.0.tgz", - "integrity": "sha512-+Hss3clwa6aNiC8ZjA45wEm4FutDV5HsVXPl/rDug1THq6gEtOYRGLqS3JlTk7mSnL5TbJz0LpEbzbPnKvY6sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.13.0", - "eslint-scope": "^5.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.1.tgz", - "integrity": "sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.38.1", - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/typescript-estree": "5.38.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz", - "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@typescript-eslint/parser/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, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz", - "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz", - "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.13.0.tgz", - "integrity": "sha512-t21Mg5cc8T3ADEUGwDisHLIubgXKjuNRbkpzDMLb7/JMmgCe/gHM9FaaujokLey+gwTuLF5ndSQ7/EfQqrQx4g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash.unescape": "4.0.1", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz", - "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.38.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@vscode/iconv-lite-umd": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz", - "integrity": "sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peer": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-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==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/applicationinsights": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.8.tgz", - "integrity": "sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "diagnostic-channel": "0.2.0", - "diagnostic-channel-publishers": "0.2.1", - "zone.js": "0.7.6" - } - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "devOptional": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "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/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "devOptional": true, - "license": "MIT", - "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": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "devOptional": true, - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/asar": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/asar/-/asar-3.0.3.tgz", - "integrity": "sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - }, - "optionalDependencies": { - "@types/glob": "^7.1.1" - } - }, - "node_modules/asar/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true, - "license": "MIT" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/azure-devops-node-api": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.1.1.tgz", - "integrity": "sha512-XDG91XzLZ15reP12s3jFkKS8oiagSICjnLwxEYieme4+4h3ZveFOFRA4iYIG40RyHXsiI0mefFYYMFIJbMpWcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "tunnel": "0.0.6", - "typed-rest-client": "^1.8.4" - } - }, - "node_modules/azure-storage": { - "version": "2.10.7", - "resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.10.7.tgz", - "integrity": "sha512-4oeFGtn3Ziw/fGs/zkoIpKKtygnCVIcZwzJ7UQzKTxhkGQqVCByOFbYqMGYR3L+wOsunX9lNfD0jc51SQuKSSA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "browserify-mime": "^1.2.9", - "extend": "^3.0.2", - "json-edm-parser": "~0.1.2", - "json-schema": "~0.4.0", - "md5.js": "^1.3.4", - "readable-stream": "^2.0.0", - "request": "^2.86.0", - "underscore": "^1.12.1", - "uuid": "^3.0.0", - "validator": "^13.7.0", - "xml2js": "~0.2.8", - "xmlbuilder": "^9.0.7" - }, - "engines": { - "node": ">= 0.8.26" - } - }, - "node_modules/azure-storage/node_modules/sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true, - "license": "BSD" - }, - "node_modules/azure-storage/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/azure-storage/node_modules/xml2js": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz", - "integrity": "sha512-ZHZBIAO55GHCn2jBYByVPHvHS+o3j8/a/qmpEe6kxO3cTnTCWC3Htq9RYJ5G4XMwMMClD2QkXA9SNdPadLyn3Q==", - "dev": true, - "dependencies": { - "sax": "0.5.x" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "devOptional": 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/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/binary-search-bounds": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.3.tgz", - "integrity": "sha1-X/hhbW3SylOIvIWy1iZuK52lAtw=", - "dev": true, - "license": "MIT" - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bl/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true, - "license": "ISC" - }, - "node_modules/boolean": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.2.tgz", - "integrity": "sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw==", - "dev": true, - "license": "MIT", - "optional": 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==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserify-mime": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz", - "integrity": "sha512-uz+ItyJXBLb6wgon1ELEiVowJBEsy03PUWGRQU7cxxx9S+DW2hujPp+DaMYEOClRPzsn7NB99NtJ6pGnt8y+CQ==", - "dev": true - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "devOptional": 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", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-alloc": { - "version": "1.2.0", - "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" - } - }, - "node_modules/buffer-alloc-unsafe": { - "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, - "license": "MIT" - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "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, - "license": "BSD-3-Clause" - }, - "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, - "license": "MIT" - }, - "node_modules/builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/byline": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", - "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.11", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.11.tgz", - "integrity": "sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag==", - "dev": true, - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "htmlparser2": "^8.0.1", - "parse5": "^7.0.0", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", - "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", - "dev": true, - "license": "MIT" - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "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=", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "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": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true, - "license": "MIT" - }, - "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==", - "license": "ISC", - "optional": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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=", - "dev": true, - "license": "MIT" - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "devOptional": true, - "license": "ISC" - }, - "node_modules/core-js": { - "version": "3.15.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz", - "integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "devOptional": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "peer": true - }, - "node_modules/defer-to-connect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", - "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "devOptional": true, - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "license": "Apache-2.0", - "optional": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/diagnostic-channel": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz", - "integrity": "sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^5.3.0" - } - }, - "node_modules/diagnostic-channel-publishers": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz", - "integrity": "sha1-ji1geottef6IC1SLxYzGvrKIxPM=", - "dev": true, - "license": "MIT", - "peerDependencies": { - "diagnostic-channel": "*" - } - }, - "node_modules/dir-compare": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz", - "integrity": "sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-equal": "1.0.0", - "colors": "1.0.3", - "commander": "2.9.0", - "minimatch": "3.0.4" - }, - "bin": { - "dircompare": "src/cli/dircompare.js" - } - }, - "node_modules/dir-compare/node_modules/colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/dir-compare/node_modules/commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-readlink": ">= 1.0.0" - }, - "engines": { - "node": ">= 0.6.x" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "peer": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/documentdb": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/documentdb/-/documentdb-1.13.0.tgz", - "integrity": "sha1-u6bwMVCy9CSYzsQmG8Q52DSjP4s=", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-search-bounds": "2.0.3", - "priorityqueuejs": "1.0.0", - "semaphore": "1.0.5", - "underscore": "1.8.3" - } - }, - "node_modules/documentdb/node_modules/underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", - "dev": true, - "license": "MIT" - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", - "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.1" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "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, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/electron-osx-sign": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.17.tgz", - "integrity": "sha512-wUJPmZJQCs1zgdlQgeIpRcvrf7M5/COQaOV68Va1J/SgmWx5KL2otgg+fAae7luw6qz9R8Gvu/Qpe9tAOu/3xQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "bluebird": "^3.5.0", - "compare-version": "^0.1.2", - "debug": "^2.6.8", - "isbinaryfile": "^3.0.2", - "minimist": "^1.2.0", - "plist": "^3.0.1" - }, - "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/electron-osx-sign/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/electron-osx-sign/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/end-of-stream": { - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/entities": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz", - "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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, - "license": "MIT", - "optional": true - }, - "node_modules/esbuild": { - "version": "0.12.6", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.6.tgz", - "integrity": "sha512-RDvVLvAjsq/kIZJoneMiUOH7EE7t2QaW7T3Q7EdQij14+bZbDq5sndb0tTanmHIFSqZVMBMMyqzVHkS3dJobeA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", - "dev": true, - "peer": true, - "dependencies": { - "@eslint/eslintrc": "^1.4.1", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "peer": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - } - }, - "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, - "license": "Apache-2.0", - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/eslint/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "peer": true - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "peer": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint/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, - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "peer": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "peer": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", - "dev": true, - "peer": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/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, - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "devOptional": true, - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, - "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==", - "license": "MIT", - "optional": 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, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "peer": true - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "peer": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/first-chunk-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha512-X8Z+b/0L4lToKYq+lwnKqi9X/Zek0NibLpsJgVsSxpoYq7JtiCtRb5HqKVEjEw/qAb/4AKKRLOwwKHlWNpm2Eg==", - "license": "MIT", - "optional": true, - "dependencies": { - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "peer": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true, - "peer": true - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fs-extra/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "license": "ISC" - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "devOptional": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "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, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.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", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=", - "devOptional": true, - "license": "MIT" - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "devOptional": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/global-agent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz", - "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "core-js": "^3.6.5", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/global-agent/node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "license": "ISC", - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dev": true, - "peer": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/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, - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", - "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/got": { - "version": "11.8.5", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz", - "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true, - "license": "ISC" - }, - "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=", - "dev": true, - "license": "MIT" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true, - "peer": true - }, - "node_modules/gulp-merge-json": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-merge-json/-/gulp-merge-json-2.1.2.tgz", - "integrity": "sha512-FysBAdHdnQvZzigVJJzlrt6TEosHxVb0mR2h/8eSnd+eJyBvb1LQF1EIrovrOCfj4HGE5p/95wGEjXsJk9qomw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json5": "^2.2.1", - "lodash.mergewith": "^4.6.1", - "plugin-error": "^1.0.1", - "through": "^2.3.8", - "vinyl": "^2.2.1" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "devOptional": true, - "license": "ISC" - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash-base/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hash-base/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/htmlparser2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", - "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "entities": "^4.3.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/http2-wrapper": { - "version": "1.0.0-beta.5.2", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz", - "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/iconv-lite-umd": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz", - "integrity": "sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "devOptional": 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": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "peer": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "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": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "devOptional": true, - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true, - "license": "MIT" - }, - "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==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true, - "license": "MIT" - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "license": "MIT", - "optional": true - }, - "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, - "license": "MIT", - "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", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "devOptional": true, - "license": "MIT" - }, - "node_modules/isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-alloc": "^1.2.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true, - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true, - "license": "MIT" - }, - "node_modules/js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "dev": true, - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "peer": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbi": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz", - "integrity": "sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "license": "MIT" - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-edm-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz", - "integrity": "sha512-J1U9mk6lf8dPULcaMwALXB6yel3cJyyhk9Z8FQ4sMwiazNwjaUhegIcpZyZFNMvLRtnXwh+TkCjX9uYUObBBYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonparse": "~1.2.0" - } - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true, - "license": "(AFL-2.1 OR BSD-3-Clause)" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "peer": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true, - "license": "ISC" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonc-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", - "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonfile/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/jsonparse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz", - "integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70=", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "dev": true, - "license": "MIT", - "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.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/keytar": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", - "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "node-addon-api": "^4.3.0", - "prebuild-install": "^7.0.1" - } - }, - "node_modules/keytar/node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/keytar/node_modules/node-abi": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.22.0.tgz", - "integrity": "sha512-u4uAs/4Zzmp/jjsD9cyFYDXeISfUWaAVWshPmDZOFOv4Xl4SbzTXm53I04C2uRueYJ+0t5PEtLH/owbn2Npf/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/keytar/node_modules/prebuild-install": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.0.tgz", - "integrity": "sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^3.3.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/keytar/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/keytar/node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "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", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "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, - "peer": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT", - "optional": true - }, - "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.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.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.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.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, - "peer": true - }, - "node_modules/lodash.mergewith": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true, - "license": "MIT" - }, - "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/lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", - "dev": true, - "license": "MIT" - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "sourcemap-codec": "^1.4.4" - } - }, - "node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/matcher/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "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, - "license": "MIT", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.46.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", - "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.29", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", - "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.46.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "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" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "devOptional": true, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true, - "license": "ISC" - }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "license": "MIT", - "optional": true - }, - "node_modules/napi-build-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "peer": true - }, - "node_modules/node-abi": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz", - "integrity": "sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==", - "license": "MIT", - "optional": true, - "dependencies": { - "semver": "^5.4.1" - } - }, - "node_modules/node-abort-controller": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz", - "integrity": "sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-conf/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "devOptional": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "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": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", - "integrity": "sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "devOptional": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "license": "MIT", - "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/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "peer": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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/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, - "peer": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "peer": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/parse-semver": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", - "integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^5.1.0" - } - }, - "node_modules/parse5": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz", - "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^4.3.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.2", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "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, - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true, - "license": "MIT" - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true, - "license": "MIT" - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plist": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz", - "integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "base64-js": "^1.5.1", - "xmlbuilder": "^9.0.7" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/plugin-error/node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "ansi-wrap": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss/node_modules/supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/prebuild-install": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz", - "integrity": "sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.21.0", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "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=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/priorityqueuejs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz", - "integrity": "sha1-LuTyPCVgkT4IwHzlzN1t498sWvg=", - "dev": true, - "license": "MIT" - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "devOptional": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true, - "license": "ISC", - "optional": true - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true, - "license": "MIT" - }, - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "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/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "devOptional": true, - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "dev": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/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==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz", - "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^2.0.0" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" - }, - "bin": { - "rollup": "dist/bin/rollup" - } - }, - "node_modules/rollup-plugin-commonjs": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", - "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "estree-walker": "^0.6.1", - "is-reference": "^1.1.2", - "magic-string": "^0.25.2", - "resolve": "^1.11.0", - "rollup-pluginutils": "^2.8.1" - }, - "peerDependencies": { - "rollup": ">=1.12.0" - } - }, - "node_modules/rollup-plugin-node-resolve": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", - "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/resolve": "0.0.8", - "builtin-modules": "^3.1.0", - "is-module": "^1.0.0", - "resolve": "^1.11.1", - "rollup-pluginutils": "^2.8.1" - }, - "peerDependencies": { - "rollup": ">=1.11.0" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup/node_modules/@types/node": { - "version": "8.0.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.51.tgz", - "integrity": "sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==", - "dev": true, - "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" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "devOptional": 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/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "license": "ISC" - }, - "node_modules/semaphore": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.0.5.tgz", - "integrity": "sha1-tJJXbmavGT25XWXiXsU/Xxl5jWA=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "devOptional": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "devOptional": true, - "license": "ISC" - }, - "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": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "devOptional": 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/simple-get": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", - "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", - "license": "MIT", - "optional": true, - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "license": "MIT", - "optional": true, - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/simple-get/node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "dev": true, - "license": "MIT" - }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stoppable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", - "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4", - "npm": ">=6" - } - }, - "node_modules/stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/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==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "devOptional": true, - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "devOptional": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha512-1sUIL1jck0T1mhOLP2c696BIznzT525Lkub+n4jjMHjhjhoAQA6Ye659DxdlZBr0aLDMQoTxKIpnlqxgtwjsuQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-utf8": "^0.2.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-bom-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz", - "integrity": "sha512-yH0+mD8oahBZWnY43vxs4pSinn8SMKAdml/EOGBewoe1Y0Eitd0h2Mg3ZRiXruUW6L4P+lvZiEgbh0NgUGia1w==", - "license": "MIT", - "optional": true, - "dependencies": { - "first-chunk-stream": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.1.0" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tar-stream/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "peer": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true, - "license": "MIT" - }, - "node_modules/tree-sitter": { - "version": "0.20.0", - "resolved": "https://github.com/joaomoreno/node-tree-sitter/releases/download/v0.20.0/tree-sitter-0.20.0.tgz", - "integrity": "sha512-FfyATFV6xANETqV0izjt/iC76yxFM8oGe5IfeyGfqXxRTsKKs2IOSGx1LTa6guOL3M2SagIQShAkHkJ4sK5/eA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "nan": "^2.14.0", - "prebuild-install": "^6.0.1" - } - }, - "node_modules/tree-sitter-typescript": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.20.1.tgz", - "integrity": "sha512-wqpnhdVYX26ATNXeZtprib4+mF2GlYQB1cjRPibYGxDRiugx5OfjWwLE4qPPxEGdp2ZLSmZVesGUjLWzfKo6rA==", - "license": "MIT", - "optional": true, - "dependencies": { - "nan": "^2.14.0" - } - }, - "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "dev": true, - "license": "0BSD" - }, - "node_modules/tsutils": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz", - "integrity": "sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "license": "Unlicense" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-rest-client": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz", - "integrity": "sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "qs": "^6.9.1", - "tunnel": "0.0.6", - "underscore": "^1.12.1" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true, - "license": "MIT" - }, - "node_modules/underscore": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz", - "integrity": "sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA==", - "dev": true, - "license": "MIT" - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true, - "license": "ISC" - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true, - "license": "MIT" - }, - "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=", - "dev": true, - "license": "MIT", - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "devOptional": true, - "license": "MIT" - }, - "node_modules/uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/validator": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", - "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT", - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/extsprintf": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz", - "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "license": "MIT" - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-file": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-3.0.0.tgz", - "integrity": "sha512-BoJDj+ca3D9xOuPEM6RWVtWQtvEPQiQYn82LvdxhLWplfQsBzBqtgK0yhCP0s1BNTi6dH9BO+dzybvyQIacifg==", - "license": "MIT", - "optional": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "pify": "^2.3.0", - "strip-bom-buf": "^1.0.0", - "strip-bom-stream": "^2.0.0", - "vinyl": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/vinyl-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "license": "ISC", - "optional": true - }, - "node_modules/vsce": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.8.0.tgz", - "integrity": "sha512-p6BTbUVp33Ed0OWRRhRQT55yrmgLEca2fTmqxZJW44T1eP4yVWEsdaNIDsjFIeuCrjG/CYvwi1QLG4ql0s7bDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "azure-devops-node-api": "^11.0.1", - "chalk": "^2.4.2", - "cheerio": "^1.0.0-rc.9", - "commander": "^6.1.0", - "glob": "^7.0.6", - "hosted-git-info": "^4.0.2", - "keytar": "^7.7.0", - "leven": "^3.1.0", - "markdown-it": "^12.3.2", - "mime": "^1.3.4", - "minimatch": "^3.0.3", - "parse-semver": "^1.1.1", - "read": "^1.0.7", - "semver": "^5.1.0", - "tmp": "^0.2.1", - "typed-rest-client": "^1.8.4", - "url-join": "^4.0.1", - "xml2js": "^0.4.23", - "yauzl": "^2.3.1", - "yazl": "^2.2.2" - }, - "bin": { - "vsce": "vsce" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/vsce/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/vsce/node_modules/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/vscode-gulp-watch": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vscode-gulp-watch/-/vscode-gulp-watch-5.0.3.tgz", - "integrity": "sha512-MTUp2yLE9CshhkNSNV58EQNxQSeF8lIj3mkXZX9a1vAk+EQNM2PAYdPUDSd/P/08W3PMHGznEiZyfK7JAjLosg==", - "license": "MIT", - "optional": true, - "dependencies": { - "ansi-colors": "4.1.1", - "anymatch": "^3.1.1", - "chokidar": "3.5.1", - "fancy-log": "^1.3.3", - "glob-parent": "^5.1.1", - "normalize-path": "^3.0.0", - "object-assign": "^4.1.1", - "plugin-error": "1.0.1", - "readable-stream": "^3.6.0", - "vinyl": "^2.2.0", - "vinyl-file": "^3.0.0" - } - }, - "node_modules/vscode-gulp-watch/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "license": "MIT", - "optional": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/vscode-gulp-watch/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "optional": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/vscode-universal-bundler": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/vscode-universal-bundler/-/vscode-universal-bundler-0.0.2.tgz", - "integrity": "sha512-FPJcvKnQGBqFzy6M6Nm2yvAczNLUeXsfYM6GwCex/pUOkvIM2icIHmiSvtMJINlLW1iG+oEwE3/LVbABmcjEmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@malept/cross-spawn-promise": "^1.1.0", - "asar": "^3.0.3", - "debug": "^4.3.1", - "dir-compare": "^2.4.0", - "fs-extra": "^9.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/vscode-universal-bundler/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "devOptional": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/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==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/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==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "devOptional": true, - "license": "ISC" - }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dev": true, - "license": "MIT", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xml2js/node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zone.js": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz", - "integrity": "sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=", - "dev": true, - "license": "MIT" - } - } -} diff --git a/build/package.json b/build/package.json index 92a0e46d09..5ecfc0001e 100644 --- a/build/package.json +++ b/build/package.json @@ -17,12 +17,12 @@ "@types/documentdb": "^1.10.5", "@types/eslint": "4.16.1", "@types/eslint-visitor-keys": "^1.0.0", - "@types/fancy-log": "^1.3.1", + "@types/fancy-log": "^1.3.0", "@types/fs-extra": "^9.0.12", "@types/glob": "^7.1.1", - "@types/gulp": "^4.0.10", + "@types/gulp": "^4.0.5", "@types/gulp-concat": "^0.0.32", - "@types/gulp-filter": "^3.0.35", + "@types/gulp-filter": "^3.0.32", "@types/gulp-gzip": "^0.0.31", "@types/gulp-json-editor": "^2.2.31", "@types/gulp-postcss": "^8.0.0", @@ -47,24 +47,22 @@ "@types/xml2js": "0.4.11", "@typescript-eslint/experimental-utils": "~2.13.0", "@typescript-eslint/parser": "^5.10.0", - "@vscode/iconv-lite-umd": "0.7.0", "applicationinsights": "1.0.8", "byline": "^5.0.0", "colors": "^1.4.0", "commander": "^7.0.0", "debug": "^4.3.2", - "documentdb": "1.13.0", "electron-osx-sign": "^0.4.16", "esbuild": "^0.12.6", "extract-zip": "^2.0.1", "fs-extra": "^9.1.0", + "documentdb": "1.13.0", "got": "11.8.5", "gulp-merge-json": "^2.1.1", "iconv-lite-umd": "0.6.8", "jsonc-parser": "^2.3.0", "mime": "^1.4.1", "mkdirp": "^1.0.4", - "node-fetch": "2", "p-limit": "^3.1.0", "plist": "^3.0.5", "rollup": "^1.20.3", @@ -72,8 +70,7 @@ "rollup-plugin-node-resolve": "^5.2.0", "source-map": "0.6.1", "tmp": "^0.2.1", - "typescript": "^4.8.0-dev.20220518", - "vsce": "2.8.0", + "typescript": "^4.5.0-dev.20210817", "vscode-universal-bundler": "^0.0.2" }, "scripts": { @@ -81,11 +78,7 @@ "watch": "tsc -p tsconfig.build.json --watch", "npmCheckJs": "tsc --noEmit" }, - "optionalDependencies": { - "tree-sitter": "https://github.com/joaomoreno/node-tree-sitter/releases/download/v0.20.0/tree-sitter-0.20.0.tgz", - "tree-sitter-typescript": "^0.20.1", - "vscode-gulp-watch": "^5.0.3" - }, + "dependencies": {}, "resolutions": { "json-schema": "0.4.0", "jsonwebtoken": "9.0.0" diff --git a/build/tsconfig.json b/build/tsconfig.json index 17f030c386..290dc2792c 100644 --- a/build/tsconfig.json +++ b/build/tsconfig.json @@ -2,7 +2,6 @@ "compilerOptions": { "target": "es2017", "module": "commonjs", - "alwaysStrict": true, "removeComments": false, "preserveConstEnums": true, "sourceMap": false, diff --git a/build/win32/code.iss b/build/win32/code.iss index facbc7beb8..204a0902b5 100644 --- a/build/win32/code.iss +++ b/build/win32/code.iss @@ -346,7 +346,7 @@ begin Permissions := '/grant:r "*S-1-5-18:(OI)(CI)F" /grant:r "*S-1-5-32-544:(OI)(CI)F" /grant:r "*S-1-5-11:(OI)(CI)RX" /grant:r "*S-1-5-32-545:(OI)(CI)RX"'; #if "user" == InstallTarget - Permissions := Permissions + Format(' /grant:r "*S-1-3-0:(OI)(CI)F" /grant:r "%s:(OI)(CI)F"', [GetUserNameString()]); + Permissions := Permissions + ' /grant:r "*S-1-3-0:(OI)(CI)F"'; #endif Exec(ExpandConstant('{sys}\icacls.exe'), ExpandConstant('"{app}" /inheritancelevel:r ') + Permissions, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); diff --git a/build/yarn.lock b/build/yarn.lock index 086cadee94..b93c1954cd 100644 --- a/build/yarn.lock +++ b/build/yarn.lock @@ -4,19 +4,19 @@ "@azure/abort-controller@^1.0.0": version "1.0.2" - resolved "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.2.tgz#822405c966b2aec16fb62c1b19d37eaccf231995" integrity sha512-XUyTo+bcyxHEf+jlN2MXA7YU9nxVehaubngHV1MIZZaqYmZqykkoeAz/JMMEeR7t3TcyDwbFa3Zw8BZywmIx4g== dependencies: tslib "^2.0.0" "@azure/core-asynciterator-polyfill@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz#dcccebb88406e5c76e0e1d52e8cc4c43a68b3ee7" integrity sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg== "@azure/core-auth@^1.3.0", "@azure/core-auth@^1.4.0": version "1.4.0" - resolved "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.4.0.tgz#6fa9661c1705857820dbc216df5ba5665ac36a9e" integrity sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ== dependencies: "@azure/abort-controller" "^1.0.0" @@ -24,7 +24,7 @@ "@azure/core-client@^1.4.0": version "1.6.1" - resolved "https://registry.npmjs.org/@azure/core-client/-/core-client-1.6.1.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-client/-/core-client-1.6.1.tgz#a1aad3f7c69b6e5d9dddb39fabaeba013eac9313" integrity sha512-mZ1MSKhZBYoV8GAWceA+PEJFWV2VpdNSpxxcj1wjIAOi00ykRuIQChT99xlQGZWLY3/NApWhSImlFwsmCEs4vA== dependencies: "@azure/abort-controller" "^1.0.0" @@ -57,7 +57,7 @@ "@azure/core-lro@^2.2.0": version "2.3.1" - resolved "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-2.3.1.tgz#c8270b2785ea98c793af28ed106a470650859049" integrity sha512-nQ+Xnm9g1EWcmbqgxJGmkNHfOHRUmrbYIlRT4KjluzhHQooaGO55m/h6wCX0ho3Jte2ZNBzZPJRmi6yBWeb3yA== dependencies: "@azure/abort-controller" "^1.0.0" @@ -66,14 +66,14 @@ "@azure/core-paging@^1.1.1": version "1.1.3" - resolved "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.1.3.tgz#3587c9898a0530cacb64bab216d7318468aa5efc" integrity sha512-his7Ah40ThEYORSpIAwuh6B8wkGwO/zG7gqVtmSE4WAJ46e36zUDXTKReUCLBDc6HmjjApQQxxcRFy5FruG79A== dependencies: "@azure/core-asynciterator-polyfill" "^1.0.0" "@azure/core-rest-pipeline@^1.1.0", "@azure/core-rest-pipeline@^1.2.0", "@azure/core-rest-pipeline@^1.9.1": version "1.9.2" - resolved "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.9.2.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.9.2.tgz#47ee72ca96e2b82e3d1362c29fd7688dc7464527" integrity sha512-8rXI6ircjenaLp+PkOFpo37tQ1PQfztZkfVj97BIF3RPxHAsoVSgkJtu3IK/bUEWcb7HzXSoyBe06M7ODRkRyw== dependencies: "@azure/abort-controller" "^1.0.0" @@ -89,7 +89,7 @@ "@azure/core-tracing@1.0.0-preview.13": version "1.0.0-preview.13" - resolved "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644" integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ== dependencies: "@opentelemetry/api" "^1.0.1" @@ -97,14 +97,14 @@ "@azure/core-tracing@^1.0.0", "@azure/core-tracing@^1.0.1": version "1.0.1" - resolved "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503" integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw== dependencies: tslib "^2.2.0" "@azure/core-util@^1.0.0": version "1.1.0" - resolved "https://registry.npmjs.org/@azure/core-util/-/core-util-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.1.0.tgz#36736b274e9abee4b6cc6e4d162683b4e1e3db52" integrity sha512-+i93lNJNA3Pl3KSuC6xKP2jTL4YFeDfO6VNOaYdk0cppZcLCxt811gS878VsqsCisaltdhl9lhMzK5kbxCiF4w== dependencies: tslib "^2.2.0" @@ -119,7 +119,7 @@ "@azure/cosmos@^3.14.1": version "3.17.1" - resolved "https://registry.npmjs.org/@azure/cosmos/-/cosmos-3.17.1.tgz" + resolved "https://registry.yarnpkg.com/@azure/cosmos/-/cosmos-3.17.1.tgz#10a654f59720681adad670b49c1f3a3ccf3e13d4" integrity sha512-3pgPwNwAiTgiH/OgcntDLzrANy+roaaDFYoLOhC4bxoDC94nPCjpLYRRwueIpisZAdopPVrxQloNs9fEjVlL0A== dependencies: "@azure/core-auth" "^1.3.0" @@ -137,7 +137,7 @@ "@azure/identity@^2.1.0": version "2.1.0" - resolved "https://registry.npmjs.org/@azure/identity/-/identity-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/@azure/identity/-/identity-2.1.0.tgz#89f0bfc1d1264dfd3d0cb19837c33a9c6706d548" integrity sha512-BPDz1sK7Ul9t0l9YKLEa8PHqWU4iCfhGJ+ELJl6c8CP3TpJt2urNCbm0ZHsthmxRsYoMPbz2Dvzj30zXZVmAFw== dependencies: "@azure/abort-controller" "^1.0.0" @@ -159,26 +159,26 @@ "@azure/logger@^1.0.0": version "1.0.1" - resolved "https://registry.npmjs.org/@azure/logger/-/logger-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.1.tgz#19b333203d1b2931353d8879e814b64a7274837a" integrity sha512-QYQeaJ+A5x6aMNu8BG5qdsVBnYBop9UMwgUvGihSjf1PdZZXB+c/oMdM2ajKwzobLBh9e9QuMQkN9iL+IxLBLA== dependencies: tslib "^2.0.0" "@azure/msal-browser@^2.26.0": version "2.28.3" - resolved "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-2.28.3.tgz" + resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-2.28.3.tgz#7cd35e632ea74a2ef5f9939fdce8757ffb93487f" integrity sha512-2SdyH2el3s8BzPURf9RK17BvvXvaMEGpLc3D9WilZcmjJqP4nStVH7Ogwr/SNTuGV48FUhqEkP0RxDvzuFJSIw== dependencies: "@azure/msal-common" "^7.4.1" "@azure/msal-common@^7.0.0", "@azure/msal-common@^7.4.1": version "7.4.1" - resolved "https://registry.npmjs.org/@azure/msal-common/-/msal-common-7.4.1.tgz" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-7.4.1.tgz#204c32d247336d7e334984e599bfd63156554f83" integrity sha512-zxcxg9pRdgGTS5mrRJeQvwA8aIjD8qSGzaAiz5SeTVkyhtjB0AeFnAcvBOKHv/TkswWNfYKpERxsXOAKXkXk0w== "@azure/msal-node@^1.10.0": version "1.14.0" - resolved "https://registry.npmjs.org/@azure/msal-node/-/msal-node-1.14.0.tgz" + resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-1.14.0.tgz#b1b6018e52e06c3789b434f636f5b632aa1d2ec7" integrity sha512-3XB7FuHLhmGBjw7bxuz1LCHOXQgmNIO3J56tlbOjuJcyJtd4aBCgnYIXNKLed3uRcQNHEO0mlg24I4iGxAV/UA== dependencies: "@azure/msal-common" "^7.4.1" @@ -186,9 +186,9 @@ uuid "^8.3.0" "@azure/storage-blob@^12.13.0": - version "12.14.0" - resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.14.0.tgz#32d3e5fa3bb2a12d5d44b186aed11c8e78f00178" - integrity sha512-g8GNUDpMisGXzBeD+sKphhH5yLwesB4JkHr1U6be/X3F+cAMcyGLPD1P89g2M7wbEtUJWoikry1rlr83nNRBzg== + version "12.13.0" + resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.13.0.tgz#9209cbb5c2cd463fb967a0f2ae144ace20879160" + integrity sha512-t3Q2lvBMJucgTjQcP5+hvEJMAsJSk0qmAnjDLie2td017IiduZbbC9BOcFfmwzR6y6cJdZOuewLCNFmEx9IrXA== dependencies: "@azure/abort-controller" "^1.0.0" "@azure/core-http" "^3.0.0" @@ -201,7 +201,7 @@ "@electron/get@^1.12.4": version "1.12.4" - resolved "https://registry.npmjs.org/@electron/get/-/get-1.12.4.tgz" + resolved "https://registry.yarnpkg.com/@electron/get/-/get-1.12.4.tgz#a5971113fc1bf8fa12a8789dc20152a7359f06ab" integrity sha512-6nr9DbJPUR9Xujw6zD3y+rS95TyItEVM0NVjt1EehY2vUWfIgPiIPVHxCvaTS0xr2B+DRxovYVKbuOWqC35kjg== dependencies: debug "^4.1.1" @@ -217,14 +217,14 @@ "@malept/cross-spawn-promise@^1.1.0": version "1.1.1" - resolved "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d" integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ== dependencies: cross-spawn "^7.0.1" "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" @@ -232,12 +232,12 @@ "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -245,60 +245,60 @@ "@opentelemetry/api@^1.0.1": version "1.2.0" - resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.2.0.tgz#89ef99401cde6208cff98760b67663726ef26686" integrity sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g== "@sindresorhus/is@^0.14.0": version "0.14.0" - resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@sindresorhus/is@^4.0.0": version "4.0.0" - resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== "@szmarczak/http-timer@^1.1.2": version "1.1.2" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== dependencies: defer-to-connect "^1.0.1" "@szmarczak/http-timer@^4.0.5": version "4.0.5" - resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152" integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ== dependencies: defer-to-connect "^2.0.0" "@tootallnate/once@2": version "2.0.0" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== "@types/ansi-colors@^3.2.0": version "3.2.0" - resolved "https://registry.npmjs.org/@types/ansi-colors/-/ansi-colors-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/@types/ansi-colors/-/ansi-colors-3.2.0.tgz#3e4fe85d9131ce1c6994f3040bd0b25306c16a6e" integrity sha512-0caWAhXht9N2lOdMzJLXybsSkYCx1QOdxx6pae48tswI9QV3DFX26AoOpy0JxwhCb+zISTqmd6H8t9Zby9BoZg== "@types/azure@0.9.19": version "0.9.19" - resolved "https://registry.npmjs.org/@types/azure/-/azure-0.9.19.tgz" + resolved "https://registry.yarnpkg.com/@types/azure/-/azure-0.9.19.tgz#1a6a9bd856b437ddecf3f9fc8407a683c869ba02" integrity sha1-Gmqb2Fa0N93s8/n8hAemg8hpugI= dependencies: "@types/node" "*" "@types/byline@^4.2.32": version "4.2.32" - resolved "https://registry.npmjs.org/@types/byline/-/byline-4.2.32.tgz" + resolved "https://registry.yarnpkg.com/@types/byline/-/byline-4.2.32.tgz#9d35ec15968056118548412ee24c2c3026c997dc" integrity sha512-qtlm/J6XOO9p+Ep/ZB5+mCFEDhzWDDHWU4a1eReN7lkPZXW9rkloq2jcAhvKKmlO5tL2GSvKROb+PTsNVhBiyQ== dependencies: "@types/node" "*" "@types/cacheable-request@^6.0.1": version "6.0.1" - resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976" integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ== dependencies: "@types/http-cache-semantics" "*" @@ -308,41 +308,49 @@ "@types/caseless@*": version "0.12.1" - resolved "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.1.tgz#9794c69c8385d0192acc471a540d1f8e0d16218a" integrity sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A== +"@types/chokidar@*": + version "1.7.5" + resolved "https://registry.yarnpkg.com/@types/chokidar/-/chokidar-1.7.5.tgz#1fa78c8803e035bed6d98e6949e514b133b0c9b6" + integrity sha512-PDkSRY7KltW3M60hSBlerxI8SFPXsO3AL/aRVsO4Kh9IHRW74Ih75gUuTd/aE4LSSFqypb10UIX3QzOJwBQMGQ== + dependencies: + "@types/events" "*" + "@types/node" "*" + "@types/cssnano@^4.0.0": version "4.0.1" - resolved "https://registry.npmjs.org/@types/cssnano/-/cssnano-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/@types/cssnano/-/cssnano-4.0.1.tgz#67fa912753d80973a016e7684a47fedf338aacff" integrity sha512-hGOroxRTBkYl5gSBRJOffhV4+io+Y2bFX1VP7LgKEVHJt/LPPJaWUIuDAz74Vlp7l7hCDZfaDi7iPxwNwuVA4Q== dependencies: postcss "5 - 7" "@types/debounce@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@types/debounce/-/debounce-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@types/debounce/-/debounce-1.0.0.tgz#417560200331e1bb84d72da85391102c2fcd61b7" integrity sha1-QXVgIAMx4buE1y2oU5EQLC/NYbc= "@types/debug@4.1.5": version "4.1.5" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== "@types/documentdb@^1.10.5": version "1.10.8" - resolved "https://registry.npmjs.org/@types/documentdb/-/documentdb-1.10.8.tgz" + resolved "https://registry.yarnpkg.com/@types/documentdb/-/documentdb-1.10.8.tgz#cf2008f8a4944abbd971f2ac1dbb81abf2d92f92" integrity sha512-GkOXovVMlMVTYkPomq9rOI79DmVOMZ0TDziL3H3TSlhUSm1/txi5qA49H/qZRDFsExagjnf5Cd/4xF8mXVxubw== dependencies: "@types/node" "*" "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== "@types/eslint@4.16.1": version "4.16.1" - resolved "https://registry.npmjs.org/@types/eslint/-/eslint-4.16.1.tgz" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-4.16.1.tgz#19730c9fcb66b6e44742d12b27a603fabfeb2f49" integrity sha512-lRUXQAULl5geixTiP2K0iYvMUbCkEnuOwvLGjwff12I4ECxoW5QaWML5UUOZ1CvpQLILkddBdMPMZz4ByQizsg== dependencies: "@types/estree" "*" @@ -350,36 +358,36 @@ "@types/estree@*": version "0.0.41" - resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.41.tgz" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.41.tgz#fd90754150b57432b72bf560530500597ff04421" integrity sha512-rIAmXyJlqw4KEBO7+u9gxZZSQHaCNnIzYrnNmYVpgfJhxTqO0brCX0SYpqUTkVI5mwwUwzmtspLBGBKroMeynA== "@types/events@*": version "1.2.0" - resolved "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== -"@types/fancy-log@^1.3.1": - version "1.3.1" - resolved "https://registry.npmjs.org/@types/fancy-log/-/fancy-log-1.3.1.tgz" - integrity sha512-31Dt9JaGfHretvwVxCBrCFL5iC9MQ3zOXpu+8C4qzW0cxc5rJJVGxB5c/vZ+wmeTk/JjPz/D0gv8BZ+Ip6iCqQ== +"@types/fancy-log@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@types/fancy-log/-/fancy-log-1.3.0.tgz#a61ab476e5e628cd07a846330df53b85e05c8ce0" + integrity sha512-mQjDxyOM1Cpocd+vm1kZBP7smwKZ4TNokFeds9LV7OZibmPJFEzY3+xZMrKfUdNT71lv8GoCPD6upKwHxubClw== "@types/form-data@*": version "2.2.1" - resolved "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-2.2.1.tgz#ee2b3b8eaa11c0938289953606b745b738c54b1e" integrity sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ== dependencies: "@types/node" "*" "@types/fs-extra@^9.0.12": version "9.0.12" - resolved "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.12.tgz#9b8f27973df8a7a3920e8461517ebf8a7d4fdfaf" integrity sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw== dependencies: "@types/node" "*" "@types/glob-stream@*": version "6.1.0" - resolved "https://registry.npmjs.org/@types/glob-stream/-/glob-stream-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/@types/glob-stream/-/glob-stream-6.1.0.tgz#7ede8a33e59140534f8d8adfb8ac9edfb31897bc" integrity sha512-RHv6ZQjcTncXo3thYZrsbAVwoy4vSKosSWhuhuQxLOTv74OJuFQxXkmUuZCr3q9uNBEVCvIzmZL/FeRNbHZGUg== dependencies: "@types/glob" "*" @@ -387,7 +395,7 @@ "@types/glob@*", "@types/glob@^7.1.1": version "7.1.1" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== dependencies: "@types/events" "*" @@ -396,15 +404,15 @@ "@types/gulp-concat@^0.0.32": version "0.0.32" - resolved "https://registry.npmjs.org/@types/gulp-concat/-/gulp-concat-0.0.32.tgz" + resolved "https://registry.yarnpkg.com/@types/gulp-concat/-/gulp-concat-0.0.32.tgz#72486028b1cf5faa94c8c1cf34c626531cecacd6" integrity sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g== dependencies: "@types/node" "*" -"@types/gulp-filter@^3.0.35": - version "3.0.35" - resolved "https://registry.npmjs.org/@types/gulp-filter/-/gulp-filter-3.0.35.tgz" - integrity sha512-xBdmHVMnPvAdwyLDFD2Yi8lYXXhYlMWnsWxvMPiinj8b7LJmzNKloI4TQyod+WXEfbiUsHULp0q0qdCIXBVRDQ== +"@types/gulp-filter@^3.0.32": + version "3.0.32" + resolved "https://registry.yarnpkg.com/@types/gulp-filter/-/gulp-filter-3.0.32.tgz#eeff3e9dbc092268fed01f2421ab00f6c8cb4848" + integrity sha512-JvY4qTxXehoK2yCUxYVxTMvckVbDM5TWHWeUoYJyX31gwFqw4YDD6JNzhuTxI3yHPUTY4BBRTqgm6puQEZVCNg== dependencies: "@types/minimatch" "*" "@types/node" "*" @@ -412,14 +420,14 @@ "@types/gulp-gzip@^0.0.31": version "0.0.31" - resolved "https://registry.npmjs.org/@types/gulp-gzip/-/gulp-gzip-0.0.31.tgz" + resolved "https://registry.yarnpkg.com/@types/gulp-gzip/-/gulp-gzip-0.0.31.tgz#9358def25540442138fd61a7227f40d4c1e26760" integrity sha512-KQjHz1FTqLse8/EiktfhN/vo33vamX4gVAQhMTp55STDBA7UToW5CJqYyP7iRorkHK9/aJ2nL2hLkNZkY4M8+w== dependencies: "@types/node" "*" "@types/gulp-json-editor@^2.2.31": version "2.2.31" - resolved "https://registry.npmjs.org/@types/gulp-json-editor/-/gulp-json-editor-2.2.31.tgz" + resolved "https://registry.yarnpkg.com/@types/gulp-json-editor/-/gulp-json-editor-2.2.31.tgz#3c1a8950556c109a0e2d0ab11d5f2a2443665ed2" integrity sha512-piis0ImYAy0dt18R4EtTbAY+RV8jwTq5VisnUV6OfP8kD4743aHGkAdAd08No4NY3rFa5mD6ytIu8L0YU7nL9w== dependencies: "@types/js-beautify" "*" @@ -427,7 +435,7 @@ "@types/gulp-postcss@^8.0.0": version "8.0.0" - resolved "https://registry.npmjs.org/@types/gulp-postcss/-/gulp-postcss-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/@types/gulp-postcss/-/gulp-postcss-8.0.0.tgz#f7e86d45e4999fd43e6d8c55b00504c88a67ad61" integrity sha512-AVgjA03bpkYONKZpzuJviB9PzaNbDzrovYPbenj8/XxivUc35C/dIzJanyaQv7CFqfLLPLsqSalmtP3GLq6iag== dependencies: "@types/node" "*" @@ -435,104 +443,109 @@ "@types/gulp-rename@^0.0.33": version "0.0.33" - resolved "https://registry.npmjs.org/@types/gulp-rename/-/gulp-rename-0.0.33.tgz" + resolved "https://registry.yarnpkg.com/@types/gulp-rename/-/gulp-rename-0.0.33.tgz#38d146e97786569f74f5391a1b1f9b5198674b6c" integrity sha512-FIZQvbZJj6V1gHPTzO+g/BCWpDur7fJrroae4gwV3LaoHBQ+MrR9sB+2HssK8fHv4WdY6hVNxkcft9bYatuPIA== dependencies: "@types/node" "*" "@types/gulp-sourcemaps@^0.0.32": version "0.0.32" - resolved "https://registry.npmjs.org/@types/gulp-sourcemaps/-/gulp-sourcemaps-0.0.32.tgz" + resolved "https://registry.yarnpkg.com/@types/gulp-sourcemaps/-/gulp-sourcemaps-0.0.32.tgz#e79ee617e0cb15729874be4533fe59c07793a175" integrity sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA== dependencies: "@types/node" "*" -"@types/gulp@^4.0.10": - version "4.0.10" - resolved "https://registry.npmjs.org/@types/gulp/-/gulp-4.0.10.tgz" - integrity sha512-spgZHJFqiEJGwqGlf7T/k4nkBpBcLgP7T0EfN6G2vvnhUfvd4uO1h8RwpXOE8x/54DVYUs1XCAtBHkX/R3axAQ== +"@types/gulp@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-4.0.5.tgz#f5f498d5bf9538364792de22490a12c0e6bc5eb4" + integrity sha512-nx1QjPTiRpvLfYsZ7MBu7bT6Cm7tAXyLbY0xbdx2IEMxCK2v2urIhJMQZHW0iV1TskM71Xl6p2uRRuWDbk+/7g== dependencies: - "@types/undertaker" ">=1.2.6" + "@types/chokidar" "*" + "@types/undertaker" "*" "@types/vinyl-fs" "*" - chokidar "^3.3.1" "@types/http-cache-semantics@*": version "4.0.0" - resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a" integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A== "@types/js-beautify@*": version "1.8.0" - resolved "https://registry.npmjs.org/@types/js-beautify/-/js-beautify-1.8.0.tgz" + resolved "https://registry.yarnpkg.com/@types/js-beautify/-/js-beautify-1.8.0.tgz#0369d3d0e1f35a6aec07cb4da2ee2bcda111367c" integrity sha512-/siF86XrwDKLuHe8l7h6NhrAWgLdgqbxmjZv9NvGWmgYRZoTipkjKiWb0SQHy/jcR+ee0GvbG6uGd+LEBMGNvA== "@types/json-schema@*": version "7.0.4" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== "@types/json-schema@^7.0.3": version "7.0.7" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== "@types/keyv@*": version "3.1.1" - resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7" integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw== dependencies: "@types/node" "*" "@types/mime@0.0.29": version "0.0.29" - resolved "https://registry.npmjs.org/@types/mime/-/mime-0.0.29.tgz" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-0.0.29.tgz#fbcfd330573b912ef59eeee14602bface630754b" integrity sha1-+8/TMFc7kS71nu7hRgK/rOYwdUs= "@types/minimatch@*", "@types/minimatch@^3.0.3": version "3.0.3" - resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/minimist@^1.2.1": version "1.2.1" - resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== "@types/mkdirp@^1.0.1": version "1.0.1" - resolved "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.1.tgz#0930b948914a78587de35458b86c907b6e98bbf6" integrity sha512-HkGSK7CGAXncr8Qn/0VqNtExEE+PHMWb+qlR1faHMao7ng6P3tAaoWWBMdva0gL5h4zprjIO89GJOLXsMcDm1Q== dependencies: "@types/node" "*" "@types/mocha@^9.1.1": version "9.1.1" - resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node-fetch@^2.5.0": version "2.5.8" - resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.8.tgz" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.8.tgz#e199c835d234c7eb0846f6618012e558544ee2fb" integrity sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw== dependencies: "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@16.x": +"@types/node@*": + version "8.0.51" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb" + integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ== + +"@types/node@16.x": version "16.11.62" - resolved "https://registry.npmjs.org/@types/node/-/node-16.11.62.tgz" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.62.tgz#bab2e6208531321d147eda20c38e389548cd5ffc" integrity sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ== "@types/p-limit@^2.2.0": version "2.2.0" - resolved "https://registry.npmjs.org/@types/p-limit/-/p-limit-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/@types/p-limit/-/p-limit-2.2.0.tgz#94a608e9b258a6c6156a13d1a14fd720dba70b97" integrity sha512-fGFbybl1r0oE9mqgfc2EHHUin9ZL5rbQIexWI6jYRU1ADVn4I3LHzT+g/kpPpZsfp8PB94CQ655pfAjNF8LP6A== dependencies: p-limit "*" "@types/plist@^3.0.2": version "3.0.2" - resolved "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01" integrity sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw== dependencies: "@types/node" "*" @@ -540,14 +553,14 @@ "@types/pump@^1.0.1": version "1.0.1" - resolved "https://registry.npmjs.org/@types/pump/-/pump-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@types/pump/-/pump-1.0.1.tgz#ae8157cefef04d1a4d24c1cc91d403c2f5da5cd0" integrity sha1-roFXzv7wTRpNJMHMkdQDwvXaXNA= dependencies: "@types/node" "*" "@types/request@^2.47.0": version "2.47.0" - resolved "https://registry.npmjs.org/@types/request/-/request-2.47.0.tgz" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.47.0.tgz#76a666cee4cb85dcffea6cd4645227926d9e114e" integrity sha512-/KXM5oev+nNCLIgBjkwbk8VqxmzI56woD4VUxn95O+YeQ8hJzcSmIZ1IN3WexiqBb6srzDo2bdMbsXxgXNkz5Q== dependencies: "@types/caseless" "*" @@ -557,21 +570,21 @@ "@types/resolve@0.0.8": version "0.0.8" - resolved "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ== dependencies: "@types/node" "*" "@types/responselike@*", "@types/responselike@^1.0.0": version "1.0.0" - resolved "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== dependencies: "@types/node" "*" "@types/rimraf@^2.0.4": version "2.0.4" - resolved "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.4.tgz#403887b0b53c6100a6c35d2ab24f6ccc042fec46" integrity sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q== dependencies: "@types/glob" "*" @@ -579,74 +592,73 @@ "@types/source-list-map@*": version "0.1.2" - resolved "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/tapable@^1": version "1.0.8" - resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== "@types/through2@^2.0.34": version "2.0.34" - resolved "https://registry.npmjs.org/@types/through2/-/through2-2.0.34.tgz" + resolved "https://registry.yarnpkg.com/@types/through2/-/through2-2.0.34.tgz#9c2a259a238dace2a05a2f8e94b786961bc27ac4" integrity sha512-nhRG8+RuG/L+0fAZBQYaRflXKjTrHOKH8MFTChnf+dNVMxA3wHYYrfj0tztK0W51ABXjGfRCDc0vRkecCOrsow== dependencies: "@types/node" "*" "@types/through@^0.0.29": version "0.0.29" - resolved "https://registry.npmjs.org/@types/through/-/through-0.0.29.tgz" + resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.29.tgz#72943aac922e179339c651fa34a4428a4d722f93" integrity sha512-9a7C5VHh+1BKblaYiq+7Tfc+EOmjMdZaD1MYtkQjSoxgB69tBjW98ry6SKsi4zEIWztLOMRuL87A3bdT/Fc/4w== dependencies: "@types/node" "*" "@types/tmp@^0.2.1": version "0.2.1" - resolved "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.2.1.tgz#83ecf4ec22a8c218c71db25f316619fe5b986011" integrity sha512-7cTXwKP/HLOPVgjg+YhBdQ7bMiobGMuoBmrGmqwIWJv8elC6t1DfVc/mn4fD9UE1IjhwmhaQ5pGVXkmXbH0rhg== "@types/tough-cookie@*": version "2.3.2" - resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.2.tgz" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.2.tgz#e0d481d8bb282ad8a8c9e100ceb72c995fb5e709" integrity sha512-vOVmaruQG5EatOU/jM6yU2uCp3Lz6mK1P5Ztu4iJjfM4SVHU9XYktPUQtKlIXuahqXHdEyUarMrBEwg5Cwu+bA== "@types/tunnel@^0.0.3": version "0.0.3" - resolved "https://registry.npmjs.org/@types/tunnel/-/tunnel-0.0.3.tgz" + resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9" integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA== dependencies: "@types/node" "*" "@types/uglify-js@*": version "3.13.1" - resolved "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.1.tgz" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.1.tgz#5e889e9e81e94245c75b6450600e1c5ea2878aea" integrity sha512-O3MmRAk6ZuAKa9CHgg0Pr0+lUOqoMLpc9AS4R8ano2auvsg7IE8syF3Xh/NPr26TWklxYcqoEEFdzLLs1fV9PQ== dependencies: source-map "^0.6.1" "@types/underscore@^1.8.9": version "1.8.9" - resolved "https://registry.npmjs.org/@types/underscore/-/underscore-1.8.9.tgz" + resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.8.9.tgz#fef41f800cd23db1b4f262ddefe49cd952d82323" integrity sha512-vfzZGgZKRFy7KEWcBGfIFk+h6B+thDCLfkD1exMBMRlUsx2icA+J6y4kAbZs/TjSTeY1duw89QUU133TSzr60Q== "@types/undertaker-registry@*": version "1.0.1" - resolved "https://registry.npmjs.org/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/@types/undertaker-registry/-/undertaker-registry-1.0.1.tgz#4306d4a03d7acedb974b66530832b90729e1d1da" integrity sha512-Z4TYuEKn9+RbNVk1Ll2SS4x1JeLHecolIbM/a8gveaHsW0Hr+RQMraZACwTO2VD7JvepgA6UO1A1VrbktQrIbQ== -"@types/undertaker@>=1.2.6": - version "1.2.8" - resolved "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.8.tgz" - integrity sha512-gW3PRqCHYpo45XFQHJBhch7L6hytPsIe0QeLujlnFsjHPnXLhJcPdN6a9368d7aIQgH2I/dUTPFBlGeSNA3qOg== +"@types/undertaker@*": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/undertaker/-/undertaker-1.2.0.tgz#d39a81074b4f274eb656870fc904a70737e00f8e" + integrity sha512-bx/5nZCGkasXs6qaA3B6SVDjBZqdyk04UO12e0uEPSzjt5H8jEJw0DKe7O7IM0hM2bVHRh70pmOH7PEHqXwzOw== dependencies: - "@types/node" "*" + "@types/events" "*" "@types/undertaker-registry" "*" - async-done "~1.3.2" "@types/vinyl-fs@*": version "2.4.9" - resolved "https://registry.npmjs.org/@types/vinyl-fs/-/vinyl-fs-2.4.9.tgz" + resolved "https://registry.yarnpkg.com/@types/vinyl-fs/-/vinyl-fs-2.4.9.tgz#d312c24b5ba8d2db456d23ee4a66f9d016af82ea" integrity sha512-Q0EXd6c1fORjiOuK4ZaKdfFcMyFzJlTi56dqktwaWVLIDAzE49wUs3bKnYbZwzyMWoH+NcMWnRuR73S9A0jnRA== dependencies: "@types/events" "*" @@ -656,14 +668,14 @@ "@types/vinyl@*": version "2.0.2" - resolved "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.2.tgz#4f3b8dae8f5828d3800ef709b0cff488ee852de3" integrity sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw== dependencies: "@types/node" "*" "@types/webpack-sources@*": version "2.1.1" - resolved "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-2.1.1.tgz#6af17e3a3ded71eec2b98008d7c12f498a0a4506" integrity sha512-MjM1R6iuw8XaVbtkCBz0N349cyqBjJHCbQiOeppe3VBeFvxqs74RKHAVt9LkxTnUWc7YLZOEsUfPUnmK6SBPKQ== dependencies: "@types/node" "*" @@ -672,7 +684,7 @@ "@types/webpack@^4.41.25": version "4.41.30" - resolved "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.30.tgz" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.30.tgz#fd3db6d0d41e145a8eeeafcd3c4a7ccde9068ddc" integrity sha512-GUHyY+pfuQ6haAfzu4S14F+R5iGRwN6b2FRNJY7U0NilmFAqbsOfK6j1HwuLBAqwRIT+pVdNDJGJ6e8rpp0KHA== dependencies: "@types/node" "*" @@ -691,14 +703,14 @@ "@types/yauzl@^2.9.1": version "2.9.2" - resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA== dependencies: "@types/node" "*" "@typescript-eslint/experimental-utils@~2.13.0": version "2.13.0" - resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.13.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.13.0.tgz#958614faa6f77599ee2b241740e0ea402482533d" integrity sha512-+Hss3clwa6aNiC8ZjA45wEm4FutDV5HsVXPl/rDug1THq6gEtOYRGLqS3JlTk7mSnL5TbJz0LpEbzbPnKvY6sw== dependencies: "@types/json-schema" "^7.0.3" @@ -707,7 +719,7 @@ "@typescript-eslint/parser@^5.10.0": version "5.38.1" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.1.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.38.1.tgz#c577f429f2c32071b92dff4af4f5fbbbd2414bd0" integrity sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw== dependencies: "@typescript-eslint/scope-manager" "5.38.1" @@ -717,7 +729,7 @@ "@typescript-eslint/scope-manager@5.38.1": version "5.38.1" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz#f87b289ef8819b47189351814ad183e8801d5764" integrity sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ== dependencies: "@typescript-eslint/types" "5.38.1" @@ -725,12 +737,12 @@ "@typescript-eslint/types@5.38.1": version "5.38.1" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.1.tgz#74f9d6dcb8dc7c58c51e9fbc6653ded39e2e225c" integrity sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg== "@typescript-eslint/typescript-estree@2.13.0": version "2.13.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.13.0.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.13.0.tgz#a2e746867da772c857c13853219fced10d2566bc" integrity sha512-t21Mg5cc8T3ADEUGwDisHLIubgXKjuNRbkpzDMLb7/JMmgCe/gHM9FaaujokLey+gwTuLF5ndSQ7/EfQqrQx4g== dependencies: debug "^4.1.1" @@ -743,7 +755,7 @@ "@typescript-eslint/typescript-estree@5.38.1": version "5.38.1" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz#657d858d5d6087f96b638ee383ee1cff52605a1e" integrity sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g== dependencies: "@typescript-eslint/types" "5.38.1" @@ -756,17 +768,12 @@ "@typescript-eslint/visitor-keys@5.38.1": version "5.38.1" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz#508071bfc6b96d194c0afe6a65ad47029059edbc" integrity sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA== dependencies: "@typescript-eslint/types" "5.38.1" eslint-visitor-keys "^3.3.0" -"@vscode/iconv-lite-umd@0.7.0": - version "0.7.0" - resolved "https://registry.npmjs.org/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz" - integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg== - "@vscode/vsce@2.16.0": version "2.16.0" resolved "https://registry.yarnpkg.com/@vscode/vsce/-/vsce-2.16.0.tgz#a3ddcf7e84914576f35d891e236bc496c568776f" @@ -796,76 +803,56 @@ acorn@^7.1.0: version "7.4.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== agent-base@6: version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - ansi-colors@^1.0.1: version "1.1.0" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== dependencies: ansi-wrap "^0.1.0" -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz" - integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== - dependencies: - ansi-wrap "0.1.0" - ansi-regex@^2.0.0: version "2.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: +ansi-wrap@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== anymatch@^3.0.0: version "3.1.2" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" -anymatch@^3.1.1, anymatch@~3.1.1: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - applicationinsights@1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/applicationinsights/-/applicationinsights-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5" integrity sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg== dependencies: diagnostic-channel "0.2.0" @@ -874,12 +861,12 @@ applicationinsights@1.0.8: aproba@^1.0.3: version "1.2.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== are-we-there-yet@~1.1.2: version "1.1.7" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== dependencies: delegates "^1.0.0" @@ -887,27 +874,27 @@ are-we-there-yet@~1.1.2: argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== arr-diff@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== arr-union@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== asar@^3.0.3: version "3.0.3" - resolved "https://registry.npmjs.org/asar/-/asar-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/asar/-/asar-3.0.3.tgz#1fef03c2d6d2de0cbad138788e4f7ae03b129c7b" integrity sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw== dependencies: chromium-pickle-js "^0.2.0" @@ -919,32 +906,22 @@ asar@^3.0.3: assign-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== -async-done@~1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz" - integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.2" - process-nextick-args "^2.0.0" - stream-exhaust "^1.0.1" - asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= at-least-node@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== azure-devops-node-api@^11.0.1: version "11.1.1" - resolved "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.1.1.tgz" + resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-11.1.1.tgz#dd1356031fa4e334e016732594e8fee0f68268c4" integrity sha512-XDG91XzLZ15reP12s3jFkKS8oiagSICjnLwxEYieme4+4h3ZveFOFRA4iYIG40RyHXsiI0mefFYYMFIJbMpWcg== dependencies: tunnel "0.0.6" @@ -952,27 +929,22 @@ azure-devops-node-api@^11.0.1: balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - binary-search-bounds@2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/binary-search-bounds/-/binary-search-bounds-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-2.0.3.tgz#5ff8616d6dd2ca5388bc85b2d6266e2b9da502dc" integrity sha1-X/hhbW3SylOIvIWy1iZuK52lAtw= bl@^4.0.3: version "4.1.0" - resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== dependencies: buffer "^5.5.0" @@ -981,42 +953,42 @@ bl@^4.0.3: bluebird@^3.5.0: version "3.7.2" - resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== boolbase@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= boolean@^3.0.1: version "3.1.2" - resolved "https://registry.npmjs.org/boolean/-/boolean-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.1.2.tgz#e30f210a26b02458482a8cc353ab06f262a780c2" integrity sha512-YN6UmV0FfLlBVvRvNPx3pz5W/mUoYB24J4WSXOKP/OOJpi+Oq6WYqPaNTHzjI0QzwWtnvEd5CGYyQPgp1jFxnw== brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.2, braces@~3.0.2: +braces@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" buffer-alloc-unsafe@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== buffer-alloc@^1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== dependencies: buffer-alloc-unsafe "^1.1.0" @@ -1024,27 +996,27 @@ buffer-alloc@^1.2.0: buffer-crc32@~0.2.3: version "0.2.13" - resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= buffer-equal-constant-time@1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== buffer-equal@1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= buffer-fill@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= buffer@^5.5.0: version "5.7.1" - resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" @@ -1052,22 +1024,22 @@ buffer@^5.5.0: builtin-modules@^3.1.0: version "3.2.0" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== byline@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= cacheable-lookup@^5.0.3: version "5.0.4" - resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== cacheable-request@^6.0.0: version "6.1.0" - resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== dependencies: clone-response "^1.0.2" @@ -1080,7 +1052,7 @@ cacheable-request@^6.0.0: cacheable-request@^7.0.2: version "7.0.2" - resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== dependencies: clone-response "^1.0.2" @@ -1093,7 +1065,7 @@ cacheable-request@^7.0.2: call-bind@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: function-bind "^1.1.1" @@ -1101,7 +1073,7 @@ call-bind@^1.0.0: chalk@^2.4.2: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -1110,7 +1082,7 @@ chalk@^2.4.2: cheerio-select@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== dependencies: boolbase "^1.0.0" @@ -1122,7 +1094,7 @@ cheerio-select@^2.1.0: cheerio@^1.0.0-rc.9: version "1.0.0-rc.11" - resolved "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.11.tgz" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.11.tgz#1be84be1a126958366bcc57a11648cd9b30a60c2" integrity sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag== dependencies: cheerio-select "^2.1.0" @@ -1134,56 +1106,41 @@ cheerio@^1.0.0-rc.9: parse5-htmlparser2-tree-adapter "^7.0.0" tslib "^2.4.0" -chokidar@3.5.1, chokidar@^3.3.1: - version "3.5.1" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz" - integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.5.0" - optionalDependencies: - fsevents "~2.3.1" - chownr@^1.1.1: version "1.1.4" - resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== chromium-pickle-js@^0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz#04a106672c18b085ab774d983dfa3ea138f22205" integrity sha1-BKEGZywYsIWrd02YPfo+oTjyIgU= clone-buffer@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== clone-response@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= dependencies: mimic-response "^1.0.0" clone-stats@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== clone@^2.1.1: version "2.1.2" - resolved "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== cloneable-readable@^1.0.0: version "1.1.3" - resolved "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== dependencies: inherits "^2.0.1" @@ -1192,78 +1149,73 @@ cloneable-readable@^1.0.0: code-point-at@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-support@^1.1.3: - 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== - colors@1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= colors@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== combined-stream@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" commander@2.9.0: version "2.9.0" - resolved "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= dependencies: graceful-readlink ">= 1.0.0" commander@^5.0.0: version "5.1.0" - resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== commander@^6.1.0: version "6.2.1" - resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== commander@^7.0.0: version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== compare-version@^0.1.2: version "0.1.2" - resolved "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" integrity sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA= concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= config-chain@^1.1.11: version "1.1.13" - resolved "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== dependencies: ini "^1.3.4" @@ -1271,22 +1223,22 @@ config-chain@^1.1.11: console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= core-js@^3.6.5: version "3.15.2" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61" integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q== core-util-is@~1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cross-spawn@^7.0.1: version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -1295,7 +1247,7 @@ cross-spawn@^7.0.1: css-select@^5.1.0: version "5.1.0" - resolved "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== dependencies: boolbase "^1.0.0" @@ -1306,125 +1258,113 @@ css-select@^5.1.0: css-what@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== debug@4, debug@^4.3.4: version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" debug@^2.6.8: version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: +debug@^4.1.0, debug@^4.3.2: version "4.3.2" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" -debug@^4.3.1: +debug@^4.1.1, debug@^4.3.1: version "4.3.1" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" decompress-response@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= dependencies: mimic-response "^1.0.0" -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - decompress-response@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== dependencies: mimic-response "^3.1.0" deep-extend@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== defer-to-connect@^1.0.1: version "1.1.3" - resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== defer-to-connect@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1" integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg== define-lazy-prop@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-properties@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== dependencies: object-keys "^1.0.12" delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= delegates@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz" - integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== - detect-libc@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== detect-node@^2.0.4: version "2.1.0" - resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== diagnostic-channel-publishers@0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3" integrity sha1-ji1geottef6IC1SLxYzGvrKIxPM= diagnostic-channel@0.2.0: version "0.2.0" - resolved "https://registry.npmjs.org/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz" + resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17" integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc= dependencies: semver "^5.3.0" dir-compare@^2.4.0: version "2.4.0" - resolved "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz" + resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631" integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA== dependencies: buffer-equal "1.0.0" @@ -1434,14 +1374,14 @@ dir-compare@^2.4.0: dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" documentdb@1.13.0: version "1.13.0" - resolved "https://registry.npmjs.org/documentdb/-/documentdb-1.13.0.tgz" + resolved "https://registry.yarnpkg.com/documentdb/-/documentdb-1.13.0.tgz#bba6f03150b2f42498cec4261bc439d834a33f8b" integrity sha1-u6bwMVCy9CSYzsQmG8Q52DSjP4s= dependencies: binary-search-bounds "2.0.3" @@ -1451,7 +1391,7 @@ documentdb@1.13.0: dom-serializer@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== dependencies: domelementtype "^2.3.0" @@ -1460,19 +1400,19 @@ dom-serializer@^2.0.0: domelementtype@^2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: version "5.0.3" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== dependencies: domelementtype "^2.3.0" domutils@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== dependencies: dom-serializer "^2.0.0" @@ -1481,19 +1421,19 @@ domutils@^3.0.1: duplexer3@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= ecdsa-sig-formatter@1.0.11: version "1.0.11" - resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== dependencies: safe-buffer "^5.0.1" electron-osx-sign@^0.4.16: version "0.4.17" - resolved "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.17.tgz" + resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.4.17.tgz#2727ca0c79e1e4e5ccd3861fb3da9c3c913b006c" integrity sha512-wUJPmZJQCs1zgdlQgeIpRcvrf7M5/COQaOV68Va1J/SgmWx5KL2otgg+fAae7luw6qz9R8Gvu/Qpe9tAOu/3xQ== dependencies: bluebird "^3.5.0" @@ -1505,59 +1445,59 @@ electron-osx-sign@^0.4.16: emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== encodeurl@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" entities@^4.2.0, entities@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.0.tgz#62915f08d67353bb4eb67e3d62641a4059aec656" integrity sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg== entities@~2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== env-paths@^2.2.0: version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== es6-error@^4.1.1: version "4.1.1" - resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== esbuild@^0.12.6: version "0.12.6" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.6.tgz" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.6.tgz#85bc755c7cf3005d4f34b4f10f98049ce0ee67ce" integrity sha512-RDvVLvAjsq/kIZJoneMiUOH7EE7t2QaW7T3Q7EdQij14+bZbDq5sndb0tTanmHIFSqZVMBMMyqzVHkS3dJobeA== escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== eslint-scope@^5.0.0: version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -1565,49 +1505,49 @@ eslint-scope@^5.0.0: eslint-visitor-keys@^1.1.0: version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== estree-walker@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== events@^3.0.0: version "3.2.0" - resolved "https://registry.npmjs.org/events/-/events-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== expand-template@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== extend-shallow@^3.0.2: version "3.0.2" - resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== dependencies: assign-symbols "^1.0.0" @@ -1615,7 +1555,7 @@ extend-shallow@^3.0.2: extract-zip@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== dependencies: debug "^4.1.1" @@ -1624,19 +1564,9 @@ extract-zip@^2.0.1: optionalDependencies: "@types/yauzl" "^2.9.1" -fancy-log@^1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - fast-glob@^3.2.9: version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -1647,40 +1577,33 @@ fast-glob@^3.2.9: fast-json-stable-stringify@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fastq@^1.6.0: version "1.13.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" fd-slicer@~1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= dependencies: pend "~1.2.0" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" -first-chunk-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz" - integrity sha512-X8Z+b/0L4lToKYq+lwnKqi9X/Zek0NibLpsJgVsSxpoYq7JtiCtRb5HqKVEjEw/qAb/4AKKRLOwwKHlWNpm2Eg== - dependencies: - readable-stream "^2.0.2" - form-data@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" @@ -1689,7 +1612,7 @@ form-data@^3.0.0: form-data@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" @@ -1698,12 +1621,12 @@ form-data@^4.0.0: fs-constants@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== fs-extra@^8.1.0: version "8.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: graceful-fs "^4.2.0" @@ -1712,7 +1635,7 @@ fs-extra@^8.1.0: fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== dependencies: at-least-node "^1.0.0" @@ -1722,22 +1645,17 @@ fs-extra@^9.0.1, fs-extra@^9.1.0: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== gauge@~2.7.3: version "2.7.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= dependencies: aproba "^1.0.3" @@ -1751,7 +1669,7 @@ gauge@~2.7.3: get-intrinsic@^1.0.2: version "1.1.1" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== dependencies: function-bind "^1.1.1" @@ -1760,33 +1678,33 @@ get-intrinsic@^1.0.2: get-stream@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== dependencies: pump "^3.0.0" get-stream@^5.1.0: version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" github-from-package@0.0.0: version "0.0.0" - resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= -glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob@^7.0.6: version "7.1.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== dependencies: fs.realpath "^1.0.0" @@ -1798,7 +1716,7 @@ glob@^7.0.6: glob@^7.1.3, glob@^7.1.6: version "7.1.7" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" @@ -1810,7 +1728,7 @@ glob@^7.1.3, glob@^7.1.6: global-agent@^2.0.2: version "2.2.0" - resolved "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc" integrity sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg== dependencies: boolean "^3.0.1" @@ -1823,7 +1741,7 @@ global-agent@^2.0.2: global-tunnel-ng@^2.7.1: version "2.7.1" - resolved "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz" + resolved "https://registry.yarnpkg.com/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz#d03b5102dfde3a69914f5ee7d86761ca35d57d8f" integrity sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg== dependencies: encodeurl "^1.0.2" @@ -1833,14 +1751,14 @@ global-tunnel-ng@^2.7.1: globalthis@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b" integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== dependencies: define-properties "^1.1.3" globby@^11.1.0: version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -1852,7 +1770,7 @@ globby@^11.1.0: got@11.8.5: version "11.8.5" - resolved "https://registry.npmjs.org/got/-/got-11.8.5.tgz" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046" integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ== dependencies: "@sindresorhus/is" "^4.0.0" @@ -1869,7 +1787,7 @@ got@11.8.5: got@^9.6.0: version "9.6.0" - resolved "https://registry.npmjs.org/got/-/got-9.6.0.tgz" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== dependencies: "@sindresorhus/is" "^0.14.0" @@ -1884,24 +1802,19 @@ got@^9.6.0: to-readable-stream "^1.0.0" url-parse-lax "^3.0.0" -graceful-fs@^4.1.2: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.8" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== "graceful-readlink@>= 1.0.0": version "1.0.1" - resolved "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= gulp-merge-json@^2.1.1: version "2.1.2" - resolved "https://registry.npmjs.org/gulp-merge-json/-/gulp-merge-json-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/gulp-merge-json/-/gulp-merge-json-2.1.2.tgz#7810dbf8f1f1a8638c18d46bad165bd44d18ea79" integrity sha512-FysBAdHdnQvZzigVJJzlrt6TEosHxVb0mR2h/8eSnd+eJyBvb1LQF1EIrovrOCfj4HGE5p/95wGEjXsJk9qomw== dependencies: json5 "^2.2.1" @@ -1912,36 +1825,36 @@ gulp-merge-json@^2.1.1: has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-symbols@^1.0.1: version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== has-unicode@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= has@^1.0.3: version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" hosted-git-info@^4.0.2: version "4.1.0" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" htmlparser2@^8.0.1: version "8.0.1" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== dependencies: domelementtype "^2.3.0" @@ -1951,12 +1864,12 @@ htmlparser2@^8.0.1: http-cache-semantics@^4.0.0: version "4.1.1" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== http-proxy-agent@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: "@tootallnate/once" "2" @@ -1965,7 +1878,7 @@ http-proxy-agent@^5.0.0: http2-wrapper@^1.0.0-beta.5.2: version "1.0.0-beta.5.2" - resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz#8b923deb90144aea65cf834b016a340fc98556f3" integrity sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ== dependencies: quick-lru "^5.1.1" @@ -1973,7 +1886,7 @@ http2-wrapper@^1.0.0-beta.5.2: https-proxy-agent@^5.0.0: version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" @@ -1981,22 +1894,22 @@ https-proxy-agent@^5.0.0: iconv-lite-umd@0.6.8: version "0.6.8" - resolved "https://registry.npmjs.org/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz" + resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0" integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A== ieee754@^1.1.13: version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" @@ -2004,167 +1917,162 @@ inflight@^1.0.4: inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@^1.3.4, ini@~1.3.0: version "1.3.8" - resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - is-core-module@^2.2.0: version "2.4.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-extendable@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: +is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-glob@^4.0.3: version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-module@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-plain-object@^2.0.4: version "2.0.4" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-reference@^1.1.2: version "1.2.1" - resolved "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== dependencies: "@types/estree" "*" -is-utf8@^0.2.0, is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz" - integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== - is-wsl@^2.2.0: version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" isarray@~1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isbinaryfile@^3.0.2: version "3.0.3" - resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80" integrity sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw== dependencies: buffer-alloc "^1.2.0" isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== jsbi@^3.1.3: version "3.1.4" - resolved "https://registry.npmjs.org/jsbi/-/jsbi-3.1.4.tgz" + resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.1.4.tgz#9654dd02207a66a4911b4e4bb74265bc2cbc9dd0" integrity sha512-52QRRFSsi9impURE8ZUbzAMCLjPm4THO7H2fcuIvaaeFTbSysvkodbQQXIVsNgq/ypDbq6dJiuGKL0vZ/i9hUg== json-buffer@3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= json-buffer@3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-schema@0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stringify-safe@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json5@^2.2.1: version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonc-parser@^2.3.0: version "2.3.1" - resolved "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.1.tgz#59549150b133f2efacca48fe9ce1ec0659af2342" integrity sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg== jsonfile@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= optionalDependencies: graceful-fs "^4.1.6" jsonfile@^6.0.1: version "6.1.0" - resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: universalify "^2.0.0" @@ -2183,7 +2091,7 @@ jsonwebtoken@9.0.0, jsonwebtoken@^8.5.1: jwa@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== dependencies: buffer-equal-constant-time "1.0.1" @@ -2192,7 +2100,7 @@ jwa@^1.4.1: jwa@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.0.tgz#a7e9c3f29dae94027ebcaf49975c9345593410fc" integrity sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA== dependencies: buffer-equal-constant-time "1.0.1" @@ -2201,7 +2109,7 @@ jwa@^2.0.0: jws@^3.2.2: version "3.2.2" - resolved "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== dependencies: jwa "^1.4.1" @@ -2209,7 +2117,7 @@ jws@^3.2.2: jws@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.0.tgz#2d4e8cf6a318ffaa12615e9dec7e86e6c97310f4" integrity sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg== dependencies: jwa "^2.0.0" @@ -2217,7 +2125,7 @@ jws@^4.0.0: keytar@^7.7.0: version "7.9.0" - resolved "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz" + resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.9.0.tgz#4c6225708f51b50cbf77c5aae81721964c2918cb" integrity sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ== dependencies: node-addon-api "^4.3.0" @@ -2225,38 +2133,38 @@ keytar@^7.7.0: keyv@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== dependencies: json-buffer "3.0.0" keyv@^4.0.0: version "4.0.3" - resolved "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.3.tgz#4f3aa98de254803cafcd2896734108daa35e4254" integrity sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA== dependencies: json-buffer "3.0.1" leven@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== linkify-it@^3.0.1: version "3.0.3" - resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.3.tgz#a98baf44ce45a550efb4d49c769d07524cc2fa2e" integrity sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ== dependencies: uc.micro "^1.0.1" lodash.mergewith@^4.6.1: version "4.6.2" - resolved "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== lodash.unescape@4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= lodash@^4.17.10, lodash@^4.17.21: @@ -2266,31 +2174,31 @@ lodash@^4.17.10, lodash@^4.17.21: lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== lowercase-keys@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" magic-string@^0.25.2: version "0.25.7" - resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== dependencies: sourcemap-codec "^1.4.4" markdown-it@^12.3.2: version "12.3.2" - resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90" integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg== dependencies: argparse "^2.0.1" @@ -2301,24 +2209,24 @@ markdown-it@^12.3.2: matcher@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca" integrity sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng== dependencies: escape-string-regexp "^4.0.0" mdurl@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -2326,132 +2234,120 @@ micromatch@^4.0.4: mime-db@1.46.0: version "1.46.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== mime-types@^2.1.12: version "2.1.29" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== dependencies: mime-db "1.46.0" mime@^1.3.4, mime@^1.4.1: version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - mimic-response@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimist@^1.2.0, minimist@^1.2.3: version "1.2.6" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" - resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== ms@2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.2, ms@^2.1.1: +ms@2.1.2: version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mute-stream@~0.0.4: version "0.0.8" - resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.14.0: - version "2.17.0" - resolved "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - napi-build-utils@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== -node-abi@^2.21.0: - version "2.30.1" - resolved "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz" - integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w== - dependencies: - semver "^5.4.1" - node-abi@^3.3.0: version "3.22.0" - resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.22.0.tgz" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.22.0.tgz#00b8250e86a0816576258227edbce7bbe0039362" integrity sha512-u4uAs/4Zzmp/jjsD9cyFYDXeISfUWaAVWshPmDZOFOv4Xl4SbzTXm53I04C2uRueYJ+0t5PEtLH/owbn2Npf/w== dependencies: semver "^7.3.5" node-abort-controller@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.0.1.tgz#f91fa50b1dee3f909afabb7e261b1e1d6b0cb74e" integrity sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw== node-addon-api@^4.3.0: version "4.3.0" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== -node-fetch@2, node-fetch@^2.6.7: +node-fetch@^2.6.7: version "2.6.7" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" -normalize-path@^3.0.0, normalize-path@~3.0.0: +normalize-path@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== normalize-url@^4.1.0: version "4.5.1" - resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== normalize-url@^6.0.1: version "6.1.0" - resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-conf@^1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== dependencies: config-chain "^1.1.11" @@ -2459,7 +2355,7 @@ npm-conf@^1.1.3: npmlog@^4.0.1: version "4.1.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== dependencies: are-we-there-yet "~1.1.2" @@ -2469,41 +2365,41 @@ npmlog@^4.0.1: nth-check@^2.0.1: version "2.1.1" - resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== dependencies: boolbase "^1.0.0" number-is-nan@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.1.0: version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-inspect@^1.9.0: version "1.12.1" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.1.tgz#28a661153bad7e470e4b01479ef1cb91ce511191" integrity sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA== object-keys@^1.0.12: version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" open@^8.0.0: version "8.4.0" - resolved "https://registry.npmjs.org/open/-/open-8.4.0.tgz" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== dependencies: define-lazy-prop "^2.0.0" @@ -2512,36 +2408,31 @@ open@^8.0.0: p-cancelable@^1.0.0: version "1.1.0" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== p-cancelable@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e" integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg== p-limit@*, p-limit@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" -parse-node-version@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz" - integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== - parse-semver@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8" integrity sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg= dependencies: semver "^5.1.0" parse5-htmlparser2-tree-adapter@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== dependencies: domhandler "^5.0.2" @@ -2549,67 +2440,62 @@ parse5-htmlparser2-tree-adapter@^7.0.0: parse5@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.0.0.tgz#51f74a5257f5fcc536389e8c2d0b3802e1bfa91a" integrity sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g== dependencies: entities "^4.3.0" path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pend@~1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= picomatch@^2.0.4: version "2.3.0" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - pify@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= plist@^3.0.1, plist@^3.0.5: version "3.0.5" - resolved "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987" integrity sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA== dependencies: base64-js "^1.5.1" xmlbuilder "^9.0.7" -plugin-error@1.0.1, plugin-error@^1.0.1: +plugin-error@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== dependencies: ansi-colors "^1.0.1" @@ -2619,35 +2505,16 @@ plugin-error@1.0.1, plugin-error@^1.0.1: "postcss@5 - 7": version "7.0.36" - resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb" integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== dependencies: chalk "^2.4.2" source-map "^0.6.1" supports-color "^6.1.0" -prebuild-install@^6.0.1: - version "6.1.4" - resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.4.tgz" - integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== - dependencies: - detect-libc "^1.0.3" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^2.21.0" - npmlog "^4.0.1" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^3.0.3" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - prebuild-install@^7.0.1: version "7.1.0" - resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.0.tgz" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.0.tgz#991b6ac16c81591ba40a6d5de93fb33673ac1370" integrity sha512-CNcMgI1xBypOyGqjp3wOc8AAo1nMhZS3Cwd3iHIxOdAUbb+YxdNuM4Z5iIrZ8RLvOsf3F3bl7b7xGq6DjQoNYA== dependencies: detect-libc "^2.0.0" @@ -2666,37 +2533,37 @@ prebuild-install@^7.0.1: prepend-http@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= priorityqueuejs@1.0.0, priorityqueuejs@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/priorityqueuejs/-/priorityqueuejs-1.0.0.tgz#2ee4f23c2560913e08c07ce5ccdd6de3df2c5af8" integrity sha1-LuTyPCVgkT4IwHzlzN1t498sWvg= process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== process@^0.11.10: version "0.11.10" - resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= progress@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== proto-list@~1.2.1: version "1.2.4" - resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= pump@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -2704,24 +2571,24 @@ pump@^3.0.0: qs@^6.9.1: version "6.11.0" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== quick-lru@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== rc@^1.2.7: version "1.2.8" - resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== dependencies: deep-extend "^0.6.0" @@ -2731,14 +2598,14 @@ rc@^1.2.7: read@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/read/-/read-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= dependencies: mute-stream "~0.0.4" -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5: +readable-stream@^2.0.6, readable-stream@^2.3.5: version "2.3.7" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== dependencies: core-util-is "~1.0.0" @@ -2751,47 +2618,31 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5: readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.0" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.5.0: - version "3.5.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz" - integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== - dependencies: - picomatch "^2.2.1" - remove-trailing-separator@^1.0.1: version "1.1.0" - resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== replace-ext@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== resolve-alpn@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.0.0.tgz#745ad60b3d6aff4b4a48e01b8c0bdc70959e0e8c" integrity sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA== resolve@^1.11.0, resolve@^1.11.1: version "1.20.0" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== dependencies: is-core-module "^2.2.0" @@ -2799,33 +2650,33 @@ resolve@^1.11.0, resolve@^1.11.1: responselike@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= dependencies: lowercase-keys "^1.0.0" responselike@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723" integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw== dependencies: lowercase-keys "^2.0.0" reusify@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.0: version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" roarr@^2.15.3: version "2.15.4" - resolved "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz" + resolved "https://registry.yarnpkg.com/roarr/-/roarr-2.15.4.tgz#f5fe795b7b838ccfe35dc608e0282b9eba2e7afd" integrity sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A== dependencies: boolean "^3.0.1" @@ -2837,7 +2688,7 @@ roarr@^2.15.3: rollup-plugin-commonjs@^10.1.0: version "10.1.0" - resolved "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz" + resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz#417af3b54503878e084d127adf4d1caf8beb86fb" integrity sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q== dependencies: estree-walker "^0.6.1" @@ -2848,7 +2699,7 @@ rollup-plugin-commonjs@^10.1.0: rollup-plugin-node-resolve@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz#730f93d10ed202473b1fb54a5997a7db8c6d8523" integrity sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw== dependencies: "@types/resolve" "0.0.8" @@ -2859,14 +2710,14 @@ rollup-plugin-node-resolve@^5.2.0: rollup-pluginutils@^2.8.1: version "2.8.2" - resolved "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== dependencies: estree-walker "^0.6.1" rollup@^1.20.3: version "1.32.1" - resolved "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.1.tgz#4480e52d9d9e2ae4b46ba0d9ddeaf3163940f9c4" integrity sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A== dependencies: "@types/estree" "*" @@ -2875,61 +2726,61 @@ rollup@^1.20.3: run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== sax@>=0.6.0: version "1.2.4" - resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== semaphore@1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/semaphore/-/semaphore-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.0.5.tgz#b492576e66af193db95d65e25ec53f5f19798d60" integrity sha1-tJJXbmavGT25XWXiXsU/Xxl5jWA= semaphore@^1.0.5: version "1.1.0" - resolved "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa" integrity sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA== semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: +semver@^5.1.0, semver@^5.3.0: version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^6.2.0, semver@^6.3.0: version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.3.2: version "7.3.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== dependencies: lru-cache "^6.0.0" semver@^7.3.5, semver@^7.3.7: version "7.3.7" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" @@ -2943,31 +2794,31 @@ semver@^7.3.8: serialize-error@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-7.0.1.tgz#f1360b0447f61ffb483ec4157c737fab7d778e18" integrity sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw== dependencies: type-fest "^0.13.1" set-blocking@~2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== side-channel@^1.0.4: version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: call-bind "^1.0.0" @@ -2976,26 +2827,17 @@ side-channel@^1.0.4: signal-exit@^3.0.0: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simple-concat@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== -simple-get@^3.0.3: - version "3.1.1" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz" - integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - simple-get@^4.0.0: version "4.0.1" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== dependencies: decompress-response "^6.0.0" @@ -3004,42 +2846,37 @@ simple-get@^4.0.0: slash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@^0.7.3: version "0.7.3" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== sourcemap-codec@^1.4.4: version "1.4.8" - resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== sprintf-js@^1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== stoppable@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/stoppable/-/stoppable-1.1.0.tgz#32da568e83ea488b08e4d7ea2c3bcc9d75015d5b" integrity sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw== -stream-exhaust@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz" - integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== - string-width@^1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" @@ -3048,7 +2885,7 @@ string-width@^1.0.1: "string-width@^1.0.2 || 2 || 3 || 4": version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -3057,83 +2894,61 @@ string-width@^1.0.1: string_decoder@^1.1.1: version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" string_decoder@~1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== dependencies: safe-buffer "~5.1.0" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-bom-buf@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz" - integrity sha512-1sUIL1jck0T1mhOLP2c696BIznzT525Lkub+n4jjMHjhjhoAQA6Ye659DxdlZBr0aLDMQoTxKIpnlqxgtwjsuQ== - dependencies: - is-utf8 "^0.2.1" - -strip-bom-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz" - integrity sha512-yH0+mD8oahBZWnY43vxs4pSinn8SMKAdml/EOGBewoe1Y0Eitd0h2Mg3ZRiXruUW6L4P+lvZiEgbh0NgUGia1w== - dependencies: - first-chunk-stream "^2.0.0" - strip-bom "^2.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" - integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== - dependencies: - is-utf8 "^0.2.0" - strip-json-comments@~2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= sumchecker@^3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" integrity sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg== dependencies: debug "^4.1.0" supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^6.1.0: version "6.1.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== dependencies: has-flag "^3.0.0" tar-fs@^2.0.0: version "2.1.1" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== dependencies: chownr "^1.1.1" @@ -3143,7 +2958,7 @@ tar-fs@^2.0.0: tar-stream@^2.1.4: version "2.2.0" - resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== dependencies: bl "^4.0.3" @@ -3154,179 +2969,148 @@ tar-stream@^2.1.4: through@^2.3.8: version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz" - integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== - tmp@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== dependencies: rimraf "^3.0.0" to-readable-stream@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" tr46@~0.0.3: version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= -tree-sitter-typescript@^0.20.1: - version "0.20.1" - resolved "https://registry.npmjs.org/tree-sitter-typescript/-/tree-sitter-typescript-0.20.1.tgz" - integrity sha512-wqpnhdVYX26ATNXeZtprib4+mF2GlYQB1cjRPibYGxDRiugx5OfjWwLE4qPPxEGdp2ZLSmZVesGUjLWzfKo6rA== - dependencies: - nan "^2.14.0" - -"tree-sitter@https://github.com/joaomoreno/node-tree-sitter/releases/download/v0.20.0/tree-sitter-0.20.0.tgz": - version "0.20.0" - resolved "https://github.com/joaomoreno/node-tree-sitter/releases/download/v0.20.0/tree-sitter-0.20.0.tgz" - integrity sha512-FfyATFV6xANETqV0izjt/iC76yxFM8oGe5IfeyGfqXxRTsKKs2IOSGx1LTa6guOL3M2SagIQShAkHkJ4sK5/eA== - dependencies: - nan "^2.14.0" - prebuild-install "^6.0.1" - tslib@^1.8.1: version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.0: version "2.0.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== tslib@^2.2.0, tslib@^2.4.0: version "2.4.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tsutils@^3.17.1: version "3.20.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.20.0.tgz" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.20.0.tgz#ea03ea45462e146b53d70ce0893de453ff24f698" integrity sha512-RYbuQuvkhuqVeXweWT3tJLKOEJ/UUw9GjNEZGWdrLLlM+611o1gwLHBpxoFJKKl25fLprp2eVthtKs5JOrNeXg== dependencies: tslib "^1.8.1" tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" tunnel-agent@^0.6.0: version "0.6.0" - resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= dependencies: safe-buffer "^5.0.1" tunnel@0.0.6, tunnel@^0.0.6: version "0.0.6" - resolved "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== type-fest@^0.13.1: version "0.13.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== typed-rest-client@^1.8.4: version "1.8.9" - resolved "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz" + resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.8.9.tgz#e560226bcadfe71b0fb5c416b587f8da3b8f92d8" integrity sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g== dependencies: qs "^6.9.1" tunnel "0.0.6" underscore "^1.12.1" -typescript@^4.8.0-dev.20220518: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^4.5.0-dev.20210817: + version "4.5.0-dev.20210817" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.0-dev.20210817.tgz#6b0d0ce68c2381cc85fd0d609817cb3576eb9480" + integrity sha512-G427tdOZrQKSEUcLF+dq57gK7D6CzxhbZggpEwqZP1HDuBhIk2bu+br9QvR5uoubR2P6lHhWhUZaCDmkIpnnDQ== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" - resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== underscore@1.8.3: version "1.8.3" - resolved "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI= underscore@^1.12.1: version "1.13.3" - resolved "https://registry.npmjs.org/underscore/-/underscore-1.13.3.tgz" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.3.tgz#54bc95f7648c5557897e5e968d0f76bc062c34ee" integrity sha512-QvjkYpiD+dJJraRA8+dGAU4i7aBbb2s0S3jA45TFOvg2VgqvdCDd/3N6CqA8gluk1W91GLoXg5enMUx560QzuA== universal-user-agent@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== universalify@^0.1.0: version "0.1.2" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== url-join@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== url-parse-lax@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= dependencies: prepend-http "^2.0.0" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= uuid@^8.3.0: version "8.3.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== -vinyl-file@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/vinyl-file/-/vinyl-file-3.0.0.tgz" - integrity sha512-BoJDj+ca3D9xOuPEM6RWVtWQtvEPQiQYn82LvdxhLWplfQsBzBqtgK0yhCP0s1BNTi6dH9BO+dzybvyQIacifg== - dependencies: - graceful-fs "^4.1.2" - pify "^2.3.0" - strip-bom-buf "^1.0.0" - strip-bom-stream "^2.0.0" - vinyl "^2.0.1" - -vinyl@^2.0.1, vinyl@^2.2.0, vinyl@^2.2.1: +vinyl@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== dependencies: clone "^2.1.1" @@ -3336,52 +3120,9 @@ vinyl@^2.0.1, vinyl@^2.2.0, vinyl@^2.2.1: remove-trailing-separator "^1.0.1" replace-ext "^1.0.0" -vsce@2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/vsce/-/vsce-2.8.0.tgz" - integrity sha512-p6BTbUVp33Ed0OWRRhRQT55yrmgLEca2fTmqxZJW44T1eP4yVWEsdaNIDsjFIeuCrjG/CYvwi1QLG4ql0s7bDA== - dependencies: - azure-devops-node-api "^11.0.1" - chalk "^2.4.2" - cheerio "^1.0.0-rc.9" - commander "^6.1.0" - glob "^7.0.6" - hosted-git-info "^4.0.2" - keytar "^7.7.0" - leven "^3.1.0" - markdown-it "^12.3.2" - mime "^1.3.4" - minimatch "^3.0.3" - parse-semver "^1.1.1" - read "^1.0.7" - semver "^5.1.0" - tmp "^0.2.1" - typed-rest-client "^1.8.4" - url-join "^4.0.1" - xml2js "^0.4.23" - yauzl "^2.3.1" - yazl "^2.2.2" - -vscode-gulp-watch@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/vscode-gulp-watch/-/vscode-gulp-watch-5.0.3.tgz" - integrity sha512-MTUp2yLE9CshhkNSNV58EQNxQSeF8lIj3mkXZX9a1vAk+EQNM2PAYdPUDSd/P/08W3PMHGznEiZyfK7JAjLosg== - dependencies: - ansi-colors "4.1.1" - anymatch "^3.1.1" - chokidar "3.5.1" - fancy-log "^1.3.3" - glob-parent "^5.1.1" - normalize-path "^3.0.0" - object-assign "^4.1.1" - plugin-error "1.0.1" - readable-stream "^3.6.0" - vinyl "^2.2.0" - vinyl-file "^3.0.0" - vscode-universal-bundler@^0.0.2: version "0.0.2" - resolved "https://registry.npmjs.org/vscode-universal-bundler/-/vscode-universal-bundler-0.0.2.tgz" + resolved "https://registry.yarnpkg.com/vscode-universal-bundler/-/vscode-universal-bundler-0.0.2.tgz#2c988dac681d3ffe6baec6defac0995cb833c55a" integrity sha512-FPJcvKnQGBqFzy6M6Nm2yvAczNLUeXsfYM6GwCex/pUOkvIM2icIHmiSvtMJINlLW1iG+oEwE3/LVbABmcjEmQ== dependencies: "@malept/cross-spawn-promise" "^1.1.0" @@ -3392,12 +3133,12 @@ vscode-universal-bundler@^0.0.2: webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= dependencies: tr46 "~0.0.3" @@ -3405,26 +3146,26 @@ whatwg-url@^5.0.0: which@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" wide-align@^1.1.0: version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: string-width "^1.0.2 || 2 || 3 || 4" wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= xml2js@^0.4.23: version "0.4.23" - resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== dependencies: sax ">=0.6.0" @@ -3440,27 +3181,27 @@ xml2js@^0.5.0: xmlbuilder@>=11.0.1: version "15.1.1" - resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== xmlbuilder@^9.0.7: version "9.0.7" - resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= xmlbuilder@~11.0.0: version "11.0.1" - resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yauzl@^2.10.0, yauzl@^2.3.1: version "2.10.0" - resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= dependencies: buffer-crc32 "~0.2.3" @@ -3468,17 +3209,17 @@ yauzl@^2.10.0, yauzl@^2.3.1: yazl@^2.2.2: version "2.5.1" - resolved "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz" + resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35" integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw== dependencies: buffer-crc32 "~0.2.3" yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zone.js@0.7.6: version "0.7.6" - resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.7.6.tgz" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009" integrity sha1-+7w50+AmHQmG8boGMG6zrrDSIAk= diff --git a/cglicenses.json b/cglicenses.json index 5612be6269..e969eb826e 100644 --- a/cglicenses.json +++ b/cglicenses.json @@ -147,58 +147,5 @@ "", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE." ] - }, - { - "name": "@vscode/win32-app-container-tokens", - "fullLicenseText": [ - "MIT License", - "", - "Copyright (c) Microsoft Corporation.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy", - "of this software and associated documentation files (the \"Software\"), to deal", - "in the Software without restriction, including without limitation the rights", - "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", - "copies of the Software, and to permit persons to whom the Software is", - "furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all", - "copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", - "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", - "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", - "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", - "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", - "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE", - "SOFTWARE" - ] - }, - { - // Reason: Waiting for https://github.com/microsoft/vscode-markdown-languageservice/pull/9 - "name": "vscode-markdown-languageservice", - "fullLicenseText": [ - "MIT License", - "", - "Copyright (c) Microsoft Corporation.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy", - "of this software and associated documentation files (the \"Software\"), to deal", - "in the Software without restriction, including without limitation the rights", - "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", - "copies of the Software, and to permit persons to whom the Software is", - "furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all", - "copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", - "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", - "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", - "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", - "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", - "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE", - "SOFTWARE" - ] } ] diff --git a/cgmanifest.json b/cgmanifest.json index 290816d4d2..f4cd487d91 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "chromium", "repositoryUrl": "https://chromium.googlesource.com/chromium/src", - "commitHash": "c53c15c92c076f8d7593518ba99a9f8a6fc5ead6" + "commitHash": "16e28102fdf876ce6d136674ba66343ede07441f" } }, "licenseDetail": [ @@ -40,7 +40,7 @@ "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ], "isOnlyProductionDependency": true, - "version": "102.0.5005.148" + "version": "100.0.4894.0" }, { "component": { @@ -48,11 +48,11 @@ "git": { "name": "nodejs", "repositoryUrl": "https://github.com/nodejs/node", - "commitHash": "442e84a358d75152556b5d087e4dd6a51615330d" + "commitHash": "acb71eab779fb56bf70e8a9e0cb2e82a089a87de" } }, "isOnlyProductionDependency": true, - "version": "16.14.2" + "version": "16.13.2" }, { "component": { @@ -539,40 +539,6 @@ "isOnlyProductionDependency": true, "license": "MIT", "version": "0.10.0" - }, - { - "name": "@vscode/win32-app-container-tokens", - "component": { - "type": "git", - "git": { - "name": "vscode-win32-app-container-tokens", - "repositoryUrl": "https://github.com/microsoft/vscode-win32-app-container-tokens", - "commitHash": "5b871f95fd9cb8efa8ee9a80600510d5e5339137" - } - }, - "licenseDetail":[ - "MIT License", - "", - "Copyright (c) Microsoft Corporation.", - "", - "Permission is hereby granted, free of charge, to any person obtaining a copy", - "of this software and associated documentation files (the \"Software\"), to deal", - "in the Software without restriction, including without limitation the rights", - "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell", - "copies of the Software, and to permit persons to whom the Software is", - "furnished to do so, subject to the following conditions:", - "", - "The above copyright notice and this permission notice shall be included in all", - "copies or substantial portions of the Software.", - "", - "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR", - "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,", - "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE", - "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", - "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,", - "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE", - "SOFTWARE" - ] } ], "version": 1 diff --git a/extensions/configuration-editing/package.json b/extensions/configuration-editing/package.json index fdd714a55c..f2ebd926da 100644 --- a/extensions/configuration-editing/package.json +++ b/extensions/configuration-editing/package.json @@ -52,8 +52,7 @@ ".devcontainer.json" ], "filenamePatterns": [ - "**/User/snippets/*.json", - "**/User/profiles/*/snippets/*.json" + "**/User/snippets/*.json" ] }, { "id": "json", @@ -79,10 +78,6 @@ "fileMatch": "%APP_SETTINGS_HOME%/settings.json", "url": "vscode://schemas/settings/user" }, - { - "fileMatch": "%APP_SETTINGS_HOME%/profiles/*/settings.json", - "url": "vscode://schemas/settings/profile" - }, { "fileMatch": "%MACHINE_SETTINGS_HOME%/settings.json", "url": "vscode://schemas/settings/machine" diff --git a/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json b/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json deleted file mode 100644 index d224f91910..0000000000 --- a/extensions/configuration-editing/schemas/devContainer.codespaces.schema.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "customizations": { - "type": "object", - "properties": { - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*\/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - } - } - } - } - } - }, - "codespaces": { - "type": "object", - "additionalProperties": true, - "description": "Codespaces-specific configuration.", - "deprecated": true, - "deprecationMessage": "Use 'customizations/codespaces' instead" - } - } -} diff --git a/extensions/configuration-editing/schemas/devContainer.schema.generated.json b/extensions/configuration-editing/schemas/devContainer.schema.generated.json index 4ae5033f3f..d47f119240 100644 --- a/extensions/configuration-editing/schemas/devContainer.schema.generated.json +++ b/extensions/configuration-editing/schemas/devContainer.schema.generated.json @@ -406,7 +406,6 @@ }, "customizations": { "type": "object", - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -430,186 +429,13 @@ } }, "additionalProperties": false - }, - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false } }, - "additionalProperties": false - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true + "additionalProperties": { + "type": "object", + "additionalProperties": true + }, + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." } }, "required": [ @@ -1016,7 +842,6 @@ }, "customizations": { "type": "object", - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -1040,186 +865,13 @@ } }, "additionalProperties": false - }, - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false } }, - "additionalProperties": false - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true + "additionalProperties": { + "type": "object", + "additionalProperties": true + }, + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." } }, "required": [ @@ -1592,7 +1244,6 @@ }, "customizations": { "type": "object", - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -1616,186 +1267,13 @@ } }, "additionalProperties": false - }, - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false } }, - "additionalProperties": false - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true + "additionalProperties": { + "type": "object", + "additionalProperties": true + }, + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." } }, "required": [ @@ -2142,7 +1620,6 @@ }, "customizations": { "type": "object", - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -2166,186 +1643,13 @@ } }, "additionalProperties": false - }, - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false } }, - "additionalProperties": false - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true + "additionalProperties": { + "type": "object", + "additionalProperties": true + }, + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." } }, "required": [ @@ -2657,7 +1961,6 @@ }, "customizations": { "type": "object", - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -2681,186 +1984,13 @@ } }, "additionalProperties": false - }, - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false } }, - "additionalProperties": false - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true + "additionalProperties": { + "type": "object", + "additionalProperties": true + }, + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." } }, "additionalProperties": false diff --git a/extensions/configuration-editing/schemas/devContainer.schema.src.json b/extensions/configuration-editing/schemas/devContainer.schema.src.json index 73456101bb..b0e5b5c6f4 100644 --- a/extensions/configuration-editing/schemas/devContainer.schema.src.json +++ b/extensions/configuration-editing/schemas/devContainer.schema.src.json @@ -309,7 +309,6 @@ }, "customizations": { "type": "object", - "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations.", "properties": { "vscode": { "type": "object", @@ -332,183 +331,13 @@ "description": "The port VS Code can use to connect to its backend." } } - }, - "codespaces": { - "type": "object", - "description": "Customizations specific to GitHub Codespaces", - "properties": { - "repositories": { - "type": "object", - "description": "Configuration relative to the given repositories, following the format 'owner/repo'.\n A wildcard (*) is permitted for the repo name (eg: 'microsoft/*')", - "patternProperties": { - "^[a-zA-Z0-9-_.]+[.]*\/[a-zA-Z0-9-_*]+[.]*$": { - "type": "object", - "additionalProperties": true, - "oneOf": [ - { - "properties": { - "permissions": { - "type": "object", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "additionalProperties": true, - "anyOf": [ - { - "properties": { - "actions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "checks": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "contents": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "deployments": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "discussions": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "issues": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "packages": { - "type": "string", - "enum": [ - "read" - ] - } - } - }, - { - "properties": { - "pages": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "pull_requests": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "repository_projects": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "statuses": { - "type": "string", - "enum": [ - "read", - "write" - ] - } - } - }, - { - "properties": { - "workflows": { - "type": "string", - "enum": [ - "write" - ] - } - } - } - ] - } - } - }, - { - "properties": { - "permissions": { - "type": "string", - "description": "Additional repository permissions.\n See https://aka.ms/ghcs/multi-repo-auth for more info.", - "enum": [ - "read-all", - "write-all" - ] - } - } - } - ] - } - } - } - } } - } - }, - "additionalProperties": { - "type": "object", - "additionalProperties": true + }, + "additionalProperties": { + "type": "object", + "additionalProperties": true + }, + "description": "Tool-specific configuration. Each tool should use a JSON object subproperty with a unique name to group its customizations." } } }, diff --git a/extensions/configuration-editing/schemas/devContainer.vscode.schema.json b/extensions/configuration-editing/schemas/devContainer.vscode.schema.json deleted file mode 100644 index e0f2a8aa68..0000000000 --- a/extensions/configuration-editing/schemas/devContainer.vscode.schema.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "customizations": { - "type": "object", - "properties": { - "vscode": { - "type": "object", - "properties": { - "extensions": { - "type": "array", - "description": "An array of extensions that should be installed into the container.", - "items": { - "type": "string", - "pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)(@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)?$", - "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." - } - }, - "settings": { - "$ref": "vscode://schemas/settings/machine", - "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again." - }, - "devPort": { - "type": "integer", - "description": "The port VS Code can use to connect to its backend." - } - } - } - } - }, - "extensions": { - "type": "array", - "description": "An array of extensions that should be installed into the container.", - "items": { - "type": "string", - "pattern": "^([a-z0-9A-Z][a-z0-9A-Z-]*)\\.([a-z0-9A-Z][a-z0-9A-Z-]*)((@(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?)|@prerelease)?$", - "errorMessage": "Expected format: '${publisher}.${name}' or '${publisher}.${name}@${version}'. Example: 'ms-dotnettools.csharp'." - }, - "deprecated": true, - "deprecationMessage": "Use 'customizations/vscode/extensions' instead" - }, - "settings": { - "$ref": "vscode://schemas/settings/machine", - "description": "Machine specific settings that should be copied into the container. These are only copied when connecting to the container for the first time, rebuilding the container then triggers it again.", - "deprecated": true, - "deprecationMessage": "Use 'customizations/vscode/settings' instead" - }, - "devPort": { - "type": "integer", - "description": "The port VS Code can use to connect to its backend.", - "deprecated": true, - "deprecationMessage": "Use 'customizations/vscode/devPort' instead" - } - } -} diff --git a/extensions/configuration-editing/src/configurationEditingMain.ts b/extensions/configuration-editing/src/configurationEditingMain.ts index 2a08fc7791..37bac75c41 100644 --- a/extensions/configuration-editing/src/configurationEditingMain.ts +++ b/extensions/configuration-editing/src/configurationEditingMain.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getLocation, JSONPath, parse, visit, Location } from 'jsonc-parser'; +import { getLocation, JSONPath, parse, visit } from 'jsonc-parser'; import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import { SettingsDocument } from './settingsDocumentHelper'; @@ -39,11 +39,9 @@ function registerVariableCompletions(pattern: string): vscode.Disposable { return vscode.languages.registerCompletionItemProvider({ language: 'jsonc', pattern }, { provideCompletionItems(document, position, _token) { const location = getLocation(document.getText(), document.offsetAt(position)); - if (isCompletingInsidePropertyStringValue(document, location, position)) { - let range = document.getWordRangeAtPosition(position, /\$\{[^"\}]*\}?/); - if (!range || range.start.isEqual(position) || range.end.isEqual(position) && document.getText(range).endsWith('}')) { - range = new vscode.Range(position, position); - } + if (!location.isAtPropertyKey && location.previousNode && location.previousNode.type === 'string') { + const indexOf$ = document.lineAt(position.line).text.lastIndexOf('$', position.character); + const startPosition = indexOf$ >= 0 ? new vscode.Position(position.line, indexOf$) : position; return [ { label: 'workspaceFolder', detail: localize('workspaceFolder', "The path of the folder opened in VS Code") }, @@ -63,7 +61,7 @@ function registerVariableCompletions(pattern: string): vscode.Disposable { { label: 'extensionInstallFolder', detail: localize('extensionInstallFolder', "The path where an an extension is installed."), param: 'publisher.extension' }, ].map(variable => ({ label: `\${${variable.label}}`, - range, + range: new vscode.Range(startPosition, position), insertText: variable.param ? new vscode.SnippetString(`\${${variable.label}:`).appendPlaceholder(variable.param).appendText('}') : (`\${${variable.label}}`), detail: variable.detail })); @@ -74,18 +72,6 @@ function registerVariableCompletions(pattern: string): vscode.Disposable { }); } -function isCompletingInsidePropertyStringValue(document: vscode.TextDocument, location: Location, pos: vscode.Position) { - if (location.isAtPropertyKey) { - return false; - } - const previousNode = location.previousNode; - if (previousNode && previousNode.type === 'string') { - const offset = document.offsetAt(pos); - return offset > previousNode.offset && offset < previousNode.offset + previousNode.length; - } - return false; -} - interface IExtensionsContent { recommendations: string[]; } @@ -98,8 +84,8 @@ function registerExtensionsCompletionsInExtensionsDocument(): vscode.Disposable return vscode.languages.registerCompletionItemProvider({ pattern: '**/extensions.json' }, { provideCompletionItems(document, position, _token) { const location = getLocation(document.getText(), document.offsetAt(position)); + const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position); if (location.path[0] === 'recommendations') { - const range = getReplaceRange(document, location, position); const extensionsContent = parse(document.getText()); return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], '', range, false); } @@ -112,8 +98,8 @@ function registerExtensionsCompletionsInWorkspaceConfigurationDocument(): vscode return vscode.languages.registerCompletionItemProvider({ pattern: '**/*.code-workspace' }, { provideCompletionItems(document, position, _token) { const location = getLocation(document.getText(), document.offsetAt(position)); + const range = document.getWordRangeAtPosition(position) || new vscode.Range(position, position); if (location.path[0] === 'extensions' && location.path[1] === 'recommendations') { - const range = getReplaceRange(document, location, position); const extensionsContent = parse(document.getText())['extensions']; return provideInstalledExtensionProposals(extensionsContent && extensionsContent.recommendations || [], '', range, false); } @@ -122,17 +108,6 @@ function registerExtensionsCompletionsInWorkspaceConfigurationDocument(): vscode }); } -function getReplaceRange(document: vscode.TextDocument, location: Location, position: vscode.Position) { - const node = location.previousNode; - if (node) { - const nodeStart = document.positionAt(node.offset), nodeEnd = document.positionAt(node.offset + node.length); - if (nodeStart.isBeforeOrEqual(position) && nodeEnd.isAfterOrEqual(position)) { - return new vscode.Range(nodeStart, nodeEnd); - } - } - return new vscode.Range(position, position); -} - vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', language: 'jsonc' }, { provideDocumentSymbols(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.ProviderResult { const result: vscode.SymbolInformation[] = []; @@ -205,11 +180,28 @@ function registerContextKeyCompletions(): vscode.Disposable { } } - if (!isValidLocation || !isCompletingInsidePropertyStringValue(document, location, position)) { + if (!isValidLocation) { return; } - const replacing = document.getWordRangeAtPosition(position, /[a-zA-Z.]+/) || new vscode.Range(position, position); + // for JSON everything with quotes is a word + const jsonWord = document.getWordRangeAtPosition(position); + if (!jsonWord || jsonWord.start.isEqual(position) || jsonWord.end.isEqual(position)) { + // we aren't inside a "JSON word" or on its quotes + return; + } + + let replacing: vscode.Range | undefined; + if (jsonWord.end.character - jsonWord.start.character === 2 || document.getWordRangeAtPosition(position, /\s+/)) { + // empty json word or on whitespace + replacing = new vscode.Range(position, position); + } else { + replacing = document.getWordRangeAtPosition(position, /[a-zA-Z.]+/); + } + + if (!replacing) { + return; + } const inserting = replacing.with(undefined, position); const data = await vscode.commands.executeCommand('getContextKeyInfo'); diff --git a/extensions/configuration-editing/src/extensionsProposals.ts b/extensions/configuration-editing/src/extensionsProposals.ts index 419a23e879..14f9226e85 100644 --- a/extensions/configuration-editing/src/extensionsProposals.ts +++ b/extensions/configuration-editing/src/extensionsProposals.ts @@ -8,7 +8,7 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -export async function provideInstalledExtensionProposals(existing: string[], additionalText: string, range: vscode.Range, includeBuiltinExtensions: boolean): Promise { +export function provideInstalledExtensionProposals(existing: string[], additionalText: string, range: vscode.Range, includeBuiltinExtensions: boolean): vscode.ProviderResult { if (Array.isArray(existing)) { const extensions = includeBuiltinExtensions ? vscode.extensions.all : vscode.extensions.all.filter(e => !(e.id.startsWith('vscode.') || e.id === 'Microsoft.vscode-markdown')); const knownExtensionProposals = extensions.filter(e => existing.indexOf(e.id) === -1); @@ -30,10 +30,10 @@ export async function provideInstalledExtensionProposals(existing: string[], add return [example]; } } - return []; + return undefined; } -export async function provideWorkspaceTrustExtensionProposals(existing: string[], range: vscode.Range): Promise { +export function provideWorkspaceTrustExtensionProposals(existing: string[], range: vscode.Range): vscode.ProviderResult { if (Array.isArray(existing)) { const extensions = vscode.extensions.all.filter(e => e.packageJSON.main); const extensionProposals = extensions.filter(e => existing.indexOf(e.id) === -1); @@ -56,5 +56,5 @@ export async function provideWorkspaceTrustExtensionProposals(existing: string[] } } - return []; + return undefined; } diff --git a/extensions/configuration-editing/src/settingsDocumentHelper.ts b/extensions/configuration-editing/src/settingsDocumentHelper.ts index 2a001cd382..f685a820ae 100644 --- a/extensions/configuration-editing/src/settingsDocumentHelper.ts +++ b/extensions/configuration-editing/src/settingsDocumentHelper.ts @@ -15,27 +15,32 @@ export class SettingsDocument { constructor(private document: vscode.TextDocument) { } - public async provideCompletionItems(position: vscode.Position, _token: vscode.CancellationToken): Promise { + public provideCompletionItems(position: vscode.Position, _token: vscode.CancellationToken): vscode.ProviderResult { const location = getLocation(this.document.getText(), this.document.offsetAt(position)); + const range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position); // window.title if (location.path[0] === 'window.title') { - return this.provideWindowTitleCompletionItems(location, position); + return this.provideWindowTitleCompletionItems(location, range); } // files.association if (location.path[0] === 'files.associations') { - return this.provideFilesAssociationsCompletionItems(location, position); + return this.provideFilesAssociationsCompletionItems(location, range); } // files.exclude, search.exclude if (location.path[0] === 'files.exclude' || location.path[0] === 'search.exclude') { - return this.provideExcludeCompletionItems(location, position); + return this.provideExcludeCompletionItems(location, range); } // files.defaultLanguage if (location.path[0] === 'files.defaultLanguage') { - return this.provideLanguageCompletionItems(location, position); + return this.provideLanguageCompletionItems(location, range).then(items => { + + // Add special item '${activeEditorLanguage}' + return [this.newSimpleCompletionItem(JSON.stringify('${activeEditorLanguage}'), range, localize('activeEditor', "Use the language of the currently active text editor if any")), ...items]; + }); } // settingsSync.ignoredExtensions @@ -44,7 +49,6 @@ export class SettingsDocument { try { ignoredExtensions = parse(this.document.getText())['settingsSync.ignoredExtensions']; } catch (e) {/* ignore error */ } - const range = this.getReplaceRange(location, position); return provideInstalledExtensionProposals(ignoredExtensions, '', range, true); } @@ -54,85 +58,44 @@ export class SettingsDocument { try { alreadyConfigured = Object.keys(parse(this.document.getText())['remote.extensionKind']); } catch (e) {/* ignore error */ } - const range = this.getReplaceRange(location, position); - return provideInstalledExtensionProposals(alreadyConfigured, location.previousNode ? '' : `: [\n\t"ui"\n]`, range, true); + return provideInstalledExtensionProposals(alreadyConfigured, `: [\n\t"ui"\n]`, range, true); } // remote.portsAttributes if (location.path[0] === 'remote.portsAttributes' && location.path.length === 2 && location.isAtPropertyKey) { - return this.providePortsAttributesCompletionItem(this.getReplaceRange(location, position)); + return this.providePortsAttributesCompletionItem(range); } return this.provideLanguageOverridesCompletionItems(location, position); } - private getReplaceRange(location: Location, position: vscode.Position) { - const node = location.previousNode; - if (node) { - const nodeStart = this.document.positionAt(node.offset), nodeEnd = this.document.positionAt(node.offset + node.length); - if (nodeStart.isBeforeOrEqual(position) && nodeEnd.isAfterOrEqual(position)) { - return new vscode.Range(nodeStart, nodeEnd); - } - } - return new vscode.Range(position, position); - } - - private isCompletingPropertyValue(location: Location, pos: vscode.Position) { - if (location.isAtPropertyKey) { - return false; - } - const previousNode = location.previousNode; - if (previousNode) { - const offset = this.document.offsetAt(pos); - return offset >= previousNode.offset && offset <= previousNode.offset + previousNode.length; - } - return true; - } - - private async provideWindowTitleCompletionItems(location: Location, pos: vscode.Position): Promise { + private provideWindowTitleCompletionItems(_location: Location, range: vscode.Range): vscode.ProviderResult { const completions: vscode.CompletionItem[] = []; - if (!this.isCompletingPropertyValue(location, pos)) { - return completions; - } + completions.push(this.newSimpleCompletionItem('${activeEditorShort}', range, localize('activeEditorShort', "the file name (e.g. myFile.txt)"))); + completions.push(this.newSimpleCompletionItem('${activeEditorMedium}', range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)"))); + completions.push(this.newSimpleCompletionItem('${activeEditorLong}', range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)"))); + completions.push(this.newSimpleCompletionItem('${activeFolderShort}', range, localize('activeFolderShort', "the name of the folder the file is contained in (e.g. myFileFolder)"))); + completions.push(this.newSimpleCompletionItem('${activeFolderMedium}', range, localize('activeFolderMedium', "the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)"))); + completions.push(this.newSimpleCompletionItem('${activeFolderLong}', range, localize('activeFolderLong', "the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)"))); + completions.push(this.newSimpleCompletionItem('${rootName}', range, localize('rootName', "name of the workspace (e.g. myFolder or myWorkspace)"))); + completions.push(this.newSimpleCompletionItem('${rootPath}', range, localize('rootPath', "file path of the workspace (e.g. /Users/Development/myWorkspace)"))); + completions.push(this.newSimpleCompletionItem('${folderName}', range, localize('folderName', "name of the workspace folder the file is contained in (e.g. myFolder)"))); + completions.push(this.newSimpleCompletionItem('${folderPath}', range, localize('folderPath', "file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)"))); + completions.push(this.newSimpleCompletionItem('${appName}', range, localize('appName', "e.g. VS Code"))); + completions.push(this.newSimpleCompletionItem('${remoteName}', range, localize('remoteName', "e.g. SSH"))); + completions.push(this.newSimpleCompletionItem('${dirty}', range, localize('dirty', "an indicator for when the active editor has unsaved changes"))); + completions.push(this.newSimpleCompletionItem('${separator}', range, localize('separator', "a conditional separator (' - ') that only shows when surrounded by variables with values"))); - let range = this.document.getWordRangeAtPosition(pos, /\$\{[^"\}]*\}?/); - if (!range || range.start.isEqual(pos) || range.end.isEqual(pos) && this.document.getText(range).endsWith('}')) { - range = new vscode.Range(pos, pos); - } - - const getText = (variable: string) => { - const text = '${' + variable + '}'; - return location.previousNode ? text : JSON.stringify(text); - }; - - - completions.push(this.newSimpleCompletionItem(getText('activeEditorShort'), range, localize('activeEditorShort', "the file name (e.g. myFile.txt)"))); - completions.push(this.newSimpleCompletionItem(getText('activeEditorMedium'), range, localize('activeEditorMedium', "the path of the file relative to the workspace folder (e.g. myFolder/myFileFolder/myFile.txt)"))); - completions.push(this.newSimpleCompletionItem(getText('activeEditorLong'), range, localize('activeEditorLong', "the full path of the file (e.g. /Users/Development/myFolder/myFileFolder/myFile.txt)"))); - completions.push(this.newSimpleCompletionItem(getText('activeFolderShort'), range, localize('activeFolderShort', "the name of the folder the file is contained in (e.g. myFileFolder)"))); - completions.push(this.newSimpleCompletionItem(getText('activeFolderMedium'), range, localize('activeFolderMedium', "the path of the folder the file is contained in, relative to the workspace folder (e.g. myFolder/myFileFolder)"))); - completions.push(this.newSimpleCompletionItem(getText('activeFolderLong'), range, localize('activeFolderLong', "the full path of the folder the file is contained in (e.g. /Users/Development/myFolder/myFileFolder)"))); - completions.push(this.newSimpleCompletionItem(getText('rootName'), range, localize('rootName', "name of the workspace (e.g. myFolder or myWorkspace)"))); - completions.push(this.newSimpleCompletionItem(getText('rootPath'), range, localize('rootPath', "file path of the workspace (e.g. /Users/Development/myWorkspace)"))); - completions.push(this.newSimpleCompletionItem(getText('folderName'), range, localize('folderName', "name of the workspace folder the file is contained in (e.g. myFolder)"))); - completions.push(this.newSimpleCompletionItem(getText('folderPath'), range, localize('folderPath', "file path of the workspace folder the file is contained in (e.g. /Users/Development/myFolder)"))); - completions.push(this.newSimpleCompletionItem(getText('appName'), range, localize('appName', "e.g. VS Code"))); - completions.push(this.newSimpleCompletionItem(getText('remoteName'), range, localize('remoteName', "e.g. SSH"))); - completions.push(this.newSimpleCompletionItem(getText('dirty'), range, localize('dirty', "an indicator for when the active editor has unsaved changes"))); - completions.push(this.newSimpleCompletionItem(getText('separator'), range, localize('separator', "a conditional separator (' - ') that only shows when surrounded by variables with values"))); - - return completions; + return Promise.resolve(completions); } - private async provideFilesAssociationsCompletionItems(location: Location, position: vscode.Position): Promise { + private provideFilesAssociationsCompletionItems(location: Location, range: vscode.Range): vscode.ProviderResult { const completions: vscode.CompletionItem[] = []; if (location.path.length === 2) { // Key - if (location.path[1] === '') { - const range = this.getReplaceRange(location, position); - + if (!location.isAtPropertyKey || location.path[1] === '') { completions.push(this.newSnippetCompletionItem({ label: localize('assocLabelFile', "Files with Extension"), documentation: localize('assocDescriptionFile', "Map all files matching the glob pattern in their filename to the language with the given identifier."), @@ -146,68 +109,68 @@ export class SettingsDocument { snippet: location.isAtPropertyKey ? '"/${1:path to file}/*.${2:extension}": "${3:language}"' : '{ "/${1:path to file}/*.${2:extension}": "${3:language}" }', range })); - } else if (this.isCompletingPropertyValue(location, position)) { + } else { // Value - return this.provideLanguageCompletionItemsForLanguageOverrides(this.getReplaceRange(location, position)); + return this.provideLanguageCompletionItemsForLanguageOverrides(location, range); } } - return completions; + return Promise.resolve(completions); } - private async provideExcludeCompletionItems(location: Location, position: vscode.Position): Promise { + private provideExcludeCompletionItems(location: Location, range: vscode.Range): vscode.ProviderResult { const completions: vscode.CompletionItem[] = []; // Key - if (location.path.length === 1 || (location.path.length === 2 && location.path[1] === '')) { - const range = this.getReplaceRange(location, position); - + if (location.path.length === 1) { completions.push(this.newSnippetCompletionItem({ label: localize('fileLabel', "Files by Extension"), documentation: localize('fileDescription', "Match all files of a specific file extension."), - snippet: location.path.length === 2 ? '"**/*.${1:extension}": true' : '{ "**/*.${1:extension}": true }', + snippet: location.isAtPropertyKey ? '"**/*.${1:extension}": true' : '{ "**/*.${1:extension}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: localize('filesLabel', "Files with Multiple Extensions"), documentation: localize('filesDescription', "Match all files with any of the file extensions."), - snippet: location.path.length === 2 ? '"**/*.{ext1,ext2,ext3}": true' : '{ "**/*.{ext1,ext2,ext3}": true }', + snippet: location.isAtPropertyKey ? '"**/*.{ext1,ext2,ext3}": true' : '{ "**/*.{ext1,ext2,ext3}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: localize('derivedLabel', "Files with Siblings by Name"), documentation: localize('derivedDescription', "Match files that have siblings with the same name but a different extension."), - snippet: location.path.length === 2 ? '"**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" }' : '{ "**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" } }', + snippet: location.isAtPropertyKey ? '"**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" }' : '{ "**/*.${1:source-extension}": { "when": "$(basename).${2:target-extension}" } }', range })); completions.push(this.newSnippetCompletionItem({ label: localize('topFolderLabel', "Folder by Name (Top Level)"), documentation: localize('topFolderDescription', "Match a top level folder with a specific name."), - snippet: location.path.length === 2 ? '"${1:name}": true' : '{ "${1:name}": true }', + snippet: location.isAtPropertyKey ? '"${1:name}": true' : '{ "${1:name}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: localize('topFoldersLabel', "Folders with Multiple Names (Top Level)"), documentation: localize('topFoldersDescription', "Match multiple top level folders."), - snippet: location.path.length === 2 ? '"{folder1,folder2,folder3}": true' : '{ "{folder1,folder2,folder3}": true }', + snippet: location.isAtPropertyKey ? '"{folder1,folder2,folder3}": true' : '{ "{folder1,folder2,folder3}": true }', range })); completions.push(this.newSnippetCompletionItem({ label: localize('folderLabel', "Folder by Name (Any Location)"), documentation: localize('folderDescription', "Match a folder with a specific name in any location."), - snippet: location.path.length === 2 ? '"**/${1:name}": true' : '{ "**/${1:name}": true }', + snippet: location.isAtPropertyKey ? '"**/${1:name}": true' : '{ "**/${1:name}": true }', range })); } // Value - else if (location.path.length === 2 && this.isCompletingPropertyValue(location, position)) { - const range = this.getReplaceRange(location, position); + else { + completions.push(this.newSimpleCompletionItem('false', range, localize('falseDescription', "Disable the pattern."))); + completions.push(this.newSimpleCompletionItem('true', range, localize('trueDescription', "Enable the pattern."))); + completions.push(this.newSnippetCompletionItem({ label: localize('derivedLabel', "Files with Siblings by Name"), documentation: localize('siblingsDescription', "Match files that have siblings with the same name but a different extension."), @@ -216,22 +179,15 @@ export class SettingsDocument { })); } - return completions; + return Promise.resolve(completions); } - private async provideLanguageCompletionItems(location: Location, position: vscode.Position): Promise { - if (location.path.length === 1 && this.isCompletingPropertyValue(location, position)) { - const range = this.getReplaceRange(location, position); - const languages = await vscode.languages.getLanguages(); - return [ - this.newSimpleCompletionItem(JSON.stringify('${activeEditorLanguage}'), range, localize('activeEditor', "Use the language of the currently active text editor if any")), - ...languages.map(l => this.newSimpleCompletionItem(JSON.stringify(l), range)) - ]; - } - return []; + private provideLanguageCompletionItems(_location: Location, range: vscode.Range, formatFunc: (string: string) => string = (l) => JSON.stringify(l)): Thenable { + return vscode.languages.getLanguages() + .then(languages => languages.map(l => this.newSimpleCompletionItem(formatFunc(l), range))); } - private async provideLanguageCompletionItemsForLanguageOverrides(range: vscode.Range): Promise { + private async provideLanguageCompletionItemsForLanguageOverrides(_location: Location, range: vscode.Range): Promise { const languages = await vscode.languages.getLanguages(); const completionItems = []; for (const language of languages) { @@ -244,7 +200,7 @@ export class SettingsDocument { } private async provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): Promise { - if (location.path.length === 1 && location.isAtPropertyKey && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) { + if (location.path.length === 1 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) { const startPosition = this.document.positionAt(location.previousNode.offset + 1); const endPosition = startPosition.translate(undefined, location.previousNode.value.length); const donotSuggestLanguages: string[] = []; diff --git a/extensions/configuration-editing/src/test/completion.test.ts b/extensions/configuration-editing/src/test/completion.test.ts deleted file mode 100644 index f353f317ac..0000000000 --- a/extensions/configuration-editing/src/test/completion.test.ts +++ /dev/null @@ -1,594 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import * as assert from 'assert'; -import { promises as fs } from 'fs'; -import * as path from 'path'; -import * as os from 'os'; -import 'mocha'; - - -const testFolder = fs.mkdtemp(path.join(os.tmpdir(), 'conf-editing-')); - -suite('Completions in settings.json', () => { - const testFile = 'settings.json'; - - test('window.title', async () => { - { // inserting after text - const content = [ - '{', - ' "window.title": "custom|"', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "window.title": "custom${activeEditorShort}"', - '}', - ].join('\n'); - const expected = { label: '${activeEditorShort}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { // inserting before a variable - const content = [ - '{', - ' "window.title": "|${activeEditorShort}"', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "window.title": "${folderPath}${activeEditorShort}"', - '}', - ].join('\n'); - const expected = { label: '${folderPath}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { // inserting after a variable - const content = [ - '{', - ' "window.title": "${activeEditorShort}|"', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "window.title": "${activeEditorShort}${folderPath}"', - '}', - ].join('\n'); - const expected = { label: '${folderPath}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { // replacing an variable - const content = [ - '{', - ' "window.title": "${a|ctiveEditorShort}"', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "window.title": "${activeEditorMedium}"', - '}', - ].join('\n'); - const expected = { label: '${activeEditorMedium}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { // replacing a partial variable - const content = [ - '{', - ' "window.title": "${a|"', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "window.title": "${dirty}"', - '}', - ].join('\n'); - const expected = { label: '${dirty}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { // inserting a literal - const content = [ - '{', - ' "window.title": |', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "window.title": "${activeEditorMedium}"', - '}', - ].join('\n'); - const expected = { label: '"${activeEditorMedium}"', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { // no proposals after literal - const content = [ - '{', - ' "window.title": "${activeEditorShort}" |', - '}', - ].join('\n'); - const expected = { label: '${activeEditorMedium}', notAvailable: true }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - - test('files.associations', async () => { - { - const content = [ - '{', - ' "files.associations": {', - ' |', - ' }', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.associations": {', - ' "*.${1:extension}": "${2:language}"', - ' }', - '}', - ].join('\n'); - const expected = { label: 'Files with Extension', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "files.associations": {', - ' |', - ' }', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.associations": {', - ' "/${1:path to file}/*.${2:extension}": "${3:language}"', - ' }', - '}', - ].join('\n'); - const expected = { label: 'Files with Path', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "files.associations": {', - ' "*.extension": "|bat"', - ' }', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.associations": {', - ' "*.extension": "json"', - ' }', - '}', - ].join('\n'); - const expected = { label: '"json"', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "files.associations": {', - ' "*.extension": "bat"|', - ' }', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.associations": {', - ' "*.extension": "json"', - ' }', - '}', - ].join('\n'); - const expected = { label: '"json"', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "files.associations": {', - ' "*.extension": "bat" |', - ' }', - '}', - ].join('\n'); - const expected = { label: '"json"', notAvailable: true }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - test('files.exclude', async () => { - { - const content = [ - '{', - ' "files.exclude": {', - ' |', - ' }', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.exclude": {', - ' "**/*.${1:extension}": true', - ' }', - '}', - ].join('\n'); - const expected = { label: 'Files by Extension', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "files.exclude": {', - ' "**/*.extension": |true', - ' }', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.exclude": {', - ' "**/*.extension": { "when": "$(basename).${1:extension}" }', - ' }', - '}', - ].join('\n'); - const expected = { label: 'Files with Siblings by Name', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - test('files.defaultLanguage', async () => { - { - const content = [ - '{', - ' "files.defaultLanguage": "json|"', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.defaultLanguage": "jsonc"', - '}', - ].join('\n'); - const expected = { label: '"jsonc"', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "files.defaultLanguage": |', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "files.defaultLanguage": "jsonc"', - '}', - ].join('\n'); - const expected = { label: '"jsonc"', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - test('remote.extensionKind', async () => { - { - const content = [ - '{', - '\t"remote.extensionKind": {', - '\t\t|', - '\t}', - '}', - ].join('\n'); - const expected = { label: 'vscode.npm' }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - test('remote.portsAttributes', async () => { - { - const content = [ - '{', - ' "remote.portsAttributes": {', - ' |', - ' }', - '}', - ].join('\n'); - const expected = { label: '"3000"' }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); -}); - -suite('Completions in extensions.json', () => { - const testFile = 'extensions.json'; - test('change recommendation', async () => { - { - const content = [ - '{', - ' "recommendations": [', - ' "|a.b"', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "recommendations": [', - ' "ms-vscode.js-debug"', - ' ]', - '}', - ].join('\n'); - const expected = { label: 'ms-vscode.js-debug', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - test('add recommendation', async () => { - { - const content = [ - '{', - ' "recommendations": [', - ' |', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "recommendations": [', - ' "ms-vscode.js-debug"', - ' ]', - '}', - ].join('\n'); - const expected = { label: 'ms-vscode.js-debug', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); -}); - -suite('Completions in launch.json', () => { - const testFile = 'launch.json'; - test('variable completions', async () => { - { - const content = [ - '{', - ' "version": "0.2.0",', - ' "configurations": [', - ' {', - ' "name": "Run Extension",', - ' "type": "extensionHost",', - ' "preLaunchTask": "${|defaultBuildTask}"', - ' }', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "version": "0.2.0",', - ' "configurations": [', - ' {', - ' "name": "Run Extension",', - ' "type": "extensionHost",', - ' "preLaunchTask": "${cwd}"', - ' }', - ' ]', - '}', - ].join('\n'); - const expected = { label: '${cwd}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "version": "0.2.0",', - ' "configurations": [', - ' {', - ' "name": "Run Extension",', - ' "type": "extensionHost",', - ' "preLaunchTask": "|${defaultBuildTask}"', - ' }', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "version": "0.2.0",', - ' "configurations": [', - ' {', - ' "name": "Run Extension",', - ' "type": "extensionHost",', - ' "preLaunchTask": "${cwd}${defaultBuildTask}"', - ' }', - ' ]', - '}', - ].join('\n'); - const expected = { label: '${cwd}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "version": "0.2.0",', - ' "configurations": [', - ' {', - ' "name": "Do It",', - ' "program": "${workspace|"', - ' }', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "version": "0.2.0",', - ' "configurations": [', - ' {', - ' "name": "Do It",', - ' "program": "${cwd}"', - ' }', - ' ]', - '}', - ].join('\n'); - const expected = { label: '${cwd}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); -}); - -suite('Completions in tasks.json', () => { - const testFile = 'tasks.json'; - test('variable completions', async () => { - { - const content = [ - '{', - ' "version": "0.2.0",', - ' "tasks": [', - ' {', - ' "type": "shell",', - ' "command": "${|defaultBuildTask}"', - ' }', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "version": "0.2.0",', - ' "tasks": [', - ' {', - ' "type": "shell",', - ' "command": "${cwd}"', - ' }', - ' ]', - '}', - ].join('\n'); - const expected = { label: '${cwd}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - { - const content = [ - '{', - ' "version": "0.2.0",', - ' "tasks": [', - ' {', - ' "type": "shell",', - ' "command": "${defaultBuildTask}|"', - ' }', - ' ]', - '}', - ].join('\n'); - const resultText = [ - '{', - ' "version": "0.2.0",', - ' "tasks": [', - ' {', - ' "type": "shell",', - ' "command": "${defaultBuildTask}${cwd}"', - ' }', - ' ]', - '}', - ].join('\n'); - const expected = { label: '${cwd}', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); -}); - -suite('Completions in keybindings.json', () => { - const testFile = 'keybindings.json'; - test('context key insertion', async () => { - { - const content = [ - '[', - ' {', - ' "key": "ctrl+k ctrl+,",', - ' "command": "editor.jumpToNextFold",', - ' "when": "|"', - ' }', - ']', - ].join('\n'); - const resultText = [ - '[', - ' {', - ' "key": "ctrl+k ctrl+,",', - ' "command": "editor.jumpToNextFold",', - ' "when": "resourcePath"', - ' }', - ']', - ].join('\n'); - const expected = { label: 'resourcePath', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); - - test('context key replace', async () => { - { - const content = [ - '[', - ' {', - ' "key": "ctrl+k ctrl+,",', - ' "command": "editor.jumpToNextFold",', - ' "when": "resou|rcePath"', - ' }', - ']', - ].join('\n'); - const resultText = [ - '[', - ' {', - ' "key": "ctrl+k ctrl+,",', - ' "command": "editor.jumpToNextFold",', - ' "when": "resource"', - ' }', - ']', - ].join('\n'); - const expected = { label: 'resource', resultText }; - await testCompletion(testFile, 'jsonc', content, expected); - } - }); -}); - -interface ItemDescription { - label: string; - resultText?: string; - notAvailable?: boolean; -} - -async function testCompletion(testFileName: string, languageId: string, content: string, expected: ItemDescription) { - - const offset = content.indexOf('|'); - content = content.substring(0, offset) + content.substring(offset + 1); - - const docUri = vscode.Uri.file(path.join(await testFolder, testFileName)); - await fs.writeFile(docUri.fsPath, content); - - const editor = await setTestContent(docUri, languageId, content); - const position = editor.document.positionAt(offset); - - // Executing the command `vscode.executeCompletionItemProvider` to simulate triggering completion - const actualCompletions = (await vscode.commands.executeCommand('vscode.executeCompletionItemProvider', docUri, position)) as vscode.CompletionList; - - const matches = actualCompletions.items.filter(completion => { - return completion.label === expected.label; - }); - if (expected.notAvailable) { - assert.strictEqual(matches.length, 0, `${expected.label} should not existing is results`); - } else { - assert.strictEqual(matches.length, 1, `${expected.label} should only existing once: Actual: ${actualCompletions.items.map(c => c.label).join(', ')}`); - - if (expected.resultText) { - const match = matches[0]; - if (match.range && match.insertText) { - const range = match.range instanceof vscode.Range ? match.range : match.range.replacing; - const text = typeof match.insertText === 'string' ? match.insertText : match.insertText.value; - - await editor.edit(eb => eb.replace(range, text)); - assert.strictEqual(editor.document.getText(), expected.resultText); - } else { - assert.fail(`Range or insertText missing`); - } - } - } -} - -async function setTestContent(docUri: vscode.Uri, languageId: string, content: string): Promise { - const ext = vscode.extensions.getExtension('vscode.configuration-editing')!; - await ext.activate(); - - const doc = await vscode.workspace.openTextDocument(docUri); - await vscode.languages.setTextDocumentLanguage(doc, languageId); - const editor = await vscode.window.showTextDocument(doc); - - const fullRange = new vscode.Range(new vscode.Position(0, 0), doc.positionAt(doc.getText().length)); - await editor.edit(eb => eb.replace(fullRange, content)); - return editor; - -} diff --git a/extensions/css-language-features/server/src/utils/validation.ts b/extensions/css-language-features/server/src/utils/validation.ts deleted file mode 100644 index 07d40d2ff3..0000000000 --- a/extensions/css-language-features/server/src/utils/validation.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken, Connection, Diagnostic, Disposable, DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportKind, TextDocuments } from 'vscode-languageserver'; -import { TextDocument } from 'vscode-css-languageservice'; -import { formatError, runSafeAsync } from './runner'; -import { RuntimeEnvironment } from '../cssServer'; - -export type Validator = (textDocument: TextDocument) => Promise; -export type DiagnosticsSupport = { - dispose(): void; - requestRefresh(): void; -}; - -export function registerDiagnosticsPushSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { - - const pendingValidationRequests: { [uri: string]: Disposable } = {}; - const validationDelayMs = 500; - - const disposables: Disposable[] = []; - - // The content of a text document has changed. This event is emitted - // when the text document first opened or when its content has changed. - documents.onDidChangeContent(change => { - triggerValidation(change.document); - }, undefined, disposables); - - // a document has closed: clear all diagnostics - documents.onDidClose(event => { - cleanPendingValidation(event.document); - connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] }); - }, undefined, disposables); - - function cleanPendingValidation(textDocument: TextDocument): void { - const request = pendingValidationRequests[textDocument.uri]; - if (request) { - request.dispose(); - delete pendingValidationRequests[textDocument.uri]; - } - } - - function triggerValidation(textDocument: TextDocument): void { - cleanPendingValidation(textDocument); - const request = pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(async () => { - if (request === pendingValidationRequests[textDocument.uri]) { - try { - const diagnostics = await validate(textDocument); - if (request === pendingValidationRequests[textDocument.uri]) { - connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); - } - delete pendingValidationRequests[textDocument.uri]; - } catch (e) { - connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e)); - } - } - }, validationDelayMs); - } - - return { - requestRefresh: () => { - documents.all().forEach(triggerValidation); - }, - dispose: () => { - disposables.forEach(d => d.dispose()); - disposables.length = 0; - const keys = Object.keys(pendingValidationRequests); - for (const key of keys) { - pendingValidationRequests[key].dispose(); - delete pendingValidationRequests[key]; - } - } - }; -} - -export function registerDiagnosticsPullSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { - - function newDocumentDiagnosticReport(diagnostics: Diagnostic[]): DocumentDiagnosticReport { - return { - kind: DocumentDiagnosticReportKind.Full, - items: diagnostics - }; - } - - const registration = connection.languages.diagnostics.on(async (params: DocumentDiagnosticParams, token: CancellationToken) => { - return runSafeAsync(runtime, async () => { - const document = documents.get(params.textDocument.uri); - if (document) { - return newDocumentDiagnosticReport(await validate(document)); - } - return newDocumentDiagnosticReport([]); - - }, newDocumentDiagnosticReport([]), `Error while computing diagnostics for ${params.textDocument.uri}`, token); - }); - - function requestRefresh(): void { - connection.languages.diagnostics.refresh(); - } - - return { - requestRefresh, - dispose: () => { - registration.dispose(); - } - }; - -} diff --git a/extensions/datavirtualization/src/typings/markdown-it-named-headers.d.ts b/extensions/datavirtualization/src/typings/markdown-it-named-headers.d.ts index c80a3af89d..de9b23d0df 100644 --- a/extensions/datavirtualization/src/typings/markdown-it-named-headers.d.ts +++ b/extensions/datavirtualization/src/typings/markdown-it-named-headers.d.ts @@ -1,5 +1,5 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. + * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -declare module 'markdown-it-named-headers' { } +declare module 'markdown-it-named-headers' { } \ No newline at end of file diff --git a/extensions/fsharp/cgmanifest.json b/extensions/fsharp/cgmanifest.json index 6841f8c880..c01c28355a 100644 --- a/extensions/fsharp/cgmanifest.json +++ b/extensions/fsharp/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "ionide/ionide-fsgrammar", "repositoryUrl": "https://github.com/ionide/ionide-fsgrammar", - "commitHash": "e177bd7f9d3402f70d2f1fb42c74057ed1ccf6fa" + "commitHash": "8825a76681cdc14801b5d9490372ff67ec6b9711" } }, "license": "MIT", diff --git a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json index 81c033d714..f6cbec6c36 100644 --- a/extensions/fsharp/syntaxes/fsharp.tmLanguage.json +++ b/extensions/fsharp/syntaxes/fsharp.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/ionide/ionide-fsgrammar/commit/e177bd7f9d3402f70d2f1fb42c74057ed1ccf6fa", + "version": "https://github.com/ionide/ionide-fsgrammar/commit/8825a76681cdc14801b5d9490372ff67ec6b9711", "name": "fsharp", "scopeName": "source.fsharp", "patterns": [ @@ -958,26 +958,6 @@ } ] }, - { - "name": "binding.fsharp", - "begin": "\\b(use|use\\!|and|and!)\\s*(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9\\._`\\s]+|(?<=,)\\s)*)?", - "end": "\\s*(=)", - "beginCaptures": { - "1": { - "name": "keyword.fsharp" - } - }, - "endCaptures": { - "1": { - "name": "keyword.fsharp" - } - }, - "patterns": [ - { - "include": "#common_binding_definition" - } - ] - }, { "name": "binding.fsharp", "begin": "(?<=with|and)\\s*\\b((get|set)\\s*(?=\\())(\\[[^-=]*\\]|[_[:alpha:]]([_[:alpha:]0-9\\._]+)*|``[_[:alpha:]]([_[:alpha:]0-9\\._`\\s]+|(?<=,)\\s)*)?", @@ -1295,11 +1275,11 @@ }, { "name": "constant.character.string.escape.fsharp", - "match": "\\\\(['\"\\\\abfnrtv]|([01][0-9][0-9]|2[0-4][0-9]|25[0-5])|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U00(0[0-9a-fA-F]|10)[0-9a-fA-F]{4}))" + "match": "\\\\([\\\\''ntbr]|x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|u[a-fA-F0-9]{8})" }, { - "name": "invalid.illegal.character.string.fsharp", - "match": "\\\\(([0-9]{1,3})|(x[^\\s]{0,2})|(u[^\\s]{0,4})|(U[^\\s]{0,8})|[^\\s])" + "name": "invalid.illeagal.character.string.fsharp", + "match": "\\\\(?![\\\\''ntbr]|x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|u[a-fA-F0-9]{8})." }, { "include": "#string_formatter" diff --git a/extensions/git-base/src/remoteSource.ts b/extensions/git-base/src/remoteSource.ts index 9fd4bd61a5..b4a9e51470 100644 --- a/extensions/git-base/src/remoteSource.ts +++ b/extensions/git-base/src/remoteSource.ts @@ -49,12 +49,11 @@ class RemoteSourceProviderQuickPick { @throttle private async query(): Promise { try { - this.ensureQuickPick(); - this.quickpick!.busy = true; - this.quickpick!.show(); - const remoteSources = await this.provider.getRemoteSources(this.quickpick?.value) || []; + this.ensureQuickPick(); + this.quickpick!.show(); + if (remoteSources.length === 0) { this.quickpick!.items = [{ label: localize('none found', "No remote repositories found."), @@ -70,7 +69,7 @@ class RemoteSourceProviderQuickPick { })); } } catch (err) { - this.quickpick!.items = [{ label: localize('error', "{0} Error: {1}", '$(error)', err.message), alwaysShow: true }]; + this.quickpick!.items = [{ label: localize('error', "$(error) Error: {0}", err.message), alwaysShow: true }]; console.error(err); } finally { this.quickpick!.busy = false; diff --git a/extensions/git/extension.webpack.config.js b/extensions/git/extension.webpack.config.js index de93775894..7c3b1a7408 100644 --- a/extensions/git/extension.webpack.config.js +++ b/extensions/git/extension.webpack.config.js @@ -13,7 +13,6 @@ module.exports = withDefaults({ context: __dirname, entry: { main: './src/main.ts', - ['askpass-main']: './src/askpass-main.ts', - ['git-editor-main']: './src/git-editor-main.ts' + ['askpass-main']: './src/askpass-main.ts' } }); diff --git a/extensions/git/package.json b/extensions/git/package.json index 4933625182..ff804584ab 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -8,15 +8,13 @@ "engines": { "vscode": "^1.5.0" }, - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "enabledApiProposals": [ "diffCommand", - "contribMergeEditorToolbar", "contribViewsWelcome", "scmActionButton", "scmSelectedProvider", "scmValidation", - "tabInputTextMerge", "timeline" ], "categories": [ @@ -24,8 +22,7 @@ ], "activationEvents": [ "*", - "onFileSystem:git", - "onFileSystem:git-show" + "onFileSystem:git" ], "extensionDependencies": [ "vscode.git-base" @@ -214,110 +211,82 @@ "command": "git.commit", "title": "%command.commit%", "category": "Git", - "icon": "$(check)", - "enablement": "!commitInProgress" + "icon": "$(check)" }, { "command": "git.commitStaged", "title": "%command.commitStaged%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitEmpty", "title": "%command.commitEmpty%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitStagedSigned", "title": "%command.commitStagedSigned%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitStagedAmend", "title": "%command.commitStagedAmend%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitAll", "title": "%command.commitAll%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitAllSigned", "title": "%command.commitAllSigned%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitAllAmend", "title": "%command.commitAllAmend%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitNoVerify", "title": "%command.commitNoVerify%", "category": "Git", - "icon": "$(check)", - "enablement": "!commitInProgress" + "icon": "$(check)" }, { "command": "git.commitStagedNoVerify", "title": "%command.commitStagedNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitEmptyNoVerify", "title": "%command.commitEmptyNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitStagedSignedNoVerify", "title": "%command.commitStagedSignedNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitStagedAmendNoVerify", "title": "%command.commitStagedAmendNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitAllNoVerify", "title": "%command.commitAllNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitAllSignedNoVerify", "title": "%command.commitAllSignedNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.commitAllAmendNoVerify", "title": "%command.commitAllAmendNoVerify%", - "category": "Git", - "enablement": "!commitInProgress" - }, - { - "command": "git.commitMessageAccept", - "title": "%command.commitMessageAccept%", - "icon": "$(check)", - "category": "Git" - }, - { - "command": "git.commitMessageDiscard", - "title": "%command.commitMessageDiscard%", - "icon": "$(discard)", "category": "Git" }, { @@ -328,8 +297,7 @@ { "command": "git.undoCommit", "title": "%command.undoCommit%", - "category": "Git", - "enablement": "!commitInProgress" + "category": "Git" }, { "command": "git.checkout", @@ -491,21 +459,6 @@ "title": "%command.revealInExplorer%", "category": "Git" }, - { - "command": "git.revealFileInOS.linux", - "title": "%command.revealFileInOS.linux%", - "category": "Git" - }, - { - "command": "git.revealFileInOS.mac", - "title": "%command.revealFileInOS.mac%", - "category": "Git" - }, - { - "command": "git.revealFileInOS.windows", - "title": "%command.revealFileInOS.windows%", - "category": "Git" - }, { "command": "git.stashIncludeUntracked", "title": "%command.stashIncludeUntracked%", @@ -596,12 +549,6 @@ "command": "git.api.getRemoteSources", "title": "%command.api.getRemoteSources%", "category": "Git API" - }, - { - "command": "git.acceptMerge", - "title": "%command.git.acceptMerge%", - "category": "Git", - "enablement": "isMergeEditor && mergeEditorResultUri in git.mergeChanges" } ], "keybindings": [ @@ -810,30 +757,10 @@ "command": "git.restoreCommitTemplate", "when": "false" }, - { - "command": "git.commitMessageAccept", - "when": "false" - }, - { - "command": "git.commitMessageDiscard", - "when": "false" - }, { "command": "git.revealInExplorer", "when": "false" }, - { - "command": "git.revealFileInOS.linux", - "when": "false" - }, - { - "command": "git.revealFileInOS.mac", - "when": "false" - }, - { - "command": "git.revealFileInOS.windows", - "when": "false" - }, { "command": "git.undoCommit", "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0" @@ -1284,22 +1211,7 @@ { "command": "git.revealInExplorer", "when": "scmProvider == git && scmResourceGroup == merge", - "group": "2_view@1" - }, - { - "command": "git.revealFileInOS.linux", - "when": "scmProvider == git && scmResourceGroup == merge && remoteName == '' && isLinux", - "group": "2_view@2" - }, - { - "command": "git.revealFileInOS.mac", - "when": "scmProvider == git && scmResourceGroup == merge && remoteName == '' && isMac", - "group": "2_view@2" - }, - { - "command": "git.revealFileInOS.windows", - "when": "scmProvider == git && scmResourceGroup == merge && remoteName == '' && isWindows", - "group": "2_view@2" + "group": "2_view" }, { "command": "git.openFile2", @@ -1339,22 +1251,7 @@ { "command": "git.revealInExplorer", "when": "scmProvider == git && scmResourceGroup == index", - "group": "2_view@1" - }, - { - "command": "git.revealFileInOS.linux", - "when": "scmProvider == git && scmResourceGroup == index && remoteName == '' && isLinux", - "group": "2_view@2" - }, - { - "command": "git.revealFileInOS.mac", - "when": "scmProvider == git && scmResourceGroup == index && remoteName == '' && isMac", - "group": "2_view@2" - }, - { - "command": "git.revealFileInOS.windows", - "when": "scmProvider == git && scmResourceGroup == index && remoteName == '' && isWindows", - "group": "2_view@2" + "group": "2_view" }, { "command": "git.openFile2", @@ -1419,22 +1316,7 @@ { "command": "git.revealInExplorer", "when": "scmProvider == git && scmResourceGroup == workingTree", - "group": "2_view@1" - }, - { - "command": "git.revealFileInOS.linux", - "when": "scmProvider == git && scmResourceGroup == workingTree && remoteName == '' && isLinux", - "group": "2_view@2" - }, - { - "command": "git.revealFileInOS.mac", - "when": "scmProvider == git && scmResourceGroup == workingTree && remoteName == '' && isMac", - "group": "2_view@2" - }, - { - "command": "git.revealFileInOS.windows", - "when": "scmProvider == git && scmResourceGroup == workingTree && remoteName == '' && isWindows", - "group": "2_view@2" + "group": "2_view" }, { "command": "git.openChange", @@ -1501,17 +1383,7 @@ { "command": "git.openChange", "group": "navigation", - "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0 && !isInDiffEditor && !isMergeEditor && resourceScheme == file && scmActiveResourceHasChanges" - }, - { - "command": "git.commitMessageAccept", - "group": "navigation", - "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0 && editorLangId == git-commit && commitInProgress" - }, - { - "command": "git.commitMessageDiscard", - "group": "navigation", - "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0 && editorLangId == git-commit && commitInProgress" + "when": "config.git.enabled && !git.missing && gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme == file && scmActiveResourceHasChanges" }, { "command": "git.stageSelectedRanges", @@ -1546,12 +1418,6 @@ "when": "isInDiffRightEditor && !isInEmbeddedDiffEditor && config.git.enabled && !git.missing && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme =~ /^git$|^file$/" } ], - "merge/toolbar": [ - { - "command": "git.acceptMerge", - "when": "isMergeEditor && mergeEditorBaseUri =~ /^(git|file):/ && mergeEditorResultUri in git.mergeChanges" - } - ], "scm/change/title": [ { "command": "git.stageChange", @@ -1911,37 +1777,6 @@ "markdownDescription": "%config.autofetchPeriod%", "default": 180 }, - "git.branchPrefix": { - "type": "string", - "description": "%config.branchPrefix%", - "default": "", - "scope": "resource" - }, - "git.branchProtection": { - "type": "array", - "markdownDescription": "%config.branchProtection%", - "items": { - "type": "string" - }, - "default": [], - "scope": "resource" - }, - "git.branchProtectionPrompt": { - "type": "string", - "description": "%config.branchProtectionPrompt%", - "enum": [ - "alwaysCommit", - "alwaysCommitToNewBranch", - "alwaysPrompt" - ], - "enumDescriptions": [ - "%config.branchProtectionPrompt.alwaysCommit%", - "%config.branchProtectionPrompt.alwaysCommitToNewBranch%", - "%config.branchProtectionPrompt.alwaysPrompt%" - ], - "default": "alwaysPrompt", - "scope": "resource" - }, "git.branchValidationRegex": { "type": "string", "description": "%config.branchValidationRegex%", @@ -1952,38 +1787,6 @@ "description": "%config.branchWhitespaceChar%", "default": "-" }, - "git.branchRandomName.enable": { - "type": "boolean", - "description": "%config.branchRandomNameEnable%", - "default": false, - "scope": "resource" - }, - "git.branchRandomName.dictionary": { - "type": "array", - "markdownDescription": "%config.branchRandomNameDictionary%", - "items": { - "type": "string", - "enum": [ - "adjectives", - "animals", - "colors", - "numbers" - ], - "enumDescriptions": [ - "%config.branchRandomNameDictionary.adjectives%", - "%config.branchRandomNameDictionary.animals%", - "%config.branchRandomNameDictionary.colors%", - "%config.branchRandomNameDictionary.numbers%" - ] - }, - "minItems": 1, - "maxItems": 5, - "default": [ - "adjectives", - "animals" - ], - "scope": "resource" - }, "git.confirmSync": { "type": "boolean", "description": "%config.confirmSync%", @@ -2062,17 +1865,6 @@ "scope": "machine", "description": "%config.defaultCloneDirectory%" }, - "git.useEditorAsCommitInput": { - "type": "boolean", - "description": "%config.useEditorAsCommitInput%", - "default": true - }, - "git.verboseCommit": { - "type": "boolean", - "scope": "resource", - "markdownDescription": "%config.verboseCommit%", - "default": false - }, "git.enableSmartCommit": { "type": "boolean", "scope": "resource", @@ -2381,8 +2173,7 @@ "git.requireGitUserConfig": { "type": "boolean", "description": "%config.requireGitUserConfig%", - "default": true, - "scope": "resource" + "default": true }, "git.showCommitInput": { "type": "boolean", @@ -2392,14 +2183,10 @@ }, "git.terminalAuthentication": { "type": "boolean", + "scope": "resource", "default": true, "description": "%config.terminalAuthentication%" }, - "git.terminalGitEditor": { - "type": "boolean", - "default": false, - "description": "%config.terminalGitEditor%" - }, "git.useCommitInputAsStashMessage": { "type": "boolean", "scope": "resource", @@ -2440,29 +2227,20 @@ "description": "%config.timeline.showUncommitted%", "scope": "window" }, - "git.showActionButton": { - "type": "object", - "additionalProperties": false, - "description": "%config.showActionButton%", - "properties": { - "commit": { - "type": "boolean", - "description": "%config.showActionButton.commit%" - }, - "publish": { - "type": "boolean", - "description": "%config.showActionButton.publish%" - }, - "sync": { - "type": "boolean", - "description": "%config.showActionButton.sync%" - } - }, - "default": { - "commit": true, - "publish": true, - "sync": true - }, + "git.showUnpublishedCommitsButton": { + "type": "string", + "enum": [ + "always", + "whenEmpty", + "never" + ], + "enumDescriptions": [ + "%config.showUnpublishedCommitsButton.always%", + "%config.showUnpublishedCommitsButton.whenEmpty%", + "%config.showUnpublishedCommitsButton.never%" + ], + "default": "whenEmpty", + "description": "%config.showUnpublishedCommitsButton%", "scope": "resource" }, "git.statusLimit": { @@ -2471,6 +2249,19 @@ "default": 10000, "description": "%config.statusLimit%" }, + "git.experimental.installGuide": { + "type": "string", + "enum": [ + "default", + "download" + ], + "tags": [ + "experimental" + ], + "scope": "machine", + "description": "%config.experimental.installGuide%", + "default": "default" + }, "git.repositoryScanIgnoredFolders": { "type": "array", "items": { @@ -2494,37 +2285,8 @@ "type": "string" }, "default": [], + "scope": "resource", "markdownDescription": "%config.commandsToLog%" - }, - "git.logLevel": { - "type": "string", - "default": "Info", - "enum": [ - "Trace", - "Debug", - "Info", - "Warning", - "Error", - "Critical", - "Off" - ], - "enumDescriptions": [ - "%config.logLevel.trace%", - "%config.logLevel.debug%", - "%config.logLevel.info%", - "%config.logLevel.warn%", - "%config.logLevel.error%", - "%config.logLevel.critical%", - "%config.logLevel.off%" - ], - "markdownDescription": "%config.logLevel%", - "scope": "window" - }, - "git.mergeEditor": { - "type": "boolean", - "default": true, - "markdownDescription": "%config.mergeEditor%", - "scope": "window" } } }, @@ -2535,7 +2297,7 @@ "defaults": { "light": "#587c0c", "dark": "#81b88b", - "highContrast": "#a1e3ad", + "highContrast": "#1b5225", "highContrastLight": "#374e06" } }, @@ -2647,51 +2409,56 @@ "contents": "%view.workbench.scm.disabled%", "when": "!config.git.enabled" }, + { + "view": "scm", + "contents": "%view.workbench.scm.missing.guide%", + "when": "config.git.enabled && git.missing && config.git.experimental.installGuide == download" + }, + { + "view": "scm", + "contents": "%view.workbench.scm.missing.guide.mac%", + "when": "config.git.enabled && git.missing && config.git.experimental.installGuide == download && isMac" + }, + { + "view": "scm", + "contents": "%view.workbench.scm.missing.guide.windows%", + "when": "config.git.enabled && git.missing && config.git.experimental.installGuide == download && isWindows" + }, + { + "view": "scm", + "contents": "%view.workbench.scm.missing.guide.linux%", + "when": "config.git.enabled && git.missing && config.git.experimental.installGuide == download && isLinux" + }, { "view": "scm", "contents": "%view.workbench.scm.missing%", - "when": "config.git.enabled && git.missing" - }, - { - "view": "scm", - "contents": "%view.workbench.scm.missing.mac%", - "when": "config.git.enabled && git.missing && isMac" - }, - { - "view": "scm", - "contents": "%view.workbench.scm.missing.windows%", - "when": "config.git.enabled && git.missing && isWindows" - }, - { - "view": "scm", - "contents": "%view.workbench.scm.missing.linux%", - "when": "config.git.enabled && git.missing && isLinux" + "when": "config.git.enabled && git.missing && config.git.experimental.installGuide == default" }, { "view": "scm", "contents": "%view.workbench.scm.empty%", - "when": "config.git.enabled && !git.missing && workbenchState == empty", + "when": "config.git.enabled && workbenchState == empty", "enablement": "git.state == initialized", "group": "2_open@1" }, { "view": "scm", "contents": "%view.workbench.scm.folder%", - "when": "config.git.enabled && !git.missing && workbenchState == folder", + "when": "config.git.enabled && workbenchState == folder", "enablement": "git.state == initialized", "group": "5_scm@1" }, { "view": "scm", "contents": "%view.workbench.scm.workspace%", - "when": "config.git.enabled && !git.missing && workbenchState == workspace && workspaceFolderCount != 0", + "when": "config.git.enabled && workbenchState == workspace && workspaceFolderCount != 0", "enablement": "git.state == initialized", "group": "5_scm@1" }, { "view": "scm", "contents": "%view.workbench.scm.emptyWorkspace%", - "when": "config.git.enabled && !git.missing && workbenchState == workspace && workspaceFolderCount == 0", + "when": "config.git.enabled && workbenchState == workspace && workspaceFolderCount == 0", "enablement": "git.state == initialized", "group": "2_open@1" }, @@ -2712,13 +2479,11 @@ ] }, "dependencies": { - "@joaomoreno/unique-names-generator": "5.0.0", - "@vscode/extension-telemetry": "0.6.2", + "@vscode/extension-telemetry": "0.4.10", "@vscode/iconv-lite-umd": "0.7.0", "byline": "^5.0.0", "file-type": "16.5.4", "jschardet": "3.0.0", - "picomatch": "2.3.1", "vscode-nls": "^4.0.0", "vscode-uri": "^2.0.0", "which": "^1.3.0" @@ -2727,7 +2492,6 @@ "@types/byline": "4.2.31", "@types/mocha": "^9.1.1", "@types/node": "16.x", - "@types/picomatch": "2.3.0", "@types/which": "^1.0.28" }, "repository": { diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 6710c283c4..0cfc6c6c34 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -46,8 +46,6 @@ "command.commitAllNoVerify": "Commit All (No Verify)", "command.commitAllSignedNoVerify": "Commit All (Signed Off, No Verify)", "command.commitAllAmendNoVerify": "Commit All (Amend, No Verify)", - "command.commitMessageAccept": "Accept Commit Message", - "command.commitMessageDiscard": "Discard Commit Message", "command.restoreCommitTemplate": "Restore Commit Template", "command.undoCommit": "Undo Last Commit", "command.checkout": "Checkout to...", @@ -82,9 +80,6 @@ "command.showOutput": "Show Git Output", "command.ignore": "Add to .gitignore", "command.revealInExplorer": "Reveal in Explorer View", - "command.revealFileInOS.linux": "Open Containing Folder", - "command.revealFileInOS.mac": "Reveal in Finder", - "command.revealFileInOS.windows": "Reveal in File Explorer", "command.rebaseAbort": "Abort Rebase", "command.stashIncludeUntracked": "Stash (Include Untracked)", "command.stash": "Stash", @@ -102,7 +97,6 @@ "command.api.getRepositories": "Get Repositories", "command.api.getRepositoryState": "Get Repository State", "command.api.getRemoteSources": "Get Remote Sources", - "command.git.acceptMerge": "Accept Merge", "config.enabled": "Whether git is enabled.", "config.path": "Path and filename of the git executable, e.g. `C:\\Program Files\\Git\\bin\\git.exe` (Windows). This can also be an array of string values containing multiple paths to look up.", "config.autoRepositoryDetection": "Configures when repositories should be automatically detected.", @@ -122,28 +116,14 @@ "config.checkoutType.local": "Local branches", "config.checkoutType.tags": "Tags", "config.checkoutType.remote": "Remote branches", - "config.branchPrefix": "Prefix used when creating a new branch.", - "config.branchProtection": "List of protected branches. By default, a prompt is shown before changes are committed to a protected branch. The prompt can be controlled using the `#git.branchProtectionPrompt#` setting.", - "config.branchProtectionPrompt": "Controls whether a prompt is being before changes are committed to a protected branch.", - "config.branchProtectionPrompt.alwaysCommit": "Always commit changes to the protected branch.", - "config.branchProtectionPrompt.alwaysCommitToNewBranch": "Always commit changes to a new branch.", - "config.branchProtectionPrompt.alwaysPrompt": "Always prompt before changes are committed to a protected branch.", - "config.branchRandomNameDictionary": "List of dictionaries used for the randomly generated branch name. Each value represents the dictionary used to generate the segment of the branch name. Supported dictionaries: `adjectives`, `animals`, `colors` and `numbers`.", - "config.branchRandomNameDictionary.adjectives": "A random adjective", - "config.branchRandomNameDictionary.animals": "A random animal name", - "config.branchRandomNameDictionary.colors": "A random color name", - "config.branchRandomNameDictionary.numbers": "A random number between 100 and 999", - "config.branchRandomNameEnable": "Controls whether a random name is generated when creating a new branch.", "config.branchValidationRegex": "A regular expression to validate new branch names.", - "config.branchWhitespaceChar": "The character to replace whitespace in new branch names, and to separate segments of a randomly generated branch name.", + "config.branchWhitespaceChar": "The character to replace whitespace in new branch names.", "config.ignoreLegacyWarning": "Ignores the legacy Git warning.", "config.ignoreMissingGitWarning": "Ignores the warning when Git is missing.", "config.ignoreWindowsGit27Warning": "Ignores the warning when Git 2.25 - 2.26 is installed on Windows.", "config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository.", "config.ignoreRebaseWarning": "Ignores the warning when it looks like the branch might have been rebased when pulling.", "config.defaultCloneDirectory": "The default location to clone a git repository.", - "config.useEditorAsCommitInput": "Controls whether a full text editor will be used to author commit messages, whenever no message is provided in the commit input box.", - "config.verboseCommit": "Enable verbose output when `#git.useEditorAsCommitInput#` is enabled.", "config.enableSmartCommit": "Commit all changes when there are no staged changes.", "config.smartCommitChanges": "Control which changes are automatically staged by Smart Commit.", "config.smartCommitChanges.all": "Automatically stage all changes.", @@ -213,39 +193,22 @@ "config.untrackedChanges.hidden": "Untracked changes are hidden and excluded from several actions.", "config.requireGitUserConfig": "Controls whether to require explicit Git user configuration or allow Git to guess if missing.", "config.showCommitInput": "Controls whether to show the commit input in the Git source control panel.", - "config.terminalAuthentication": "Controls whether to enable VS Code to be the authentication handler for git processes spawned in the integrated terminal. Note: terminals need to be restarted to pick up a change in this setting.", - "config.terminalGitEditor": "Controls whether to enable VS Code to be git editor for git processes spawned in the integrated terminal. Note: terminals need to be restarted to pick up a change in this setting.", + "config.terminalAuthentication": "Controls whether to enable Azure Data Studio to be the authentication handler for git processes spawned in the integrated terminal. Note: terminals need to be restarted to pick up a change in this setting.", "config.timeline.showAuthor": "Controls whether to show the commit author in the Timeline view.", "config.timeline.showUncommitted": "Controls whether to show uncommitted changes in the Timeline view.", "config.timeline.date": "Controls which date to use for items in the Timeline view.", "config.timeline.date.committed": "Use the committed date", "config.timeline.date.authored": "Use the authored date", "config.useCommitInputAsStashMessage": "Controls whether to use the message from the commit input box as the default stash message.", - "config.showActionButton": "Controls whether an action button is shown in the Source Control view.", - "config.showActionButton.commit": "Show an action button to commit changes when the local branch has modified files ready to be committed.", - "config.showActionButton.publish": "Show an action button to publish the local branch when it does not have a tracking remote branch.", - "config.showActionButton.sync": "Show an action button to synchronize changes when the local branch is either ahead or behind the remote branch.", + "config.showUnpublishedCommitsButton": "Controls whether to show an action button to sync or publish, if there are unpublished commits.", + "config.showUnpublishedCommitsButton.always": "Always shows the action button, if there are unpublished commits.", + "config.showUnpublishedCommitsButton.whenEmpty": "Only shows the action button if there are no other changes and there are unpublished commits.", + "config.showUnpublishedCommitsButton.never": "Never shows the action button.", "config.statusLimit": "Controls how to limit the number of changes that can be parsed from Git status command. Can be set to 0 for no limit.", "config.experimental.installGuide": "Experimental improvements for the git setup flow.", "config.repositoryScanIgnoredFolders": "List of folders that are ignored while scanning for Git repositories when `#git.autoRepositoryDetection#` is set to `true` or `subFolders`.", "config.repositoryScanMaxDepth": "Controls the depth used when scanning workspace folders for Git repositories when `#git.autoRepositoryDetection#` is set to `true` or `subFolders`. Can be set to `-1` for no limit.", "config.useIntegratedAskPass": "Controls whether GIT_ASKPASS should be overwritten to use the integrated version.", - "config.logLevel": { - "message": "Specifies how much information (if any) to log to the [git output](command:git.showOutput).", - "comment": [ - "{Locked='](command:git.showOutput'}", - "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" - ] - }, - "config.logLevel.trace": "Log all information", - "config.logLevel.debug": "Log only debug, information, warning, error, and critical information", - "config.logLevel.info": "Log only information, warning, error, and critical information", - "config.logLevel.warn": "Log only warning, error, and critical information", - "config.logLevel.error": "Log only error, and critical information", - "config.logLevel.critical": "Log only critical information", - "config.logLevel.off": "Log nothing", - "config.mergeEditor": "Open the merge editor for files that are currently under conflict.", "submenu.explorer": "Git", "submenu.commit": "Commit", "submenu.commit.amend": "Amend", @@ -266,7 +229,15 @@ "colors.ignored": "Color for ignored resources.", "colors.conflict": "Color for resources with conflicts.", "colors.submodule": "Color for submodule resources.", - "view.workbench.scm.missing.windows": { + "view.workbench.scm.missing": { + "message": "A valid git installation was not detected, more details can be found in the [git output](command:git.showOutput).\nPlease [install git](https://git-scm.com/), or learn more about how to use git and source control in Azure Data Studio in [our docs](https://aka.ms/vscode-scm).\nIf you're using a different version control system, you can [search the Marketplace](command:workbench.extensions.search?%22%40category%3A%5C%22scm%20providers%5C%22%22) for additional extensions.", + "comment": [ + "{Locked='](command:git.showOutput'}", + "Do not translate the 'command:*' part inside of the '(..)'. It is an internal command syntax for Azure Data Studio", + "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links" + ] + }, + "view.workbench.scm.missing.guide.windows": { "message": "[Download Git for Windows](https://git-scm.com/download/win)\nAfter installing, please [reload](command:workbench.action.reloadWindow) (or [troubleshoot](command:git.showOutput)). Additional source control providers can be installed [from the Marketplace](command:workbench.extensions.search?%22%40category%3A%5C%22scm%20providers%5C%22%22).", "comment": [ "{Locked='](command:workbench.action.reloadWindow'}", @@ -274,7 +245,7 @@ "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links" ] }, - "view.workbench.scm.missing.mac": { + "view.workbench.scm.missing.guide.mac": { "message": "[Download Git for macOS](https://git-scm.com/download/mac)\nAfter installing, please [reload](command:workbench.action.reloadWindow) (or [troubleshoot](command:git.showOutput)). Additional source control providers can be installed [from the Marketplace](command:workbench.extensions.search?%22%40category%3A%5C%22scm%20providers%5C%22%22).", "comment": [ "{Locked='](command:workbench.action.reloadWindow'}", @@ -282,7 +253,7 @@ "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links" ] }, - "view.workbench.scm.missing.linux": { + "view.workbench.scm.missing.guide.linux": { "message": "Source control depends on Git being installed.\n[Download Git for Linux](https://git-scm.com/download/linux)\nAfter installing, please [reload](command:workbench.action.reloadWindow) (or [troubleshoot](command:git.showOutput)). Additional source control providers can be installed [from the Marketplace](command:workbench.extensions.search?%22%40category%3A%5C%22scm%20providers%5C%22%22).", "comment": [ "{Locked='](command:workbench.action.reloadWindow'}", @@ -290,7 +261,7 @@ "Please make sure there is no space between the right bracket and left parenthesis: ]( this is an internal syntax for links" ] }, - "view.workbench.scm.missing": "Install Git, a popular source control system, to track code changes and collaborate with others. Learn more in our [Git guides](https://aka.ms/vscode-scm).", + "view.workbench.scm.missing.guide": "Install Git, a popular source control system, to track code changes and collaborate with others. Learn more in our [Git guides](https://aka.ms/vscode-scm).", "view.workbench.scm.disabled": { "message": "If you would like to use git features, please enable git in your [settings](command:workbench.action.openSettings?%5B%22git.enabled%22%5D).\nTo learn more about how to use git and source control in VS Code [read our docs](https://aka.ms/vscode-scm).", "comment": [ diff --git a/extensions/git/src/actionButton.ts b/extensions/git/src/actionButton.ts index 30b6427232..4516b11ef6 100644 --- a/extensions/git/src/actionButton.ts +++ b/extensions/git/src/actionButton.ts @@ -3,23 +3,18 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Disposable, Event, EventEmitter, SourceControlActionButton, Uri, workspace } from 'vscode'; import * as nls from 'vscode-nls'; -import { Command, Disposable, Event, EventEmitter, SourceControlActionButton, Uri, workspace } from 'vscode'; -import { ApiRepository } from './api/api1'; -import { Branch, Status } from './api/git'; -import { IPostCommitCommandsProviderRegistry } from './postCommitCommands'; import { Repository, Operation } from './repository'; import { dispose } from './util'; +import { Branch } from './api/git'; const localize = nls.loadMessageBundle(); interface ActionButtonState { readonly HEAD: Branch | undefined; - readonly isCommitInProgress: boolean; - readonly isMergeInProgress: boolean; - readonly isRebaseInProgress: boolean; - readonly isSyncInProgress: boolean; - readonly repositoryHasChangesToCommit: boolean; + readonly isSyncRunning: boolean; + readonly repositoryHasNoChanges: boolean; } export class ActionButtonCommand { @@ -37,263 +32,81 @@ export class ActionButtonCommand { private disposables: Disposable[] = []; - constructor( - readonly repository: Repository, - readonly postCommitCommandsProviderRegistry: IPostCommitCommandsProviderRegistry) { - this._state = { - HEAD: undefined, - isCommitInProgress: false, - isMergeInProgress: false, - isRebaseInProgress: false, - isSyncInProgress: false, - repositoryHasChangesToCommit: false - }; + constructor(readonly repository: Repository) { + this._state = { HEAD: undefined, isSyncRunning: false, repositoryHasNoChanges: false }; repository.onDidRunGitStatus(this.onDidRunGitStatus, this, this.disposables); repository.onDidChangeOperations(this.onDidChangeOperations, this, this.disposables); - - this.disposables.push(postCommitCommandsProviderRegistry.onDidChangePostCommitCommandsProviders(() => this._onDidChange.fire())); - - const root = Uri.file(repository.root); - this.disposables.push(workspace.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('git.enableSmartCommit', root) || - e.affectsConfiguration('git.smartCommitChanges', root) || - e.affectsConfiguration('git.suggestSmartCommit', root)) { - this.onDidChangeSmartCommitSettings(); - } - - if (e.affectsConfiguration('git.branchProtection', root) || - e.affectsConfiguration('git.branchProtectionPrompt', root) || - e.affectsConfiguration('git.postCommitCommand', root) || - e.affectsConfiguration('git.showActionButton', root)) { - this._onDidChange.fire(); - } - })); } get button(): SourceControlActionButton | undefined { - if (!this.state.HEAD) { return undefined; } + if (!this.state.HEAD || !this.state.HEAD.name || !this.state.HEAD.commit) { return undefined; } + + const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); + const showActionButton = config.get('showUnpublishedCommitsButton', 'whenEmpty'); + const postCommitCommand = config.get('postCommitCommand'); + const noPostCommitCommand = postCommitCommand !== 'sync' && postCommitCommand !== 'push'; let actionButton: SourceControlActionButton | undefined; + if (showActionButton === 'always' || (showActionButton === 'whenEmpty' && this.state.repositoryHasNoChanges && noPostCommitCommand)) { + if (this.state.HEAD.upstream) { + if (this.state.HEAD.ahead) { + const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); + const rebaseWhenSync = config.get('rebaseWhenSync'); - if (this.state.repositoryHasChangesToCommit) { - // Commit Changes (enabled) - actionButton = this.getCommitActionButton(); - } + const ahead = `${this.state.HEAD.ahead}$(arrow-up)`; + const behind = this.state.HEAD.behind ? `${this.state.HEAD.behind}$(arrow-down) ` : ''; + const icon = this.state.isSyncRunning ? '$(sync~spin)' : '$(sync)'; - // Commit Changes (enabled) -> Publish Branch -> Sync Changes -> Commit Changes (disabled) - return actionButton ?? this.getPublishBranchActionButton() ?? this.getSyncChangesActionButton() ?? this.getCommitActionButton(); - } - - private getCommitActionButton(): SourceControlActionButton | undefined { - const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); - const showActionButton = config.get<{ commit: boolean }>('showActionButton', { commit: true }); - - // The button is disabled - if (!showActionButton.commit) { return undefined; } - - return { - command: this.getCommitActionButtonPrimaryCommand(), - secondaryCommands: this.getCommitActionButtonSecondaryCommands(), - enabled: (this.state.repositoryHasChangesToCommit || this.state.isRebaseInProgress) && !this.state.isCommitInProgress && !this.state.isMergeInProgress - }; - } - - private getCommitActionButtonPrimaryCommand(): Command { - // Rebase Continue - if (this.state.isRebaseInProgress) { - return { - command: 'git.commit', - title: localize('scm button continue title', "{0} Continue", '$(check)'), - tooltip: this.state.isCommitInProgress ? localize('scm button continuing tooltip', "Continuing Rebase...") : localize('scm button continue tooltip', "Continue Rebase"), - arguments: [this.repository.sourceControl, ''] - }; - } - - // Commit - const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); - const postCommitCommand = config.get('postCommitCommand'); - - // Branch protection - const isBranchProtected = this.repository.isBranchProtected(); - const branchProtectionPrompt = config.get<'alwaysCommit' | 'alwaysCommitToNewBranch' | 'alwaysPrompt'>('branchProtectionPrompt')!; - const alwaysPrompt = isBranchProtected && branchProtectionPrompt === 'alwaysPrompt'; - const alwaysCommitToNewBranch = isBranchProtected && branchProtectionPrompt === 'alwaysCommitToNewBranch'; - - // Icon - const icon = alwaysPrompt ? '$(lock)' : alwaysCommitToNewBranch ? '$(git-branch)' : undefined; - - let commandArg = ''; - let title = localize('scm button commit title', "{0} Commit", icon ?? '$(check)'); - let tooltip = this.state.isCommitInProgress ? localize('scm button committing tooltip', "Committing Changes...") : localize('scm button commit tooltip', "Commit Changes"); - - // Title, tooltip - switch (postCommitCommand) { - case 'push': { - commandArg = 'git.push'; - title = localize('scm button commit and push title', "{0} Commit & Push", icon ?? '$(arrow-up)'); - if (alwaysCommitToNewBranch) { - tooltip = this.state.isCommitInProgress ? - localize('scm button committing to new branch and pushing tooltip', "Committing to New Branch & Pushing Changes...") : - localize('scm button commit to new branch and push tooltip', "Commit to New Branch & Push Changes"); - } else { - tooltip = this.state.isCommitInProgress ? - localize('scm button committing and pushing tooltip', "Committing & Pushing Changes...") : - localize('scm button commit and push tooltip', "Commit & Push Changes"); - } - break; - } - case 'sync': { - commandArg = 'git.sync'; - title = localize('scm button commit and sync title', "{0} Commit & Sync", icon ?? '$(sync)'); - if (alwaysCommitToNewBranch) { - tooltip = this.state.isCommitInProgress ? - localize('scm button committing to new branch and synching tooltip', "Committing to New Branch & Synching Changes...") : - localize('scm button commit to new branch and sync tooltip', "Commit to New Branch & Sync Changes"); - } else { - tooltip = this.state.isCommitInProgress ? - localize('scm button committing and synching tooltip', "Committing & Synching Changes...") : - localize('scm button commit and sync tooltip', "Commit & Sync Changes"); - } - break; - } - default: { - if (alwaysCommitToNewBranch) { - tooltip = this.state.isCommitInProgress ? - localize('scm button committing to new branch tooltip', "Committing Changes to New Branch...") : - localize('scm button commit to new branch tooltip', "Commit Changes to New Branch"); - } - break; - } - } - - return { command: 'git.commit', title, tooltip, arguments: [this.repository.sourceControl, commandArg] }; - } - - private getCommitActionButtonSecondaryCommands(): Command[][] { - const commandGroups: Command[][] = []; - - if (!this.state.isRebaseInProgress) { - for (const provider of this.postCommitCommandsProviderRegistry.getPostCommitCommandsProviders()) { - const commands = provider.getCommands(new ApiRepository(this.repository)); - commandGroups.push((commands ?? []).map(c => { - return { - command: 'git.commit', - title: c.title, - arguments: [this.repository.sourceControl, c.command] + actionButton = { + command: { + command: this.state.isSyncRunning ? '' : rebaseWhenSync ? 'git.syncRebase' : 'git.sync', + title: localize('scm button sync title', "{0} {1}{2}", icon, behind, ahead), + tooltip: this.state.isSyncRunning ? + localize('syncing changes', "Synchronizing Changes...") + : this.repository.syncTooltip, + arguments: [this.repository.sourceControl], + }, + description: localize('scm button sync description', "{0} Sync Changes {1}{2}", icon, behind, ahead) }; - })); - } - - if (commandGroups.length > 0) { - commandGroups[0].splice(0, 0, { command: 'git.commit', title: localize('scm secondary button commit', "Commit") }); + } + } else { + actionButton = { + command: { + command: this.state.isSyncRunning ? '' : 'git.publish', + title: localize('scm button publish title', "$(cloud-upload) Publish Branch"), + tooltip: this.state.isSyncRunning ? + localize('scm button publish branch running', "Publishing Branch...") : + localize('scm button publish branch', "Publish Branch"), + arguments: [this.repository.sourceControl], + } + }; } } - return commandGroups; - } - - private getPublishBranchActionButton(): SourceControlActionButton | undefined { - const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); - const showActionButton = config.get<{ publish: boolean }>('showActionButton', { publish: true }); - - // Branch does have an upstream, commit/merge/rebase is in progress, or the button is disabled - if (this.state.HEAD?.upstream || this.state.isCommitInProgress || this.state.isMergeInProgress || this.state.isRebaseInProgress || !showActionButton.publish) { return undefined; } - - return { - command: { - command: 'git.publish', - title: localize({ key: 'scm publish branch action button title', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }, "{0} Publish Branch", '$(cloud-upload)'), - tooltip: this.state.isSyncInProgress ? - localize({ key: 'scm button publish branch running', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }, "Publishing Branch...") : - localize({ key: 'scm button publish branch', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }, "Publish Branch"), - arguments: [this.repository.sourceControl], - }, - enabled: !this.state.isSyncInProgress - }; - } - - private getSyncChangesActionButton(): SourceControlActionButton | undefined { - const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); - const showActionButton = config.get<{ sync: boolean }>('showActionButton', { sync: true }); - const branchIsAheadOrBehind = (this.state.HEAD?.behind ?? 0) > 0 || (this.state.HEAD?.ahead ?? 0) > 0; - - // Branch does not have an upstream, branch is not ahead/behind the remote branch, commit/merge/rebase is in progress, or the button is disabled - if (!this.state.HEAD?.upstream || !branchIsAheadOrBehind || this.state.isCommitInProgress || this.state.isMergeInProgress || this.state.isRebaseInProgress || !showActionButton.sync) { return undefined; } - - const ahead = this.state.HEAD.ahead ? ` ${this.state.HEAD.ahead}$(arrow-up)` : ''; - const behind = this.state.HEAD.behind ? ` ${this.state.HEAD.behind}$(arrow-down)` : ''; - const icon = this.state.isSyncInProgress ? '$(sync~spin)' : '$(sync)'; - - return { - command: { - command: 'git.sync', - title: `${icon}${behind}${ahead}`, - tooltip: this.state.isSyncInProgress ? - localize('syncing changes', "Synchronizing Changes...") - : this.repository.syncTooltip, - arguments: [this.repository.sourceControl], - }, - description: localize('scm button sync description', "{0} Sync Changes{1}{2}", icon, behind, ahead), - enabled: !this.state.isSyncInProgress - }; + return actionButton; } private onDidChangeOperations(): void { - const isCommitInProgress = - this.repository.operations.isRunning(Operation.Commit) || - this.repository.operations.isRunning(Operation.RebaseContinue); - - const isSyncInProgress = - this.repository.operations.isRunning(Operation.Sync) || + const isSyncRunning = this.repository.operations.isRunning(Operation.Sync) || this.repository.operations.isRunning(Operation.Push) || this.repository.operations.isRunning(Operation.Pull); - this.state = { ...this.state, isCommitInProgress, isSyncInProgress }; - } - - private onDidChangeSmartCommitSettings(): void { - this.state = { - ...this.state, - repositoryHasChangesToCommit: this.repositoryHasChangesToCommit() - }; + this.state = { ...this.state, isSyncRunning }; } private onDidRunGitStatus(): void { this.state = { ...this.state, HEAD: this.repository.HEAD, - isMergeInProgress: this.repository.mergeGroup.resourceStates.length !== 0, - isRebaseInProgress: !!this.repository.rebaseCommit, - repositoryHasChangesToCommit: this.repositoryHasChangesToCommit() + repositoryHasNoChanges: + this.repository.indexGroup.resourceStates.length === 0 && + this.repository.mergeGroup.resourceStates.length === 0 && + this.repository.untrackedGroup.resourceStates.length === 0 && + this.repository.workingTreeGroup.resourceStates.length === 0 }; } - private repositoryHasChangesToCommit(): boolean { - const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); - const enableSmartCommit = config.get('enableSmartCommit') === true; - const suggestSmartCommit = config.get('suggestSmartCommit') === true; - const smartCommitChanges = config.get<'all' | 'tracked'>('smartCommitChanges', 'all'); - - const resources = [...this.repository.indexGroup.resourceStates]; - - if ( - // Smart commit enabled (all) - (enableSmartCommit && smartCommitChanges === 'all') || - // Smart commit disabled, smart suggestion enabled - (!enableSmartCommit && suggestSmartCommit) - ) { - resources.push(...this.repository.workingTreeGroup.resourceStates); - } - - // Smart commit enabled (tracked only) - if (enableSmartCommit && smartCommitChanges === 'tracked') { - resources.push(...this.repository.workingTreeGroup.resourceStates.filter(r => r.type !== Status.UNTRACKED)); - } - - return resources.length !== 0; - } - dispose(): void { this.disposables = dispose(this.disposables); } diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index e159be1b63..029a19933b 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -5,8 +5,8 @@ import { Model } from '../model'; import { Repository as BaseRepository, Resource } from '../repository'; -import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, ForcePushMode, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, RefType, CredentialsProvider, BranchQuery, PushErrorHandler, PublishEvent, FetchOptions, RemoteSourceProvider, RemoteSourcePublisher, ICloneOptions, PostCommitCommandsProvider } from './git'; // {{SQL CARBON EDIT}} add ICloneOptions -import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands, CancellationToken } from 'vscode'; // {{SQL CARBON EDIT}} Add cancellationToken +import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, ForcePushMode, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, RefType, CredentialsProvider, BranchQuery, PushErrorHandler, PublishEvent, FetchOptions, RemoteSourceProvider, RemoteSourcePublisher, ICloneOptions } from './git'; // {{SQL CARBON EDIT}} add ICloneOptions +import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands, CancellationToken } from 'vscode'; import { combinedDisposable, mapEvent } from '../util'; import { toGitUri } from '../uri'; import { GitExtensionImpl } from './extension'; @@ -57,157 +57,157 @@ export class ApiRepositoryUIState implements RepositoryUIState { export class ApiRepository implements Repository { - readonly rootUri: Uri = Uri.file(this.repository.root); - readonly inputBox: InputBox = new ApiInputBox(this.repository.inputBox); - readonly state: RepositoryState = new ApiRepositoryState(this.repository); - readonly ui: RepositoryUIState = new ApiRepositoryUIState(this.repository.sourceControl); + readonly rootUri: Uri = Uri.file(this._repository.root); + readonly inputBox: InputBox = new ApiInputBox(this._repository.inputBox); + readonly state: RepositoryState = new ApiRepositoryState(this._repository); + readonly ui: RepositoryUIState = new ApiRepositoryUIState(this._repository.sourceControl); - constructor(readonly repository: BaseRepository) { } + constructor(private _repository: BaseRepository) { } apply(patch: string, reverse?: boolean): Promise { - return this.repository.apply(patch, reverse); + return this._repository.apply(patch, reverse); } getConfigs(): Promise<{ key: string; value: string }[]> { - return this.repository.getConfigs(); + return this._repository.getConfigs(); } getConfig(key: string): Promise { - return this.repository.getConfig(key); + return this._repository.getConfig(key); } setConfig(key: string, value: string): Promise { - return this.repository.setConfig(key, value); + return this._repository.setConfig(key, value); } getGlobalConfig(key: string): Promise { - return this.repository.getGlobalConfig(key); + return this._repository.getGlobalConfig(key); } getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number }> { - return this.repository.getObjectDetails(treeish, path); + return this._repository.getObjectDetails(treeish, path); } detectObjectType(object: string): Promise<{ mimetype: string; encoding?: string }> { - return this.repository.detectObjectType(object); + return this._repository.detectObjectType(object); } buffer(ref: string, filePath: string): Promise { - return this.repository.buffer(ref, filePath); + return this._repository.buffer(ref, filePath); } show(ref: string, path: string): Promise { - return this.repository.show(ref, path); + return this._repository.show(ref, path); } getCommit(ref: string): Promise { - return this.repository.getCommit(ref); + return this._repository.getCommit(ref); } add(paths: string[]) { - return this.repository.add(paths.map(p => Uri.file(p))); + return this._repository.add(paths.map(p => Uri.file(p))); } revert(paths: string[]) { - return this.repository.revert(paths.map(p => Uri.file(p))); + return this._repository.revert(paths.map(p => Uri.file(p))); } clean(paths: string[]) { - return this.repository.clean(paths.map(p => Uri.file(p))); + return this._repository.clean(paths.map(p => Uri.file(p))); } diff(cached?: boolean) { - return this.repository.diff(cached); + return this._repository.diff(cached); } diffWithHEAD(): Promise; diffWithHEAD(path: string): Promise; diffWithHEAD(path?: string): Promise { - return this.repository.diffWithHEAD(path); + return this._repository.diffWithHEAD(path); } diffWith(ref: string): Promise; diffWith(ref: string, path: string): Promise; diffWith(ref: string, path?: string): Promise { - return this.repository.diffWith(ref, path); + return this._repository.diffWith(ref, path); } diffIndexWithHEAD(): Promise; diffIndexWithHEAD(path: string): Promise; diffIndexWithHEAD(path?: string): Promise { - return this.repository.diffIndexWithHEAD(path); + return this._repository.diffIndexWithHEAD(path); } diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffIndexWith(ref: string, path?: string): Promise { - return this.repository.diffIndexWith(ref, path); + return this._repository.diffIndexWith(ref, path); } diffBlobs(object1: string, object2: string): Promise { - return this.repository.diffBlobs(object1, object2); + return this._repository.diffBlobs(object1, object2); } diffBetween(ref1: string, ref2: string): Promise; diffBetween(ref1: string, ref2: string, path: string): Promise; diffBetween(ref1: string, ref2: string, path?: string): Promise { - return this.repository.diffBetween(ref1, ref2, path); + return this._repository.diffBetween(ref1, ref2, path); } hashObject(data: string): Promise { - return this.repository.hashObject(data); + return this._repository.hashObject(data); } createBranch(name: string, checkout: boolean, ref?: string | undefined): Promise { - return this.repository.branch(name, checkout, ref); + return this._repository.branch(name, checkout, ref); } deleteBranch(name: string, force?: boolean): Promise { - return this.repository.deleteBranch(name, force); + return this._repository.deleteBranch(name, force); } getBranch(name: string): Promise { - return this.repository.getBranch(name); + return this._repository.getBranch(name); } getBranches(query: BranchQuery): Promise { - return this.repository.getBranches(query); + return this._repository.getBranches(query); } setBranchUpstream(name: string, upstream: string): Promise { - return this.repository.setBranchUpstream(name, upstream); + return this._repository.setBranchUpstream(name, upstream); } getMergeBase(ref1: string, ref2: string): Promise { - return this.repository.getMergeBase(ref1, ref2); + return this._repository.getMergeBase(ref1, ref2); } tag(name: string, upstream: string): Promise { - return this.repository.tag(name, upstream); + return this._repository.tag(name, upstream); } deleteTag(name: string): Promise { - return this.repository.deleteTag(name); + return this._repository.deleteTag(name); } status(): Promise { - return this.repository.status(); + return this._repository.status(); } checkout(treeish: string): Promise { - return this.repository.checkout(treeish); + return this._repository.checkout(treeish); } addRemote(name: string, url: string): Promise { - return this.repository.addRemote(name, url); + return this._repository.addRemote(name, url); } removeRemote(name: string): Promise { - return this.repository.removeRemote(name); + return this._repository.removeRemote(name); } renameRemote(name: string, newName: string): Promise { - return this.repository.renameRemote(name, newName); + return this._repository.renameRemote(name, newName); } fetch(arg0?: FetchOptions | string | undefined, @@ -216,30 +216,30 @@ export class ApiRepository implements Repository { prune?: boolean | undefined ): Promise { if (arg0 !== undefined && typeof arg0 !== 'string') { - return this.repository.fetch(arg0); + return this._repository.fetch(arg0); } - return this.repository.fetch({ remote: arg0, ref, depth, prune }); + return this._repository.fetch({ remote: arg0, ref, depth, prune }); } pull(unshallow?: boolean): Promise { - return this.repository.pull(undefined, unshallow); + return this._repository.pull(undefined, unshallow); } push(remoteName?: string, branchName?: string, setUpstream: boolean = false, force?: ForcePushMode): Promise { - return this.repository.pushTo(remoteName, branchName, setUpstream, force); + return this._repository.pushTo(remoteName, branchName, setUpstream, force); } blame(path: string): Promise { - return this.repository.blame(path); + return this._repository.blame(path); } log(options?: LogOptions): Promise { - return this.repository.log(options); + return this._repository.log(options); } commit(message: string, opts?: CommitOptions): Promise { - return this.repository.commit(message, opts); + return this._repository.commit(message, opts); } } @@ -323,10 +323,6 @@ export class ApiImpl implements API { return this._model.registerCredentialsProvider(provider); } - registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): Disposable { - return this._model.registerPostCommitCommandsProvider(provider); - } - registerPushErrorHandler(handler: PushErrorHandler): Disposable { return this._model.registerPushErrorHandler(handler); } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index d339f8a4c2..f7bea962a3 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Uri, Event, Disposable, ProviderResult, CancellationToken, Progress, Command } from 'vscode'; // {{SQL CARBON EDIT}} add CancellationToken +import { Uri, Event, Disposable, ProviderResult, CancellationToken, Progress } from 'vscode'; // {{SQL CARBON EDIT}} add CancellationToken export { ProviderResult } from 'vscode'; export interface Git { @@ -137,9 +137,6 @@ export interface CommitOptions { empty?: boolean; noVerify?: boolean; requireUserConfig?: boolean; - useEditor?: boolean; - verbose?: boolean; - postCommitCommand?: string; } export interface FetchOptions { @@ -254,10 +251,6 @@ export interface CredentialsProvider { getCredentials(host: Uri): ProviderResult; } -export interface PostCommitCommandsProvider { - getCommands(repository: Repository): Command[]; -} - export interface PushErrorHandler { handlePushError(repository: Repository, remote: Remote, refspec: string, error: Error & { gitErrorCode: GitErrorCodes }): Promise; } @@ -294,7 +287,6 @@ export interface API { registerRemoteSourcePublisher(publisher: RemoteSourcePublisher): Disposable; registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable; registerCredentialsProvider(provider: CredentialsProvider): Disposable; - registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): Disposable; registerPushErrorHandler(handler: PushErrorHandler): Disposable; } @@ -306,7 +298,7 @@ export interface GitExtension { /** * Returns a specific API version. * - * Throws error if git extension is disabled. You can listen to the + * Throws error if git extension is disabled. You can listed to the * [GitExtension.onDidChangeEnablement](#GitExtension.onDidChangeEnablement) event * to know when the extension becomes enabled/disabled. * @@ -352,7 +344,6 @@ export const enum GitErrorCodes { PatchDoesNotApply = 'PatchDoesNotApply', NoPathFound = 'NoPathFound', UnknownPath = 'UnknownPath', - EmptyCommitMessage = 'EmptyCommitMessage' } // {{SQL CARBON EDIT}} move ICloneOptions from git.ts to here since it's used in clone() diff --git a/extensions/git/src/askpass.ts b/extensions/git/src/askpass.ts index 87e6a21a8a..454ee27b32 100644 --- a/extensions/git/src/askpass.ts +++ b/extensions/git/src/askpass.ts @@ -3,31 +3,31 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { window, InputBoxOptions, Uri, Disposable, workspace } from 'vscode'; -import { IDisposable, EmptyDisposable, toDisposable } from './util'; +import { window, InputBoxOptions, Uri, OutputChannel, Disposable, workspace } from 'vscode'; +import { IDisposable, EmptyDisposable, toDisposable, logTimestamp } from './util'; import * as path from 'path'; -import { IIPCHandler, IIPCServer } from './ipc/ipcServer'; +import { IIPCHandler, IIPCServer, createIPCServer } from './ipc/ipcServer'; import { CredentialsProvider, Credentials } from './api/git'; -import { ITerminalEnvironmentProvider } from './terminal'; -export class Askpass implements IIPCHandler, ITerminalEnvironmentProvider { +export class Askpass implements IIPCHandler { - private env: { [key: string]: string }; private disposable: IDisposable = EmptyDisposable; private cache = new Map(); private credentialsProviders = new Set(); - constructor(private ipc?: IIPCServer) { + static async create(outputChannel: OutputChannel, context?: string): Promise { + try { + return new Askpass(await createIPCServer(context)); + } catch (err) { + outputChannel.appendLine(`${logTimestamp()} [error] Failed to create git askpass IPC: ${err}`); + return new Askpass(); + } + } + + private constructor(private ipc?: IIPCServer) { if (ipc) { this.disposable = ipc.registerHandler('askpass', this); } - - this.env = { - GIT_ASKPASS: path.join(__dirname, this.ipc ? 'askpass.sh' : 'askpass-empty.sh'), - VSCODE_GIT_ASKPASS_NODE: process.execPath, - VSCODE_GIT_ASKPASS_EXTRA_ARGS: (process.versions['electron'] && process.versions['microsoft-build']) ? '--ms-enable-electron-run-as-node' : '', - VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js'), - }; } async handle({ request, host }: { request: string; host: string }): Promise { @@ -73,13 +73,25 @@ export class Askpass implements IIPCHandler, ITerminalEnvironmentProvider { } getEnv(): { [key: string]: string } { - const config = workspace.getConfiguration('git'); - return config.get('useIntegratedAskPass') ? this.env : {}; - } + if (!this.ipc) { + return { + GIT_ASKPASS: path.join(__dirname, 'askpass-empty.sh') + }; + } + + let env: { [key: string]: string } = { + ...this.ipc.getEnv(), + VSCODE_GIT_ASKPASS_NODE: process.execPath, + VSCODE_GIT_ASKPASS_EXTRA_ARGS: (process.versions['electron'] && process.versions['microsoft-build']) ? '--ms-enable-electron-run-as-node' : '', + VSCODE_GIT_ASKPASS_MAIN: path.join(__dirname, 'askpass-main.js') + }; - getTerminalEnv(): { [key: string]: string } { const config = workspace.getConfiguration('git'); - return config.get('useIntegratedAskPass') && config.get('terminalAuthentication') ? this.env : {}; + if (config.get('useIntegratedAskPass')) { + env.GIT_ASKPASS = path.join(__dirname, 'askpass.sh'); + } + + return env; } registerCredentialsProvider(provider: CredentialsProvider): Disposable { diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 5ac9475237..a171a64aa5 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -5,18 +5,17 @@ import * as os from 'os'; import * as path from 'path'; -import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge } from 'vscode'; +import { Command, commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; import * as nls from 'vscode-nls'; -import { uniqueNamesGenerator, adjectives, animals, colors, NumberDictionary } from '@joaomoreno/unique-names-generator'; import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourcePublisher } from './api/git'; import { Git, Stash } from './git'; import { Model } from './model'; import { Repository, Resource, ResourceGroupType } from './repository'; import { applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineChange, toLineRanges } from './staging'; -import { fromGitUri, toGitUri, isGitUri, toMergeUris } from './uri'; -import { grep, isDescendant, pathEquals, relativePath } from './util'; -import { LogLevel, OutputChannelLogger } from './log'; +import { fromGitUri, toGitUri, isGitUri } from './uri'; +import { grep, isDescendant, logTimestamp, pathEquals, relativePath } from './util'; +import { Log, LogLevel } from './log'; import { GitTimelineItem } from './timelineProvider'; import { ApiRepository } from './api/api1'; import { pickRemoteSource } from './remoteSource'; @@ -26,26 +25,24 @@ const localize = nls.loadMessageBundle(); class CheckoutItem implements QuickPickItem { protected get shortCommit(): string { return (this.ref.commit || '').substr(0, 8); } - get label(): string { return `${this.repository.isBranchProtected(this.ref.name ?? '') ? '$(lock)' : '$(git-branch)'} ${this.ref.name || this.shortCommit}`; } + get label(): string { return this.ref.name || this.shortCommit; } get description(): string { return this.shortCommit; } - get refName(): string | undefined { return this.ref.name; } - constructor(protected repository: Repository, protected ref: Ref) { } + constructor(protected ref: Ref) { } - async run(opts?: { detached?: boolean }): Promise { + async run(repository: Repository, opts?: { detached?: boolean }): Promise { const ref = this.ref.name; if (!ref) { return; } - await this.repository.checkout(ref, opts); + await repository.checkout(ref, opts); } } class CheckoutTagItem extends CheckoutItem { - override get label(): string { return `$(tag) ${this.ref.name || this.shortCommit}`; } override get description(): string { return localize('tag at', "Tag at {0}", this.shortCommit); } @@ -53,22 +50,21 @@ class CheckoutTagItem extends CheckoutItem { class CheckoutRemoteHeadItem extends CheckoutItem { - override get label(): string { return `$(cloud) ${this.ref.name || this.shortCommit}`; } override get description(): string { return localize('remote branch at', "Remote branch at {0}", this.shortCommit); } - override async run(opts?: { detached?: boolean }): Promise { + override async run(repository: Repository, opts?: { detached?: boolean }): Promise { if (!this.ref.name) { return; } - const branches = await this.repository.findTrackingBranches(this.ref.name); + const branches = await repository.findTrackingBranches(this.ref.name); if (branches.length > 0) { - await this.repository.checkout(branches[0].name!, opts); + await repository.checkout(branches[0].name!, opts); } else { - await this.repository.checkoutTracking(this.ref.name, opts); + await repository.checkoutTracking(this.ref.name, opts); } } } @@ -141,7 +137,6 @@ class HEADItem implements QuickPickItem { get label(): string { return 'HEAD'; } get description(): string { return (this.repository.HEAD && this.repository.HEAD.commit || '').substr(0, 8); } get alwaysShow(): boolean { return true; } - get refName(): string { return 'HEAD'; } } class AddRemoteItem implements QuickPickItem { @@ -222,7 +217,7 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] { checkoutTypes = checkoutTypeConfig; } - const processors = checkoutTypes.map(type => getCheckoutProcessor(repository, type)) + const processors = checkoutTypes.map(getCheckoutProcessor) .filter(p => !!p) as CheckoutProcessor[]; for (const ref of repository.refs) { @@ -237,8 +232,8 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] { class CheckoutProcessor { private refs: Ref[] = []; - get items(): CheckoutItem[] { return this.refs.map(r => new this.ctor(this.repository, r)); } - constructor(private repository: Repository, private type: RefType, private ctor: { new(repository: Repository, ref: Ref): CheckoutItem }) { } + get items(): CheckoutItem[] { return this.refs.map(r => new this.ctor(r)); } + constructor(private type: RefType, private ctor: { new(ref: Ref): CheckoutItem }) { } onRef(ref: Ref): void { if (ref.type === this.type) { @@ -247,14 +242,14 @@ class CheckoutProcessor { } } -function getCheckoutProcessor(repository: Repository, type: string): CheckoutProcessor | undefined { +function getCheckoutProcessor(type: string): CheckoutProcessor | undefined { switch (type) { case 'local': - return new CheckoutProcessor(repository, RefType.Head, CheckoutItem); + return new CheckoutProcessor(RefType.Head, CheckoutItem); case 'remote': - return new CheckoutProcessor(repository, RefType.RemoteHead, CheckoutRemoteHeadItem); + return new CheckoutProcessor(RefType.RemoteHead, CheckoutRemoteHeadItem); case 'tags': - return new CheckoutProcessor(repository, RefType.Tag, CheckoutTagItem); + return new CheckoutProcessor(RefType.Tag, CheckoutTagItem); } return undefined; @@ -315,7 +310,7 @@ export class CommandCenter { constructor( private git: Git, private model: Model, - private outputChannelLogger: OutputChannelLogger, + private outputChannel: OutputChannel, private telemetryReporter: TelemetryReporter ) { this.disposables = Commands.map(({ commandId, key, method, options }) => { @@ -333,25 +328,11 @@ export class CommandCenter { @command('git.setLogLevel') async setLogLevel(): Promise { - const createItem = (logLevel: LogLevel) => { - let description: string | undefined; - const defaultDescription = localize('default', "Default"); - const currentDescription = localize('current', "Current"); - - if (logLevel === this.outputChannelLogger.defaultLogLevel && logLevel === this.outputChannelLogger.currentLogLevel) { - description = `${defaultDescription} & ${currentDescription} `; - } else if (logLevel === this.outputChannelLogger.defaultLogLevel) { - description = defaultDescription; - } else if (logLevel === this.outputChannelLogger.currentLogLevel) { - description = currentDescription; - } - - return { - label: LogLevel[logLevel], - logLevel, - description - }; - }; + const createItem = (logLevel: LogLevel) => ({ + label: LogLevel[logLevel], + logLevel, + description: Log.logLevel === logLevel ? localize('current', "Current") : undefined + }); const items = [ createItem(LogLevel.Trace), @@ -371,7 +352,8 @@ export class CommandCenter { return; } - this.outputChannelLogger.currentLogLevel = choice.logLevel; + Log.logLevel = choice.logLevel; + this.outputChannel.appendLine(localize('changed', "{0} Log level changed to: {1}", logTimestamp(), LogLevel[Log.logLevel])); } @command('git.refresh', { repository: true }) @@ -408,55 +390,6 @@ export class CommandCenter { } } - @command('_git.openMergeEditor') - async openMergeEditor(uri: unknown) { - if (!(uri instanceof Uri)) { - return; - } - const repo = this.model.getRepository(uri); - if (!repo) { - return; - } - - const isRebasing = Boolean(repo.rebaseCommit); - - type InputData = { uri: Uri; title?: string; detail?: string; description?: string }; - const mergeUris = toMergeUris(uri); - const ours: InputData = { uri: mergeUris.ours, title: localize('Yours', 'Yours') }; - const theirs: InputData = { uri: mergeUris.theirs, title: localize('Theirs', 'Theirs') }; - - try { - const [head, rebaseOrMergeHead] = await Promise.all([ - repo.getCommit('HEAD'), - isRebasing ? repo.getCommit('REBASE_HEAD') : repo.getCommit('MERGE_HEAD') - ]); - // ours (current branch and commit) - ours.detail = head.refNames.map(s => s.replace(/^HEAD ->/, '')).join(', '); - ours.description = '$(git-commit) ' + head.hash.substring(0, 7); - - // theirs - theirs.detail = rebaseOrMergeHead.refNames.join(', '); - theirs.description = '$(git-commit) ' + rebaseOrMergeHead.hash.substring(0, 7); - - } catch (error) { - // not so bad, can continue with just uris - console.error('FAILED to read HEAD, MERGE_HEAD commits'); - console.error(error); - } - - const options = { - base: mergeUris.base, - input1: isRebasing ? ours : theirs, - input2: isRebasing ? theirs : ours, - output: uri - }; - - await commands.executeCommand( - '_open.mergeEditor', - options - ); - } - async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean } = {}): Promise { if (!url || typeof url !== 'string') { url = await pickRemoteSource({ @@ -468,8 +401,7 @@ export class CommandCenter { if (!url) { /* __GDPR__ "clone" : { - "owner": "lszomoru", - "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The outcome of the git operation" } + "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_URL' }); @@ -494,8 +426,7 @@ export class CommandCenter { if (!uris || uris.length === 0) { /* __GDPR__ "clone" : { - "owner": "lszomoru", - "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The outcome of the git operation" } + "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' }); @@ -553,9 +484,8 @@ export class CommandCenter { /* __GDPR__ "clone" : { - "owner": "lszomoru", - "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The outcome of the git operation" }, - "openFolder": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true, "comment": "Indicates whether the folder is opened following the clone operation" } + "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "openFolder": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true } } */ this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'success' }, { openFolder: action === PostCloneAction.Open || action === PostCloneAction.OpenNewWindow ? 1 : 0 }); @@ -573,8 +503,7 @@ export class CommandCenter { if (/already exists and is not an empty directory/.test(err && err.stderr || '')) { /* __GDPR__ "clone" : { - "owner": "lszomoru", - "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The outcome of the git operation" } + "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'directory_not_empty' }); @@ -583,8 +512,7 @@ export class CommandCenter { } else { /* __GDPR__ "clone" : { - "owner": "lszomoru", - "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The outcome of the git operation" } + "outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'error' }); @@ -892,14 +820,14 @@ export class CommandCenter { @command('git.stage') async stage(...resourceStates: SourceControlResourceState[]): Promise { - this.outputChannelLogger.logDebug(`git.stage ${resourceStates.length} `); + this.outputChannel.appendLine(`${logTimestamp()} git.stage ${resourceStates.length}`); resourceStates = resourceStates.filter(s => !!s); if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) { const resource = this.getSCMResource(); - this.outputChannelLogger.logDebug(`git.stage.getSCMResource ${resource ? resource.resourceUri.toString() : null} `); + this.outputChannel.appendLine(`${logTimestamp()} git.stage.getSCMResource ${resource ? resource.resourceUri.toString() : null}`); if (!resource) { return; @@ -942,7 +870,7 @@ export class CommandCenter { const untracked = selection.filter(s => s.resourceGroupType === ResourceGroupType.Untracked); const scmResources = [...workingTree, ...untracked, ...resolved, ...unresolved]; - this.outputChannelLogger.logDebug(`git.stage.scmResources ${scmResources.length} `); + this.outputChannel.appendLine(`${logTimestamp()} git.stage.scmResources ${scmResources.length}`); if (!scmResources.length) { return; } @@ -1092,47 +1020,6 @@ export class CommandCenter { await this._stageChanges(textEditor, selectedChanges); } - @command('git.acceptMerge') - async acceptMerge(uri: Uri | unknown): Promise { - if (!(uri instanceof Uri)) { - return; - } - const repository = this.model.getRepository(uri); - if (!repository) { - console.log(`FAILED to accept merge because uri ${uri.toString()} doesn't belong to any repository`); - return; - } - - const { activeTab } = window.tabGroups.activeTabGroup; - if (!activeTab) { - return; - } - - // make sure to save the merged document - const doc = workspace.textDocuments.find(doc => doc.uri.toString() === uri.toString()); - if (!doc) { - console.log(`FAILED to accept merge because uri ${uri.toString()} doesn't match a document`); - return; - } - if (doc.isDirty) { - await doc.save(); - } - - // find the merge editor tabs for the resource in question and close them all - let didCloseTab = false; - const mergeEditorTabs = window.tabGroups.all.map(group => group.tabs.filter(tab => tab.input instanceof TabInputTextMerge && tab.input.result.toString() === uri.toString())).flat(); - if (mergeEditorTabs.includes(activeTab)) { - didCloseTab = await window.tabGroups.close(mergeEditorTabs, true); - } - - // Only stage if the merge editor has been successfully closed. That means all conflicts have been - // handled or unhandled conflicts are OK by the user. - if (didCloseTab) { - await repository.add([uri]); - await commands.executeCommand('workbench.view.scm'); - } - } - private async _stageChanges(textEditor: TextEditor, changes: LineChange[]): Promise { const modifiedDocument = textEditor.document; const modifiedUri = modifiedDocument.uri; @@ -1452,7 +1339,7 @@ export class CommandCenter { private async smartCommit( repository: Repository, getCommitMessage: () => Promise, - opts: CommitOptions + opts?: CommitOptions ): Promise { const config = workspace.getConfiguration('git', Uri.file(repository.root)); let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit'); @@ -1498,8 +1385,14 @@ export class CommandCenter { } } + if (!opts) { + opts = { all: noStagedChanges }; + } else if (!opts.all && noStagedChanges && !opts.empty) { + opts = { ...opts, all: true }; + } + // no changes, and the user has not configured to commit all in this case - if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit && !opts.empty && !opts.all) { + if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit && !opts.empty) { const suggestSmartCommit = config.get('suggestSmartCommit') === true; if (!suggestSmartCommit) { @@ -1523,12 +1416,6 @@ export class CommandCenter { } } - if (opts.all === undefined) { - opts = { ...opts, all: noStagedChanges }; - } else if (!opts.all && noStagedChanges && !opts.empty) { - opts = { ...opts, all: true }; - } - // enable signing of commits if configured opts.signCommit = enableCommitSigning; @@ -1536,14 +1423,6 @@ export class CommandCenter { opts.signoff = true; } - if (config.get('useEditorAsCommitInput')) { - opts.useEditor = true; - - if (config.get('verboseCommit')) { - opts.verbose = true; - } - } - const smartCommitChanges = config.get<'all' | 'tracked'>('smartCommitChanges'); if ( @@ -1558,8 +1437,6 @@ export class CommandCenter { // amend allows changing only the commit message && !opts.amend && !opts.empty - // rebase not in progress - && repository.rebaseCommit === undefined ) { const commitAnyway = localize('commit anyway', "Create Empty Commit"); const answer = await window.showInformationMessage(localize('no changes', "There are no changes to commit."), commitAnyway); @@ -1591,9 +1468,9 @@ export class CommandCenter { } } - const message = await getCommitMessage(); + let message = await getCommitMessage(); - if (!message && !opts.amend && !opts.useEditor) { + if (!message && !opts.amend) { return false; } @@ -1605,55 +1482,29 @@ export class CommandCenter { opts.all = 'tracked'; } - // Branch protection - const branchProtectionPrompt = config.get<'alwaysCommit' | 'alwaysCommitToNewBranch' | 'alwaysPrompt'>('branchProtectionPrompt')!; - if (repository.isBranchProtected() && (branchProtectionPrompt === 'alwaysPrompt' || branchProtectionPrompt === 'alwaysCommitToNewBranch')) { - const commitToNewBranch = localize('commit to branch', "Commit to a New Branch"); - - let pick: string | undefined = commitToNewBranch; - - if (branchProtectionPrompt === 'alwaysPrompt') { - const message = localize('confirm branch protection commit', "You are trying to commit to a protected branch and you might not have permission to push your commits to the remote.\n\nHow would you like to proceed?"); - const commit = localize('commit changes', "Commit Anyway"); - - pick = await window.showWarningMessage(message, { modal: true }, commitToNewBranch, commit); - } - - if (!pick) { - return false; - } else if (pick === commitToNewBranch) { - const branchName = await this.promptForBranchName(repository); - - if (!branchName) { - return false; - } - - await repository.branch(branchName, true); - } - } - await repository.commit(message, opts); - // Execute post commit command - if (opts.postCommitCommand?.length) { - await commands.executeCommand( - opts.postCommitCommand, - new ApiRepository(repository)); + const postCommitCommand = config.get<'none' | 'push' | 'sync'>('postCommitCommand'); + + switch (postCommitCommand) { + case 'push': + await this._push(repository, { pushType: PushType.Push, silent: true }); + break; + case 'sync': + await this.sync(repository); + break; } return true; } - private async commitWithAnyInput(repository: Repository, opts: CommitOptions): Promise { + private async commitWithAnyInput(repository: Repository, opts?: CommitOptions): Promise { const message = repository.inputBox.value; - const root = Uri.file(repository.root); - const config = workspace.getConfiguration('git', root); - const getCommitMessage = async () => { let _message: string | undefined = message; - if (!_message && !config.get('useEditorAsCommitInput')) { - const value: string | undefined = undefined; + if (!_message) { + let value: string | undefined = undefined; if (opts && opts.amend && repository.HEAD && repository.HEAD.commit) { return undefined; @@ -1687,8 +1538,8 @@ export class CommandCenter { } @command('git.commit', { repository: true }) - async commit(repository: Repository, postCommitCommand?: string): Promise { - await this.commitWithAnyInput(repository, { postCommitCommand }); + async commit(repository: Repository): Promise { + await this.commitWithAnyInput(repository); } @command('git.commitStaged', { repository: true }) @@ -1721,58 +1572,13 @@ export class CommandCenter { await this.commitWithAnyInput(repository, { all: true, amend: true }); } - @command('git.commitMessageAccept') - async commitMessageAccept(arg?: Uri): Promise { - if (!arg) { return; } - - // Close the tab - this._closeEditorTab(arg); - } - - @command('git.commitMessageDiscard') - async commitMessageDiscard(arg?: Uri): Promise { - if (!arg) { return; } - - // Clear the contents of the editor - const editors = window.visibleTextEditors - .filter(e => e.document.languageId === 'git-commit' && e.document.uri.toString() === arg.toString()); - - if (editors.length !== 1) { return; } - - const commitMsgEditor = editors[0]; - const commitMsgDocument = commitMsgEditor.document; - - const editResult = await commitMsgEditor.edit(builder => { - const firstLine = commitMsgDocument.lineAt(0); - const lastLine = commitMsgDocument.lineAt(commitMsgDocument.lineCount - 1); - - builder.delete(new Range(firstLine.range.start, lastLine.range.end)); - }); - - if (!editResult) { return; } - - // Save the document - const saveResult = await commitMsgDocument.save(); - if (!saveResult) { return; } - - // Close the tab - this._closeEditorTab(arg); - } - - private _closeEditorTab(uri: Uri): void { - const tabToClose = window.tabGroups.all.map(g => g.tabs).flat() - .filter(t => t.input instanceof TabInputText && t.input.uri.toString() === uri.toString()); - - window.tabGroups.close(tabToClose); - } - private async _commitEmpty(repository: Repository, noVerify?: boolean): Promise { const root = Uri.file(repository.root); const config = workspace.getConfiguration('git', root); const shouldPrompt = config.get('confirmEmptyCommits') === true; if (shouldPrompt) { - const message = localize('confirm empty commit', "Are you sure you want to create an empty commit?"); + const message = localize('confirm emtpy commit', "Are you sure you want to create an empty commit?"); const yes = localize('yes', "Yes"); const neverAgain = localize('yes never again', "Yes, Don't Show Again"); const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain); @@ -1919,7 +1725,7 @@ export class CommandCenter { const item = choice as CheckoutItem; try { - await item.run(opts); + await item.run(repository, opts); } catch (err) { if (err.gitErrorCode !== GitErrorCodes.DirtyWorkTree) { throw err; @@ -1931,10 +1737,10 @@ export class CommandCenter { if (choice === force) { await this.cleanAll(repository); - await item.run(opts); + await item.run(repository, opts); } else if (choice === stash) { await this.stash(repository); - await item.run(opts); + await item.run(repository, opts); await this.stashPopLatest(repository); } } @@ -1953,100 +1759,34 @@ export class CommandCenter { await this._branch(repository, undefined, true); } - private generateRandomBranchName(repository: Repository, separator: string): string { + private async promptForBranchName(defaultName?: string, initialValue?: string): Promise { const config = workspace.getConfiguration('git'); - const branchRandomNameDictionary = config.get('branchRandomName.dictionary')!; - - const dictionaries: string[][] = []; - for (const dictionary of branchRandomNameDictionary) { - if (dictionary.toLowerCase() === 'adjectives') { - dictionaries.push(adjectives); - } - if (dictionary.toLowerCase() === 'animals') { - dictionaries.push(animals); - } - if (dictionary.toLowerCase() === 'colors') { - dictionaries.push(colors); - } - if (dictionary.toLowerCase() === 'numbers') { - dictionaries.push(NumberDictionary.generate({ length: 3 })); - } - } - - if (dictionaries.length === 0) { - return ''; - } - - // 5 attempts to generate a random branch name - for (let index = 0; index < 5; index++) { - const randomName = uniqueNamesGenerator({ - dictionaries, - length: dictionaries.length, - separator - }); - - // Check for local ref conflict - if (!repository.refs.find(r => r.type === RefType.Head && r.name === randomName)) { - return randomName; - } - } - - return ''; - } - - private async promptForBranchName(repository: Repository, defaultName?: string, initialValue?: string): Promise { - const config = workspace.getConfiguration('git'); - const branchPrefix = config.get('branchPrefix')!; const branchWhitespaceChar = config.get('branchWhitespaceChar')!; const branchValidationRegex = config.get('branchValidationRegex')!; const sanitize = (name: string) => name ? name.trim().replace(/^-+/, '').replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar) : name; - let rawBranchName = defaultName; - - if (!rawBranchName) { - // Branch name - if (!initialValue) { - const branchRandomNameEnabled = config.get('branchRandomName.enable', false); - initialValue = `${branchPrefix}${branchRandomNameEnabled ? this.generateRandomBranchName(repository, branchWhitespaceChar) : ''}`; - } - - // Branch name selection - const initialValueSelection: [number, number] | undefined = - initialValue.startsWith(branchPrefix) ? [branchPrefix.length, initialValue.length] : undefined; - - rawBranchName = await window.showInputBox({ - placeHolder: localize('branch name', "Branch name"), - prompt: localize('provide branch name', "Please provide a new branch name"), - value: initialValue, - valueSelection: initialValueSelection, - ignoreFocusOut: true, - validateInput: (name: string) => { - const validateName = new RegExp(branchValidationRegex); - const sanitizedName = sanitize(name); - if (validateName.test(sanitizedName)) { - // If the sanitized name that we will use is different than what is - // in the input box, show an info message to the user informing them - // the branch name that will be used. - return name === sanitizedName - ? null - : { - message: localize('branch name does not match sanitized', "The new branch will be '{0}'", sanitizedName), - severity: InputBoxValidationSeverity.Info - }; - } - - return localize('branch name format invalid', "Branch name needs to match regex: {0}", branchValidationRegex); + const rawBranchName = defaultName || await window.showInputBox({ + placeHolder: localize('branch name', "Branch name"), + prompt: localize('provide branch name', "Please provide a new branch name"), + value: initialValue, + ignoreFocusOut: true, + validateInput: (name: string) => { + const validateName = new RegExp(branchValidationRegex); + if (validateName.test(sanitize(name))) { + return null; } - }); - } + + return localize('branch name format invalid', "Branch name needs to match regex: {0}", branchValidationRegex); + } + }); return sanitize(rawBranchName || ''); } private async _branch(repository: Repository, defaultName?: string, from = false): Promise { - const branchName = await this.promptForBranchName(repository, defaultName); + const branchName = await this.promptForBranchName(defaultName); if (!branchName) { return; @@ -2063,9 +1803,7 @@ export class CommandCenter { return; } - if (choice.refName) { - target = choice.refName; - } + target = choice.label; } await repository.branch(branchName, true, target); @@ -2111,7 +1849,7 @@ export class CommandCenter { @command('git.renameBranch', { repository: true }) async renameBranch(repository: Repository): Promise { const currentBranchName = repository.HEAD && repository.HEAD.name; - const branchName = await this.promptForBranchName(repository, undefined, currentBranchName); + const branchName = await this.promptForBranchName(undefined, currentBranchName); if (!branchName) { return; @@ -2577,16 +2315,17 @@ export class CommandCenter { } } - await repository.sync(HEAD, rebase); + if (rebase) { + await repository.syncRebase(HEAD); + } else { + await repository.sync(HEAD); + } } @command('git.sync', { repository: true }) async sync(repository: Repository): Promise { - const config = workspace.getConfiguration('git', Uri.file(repository.root)); - const rebase = config.get('rebaseWhenSync', false) === true; - try { - await this._sync(repository, rebase); + await this._sync(repository, false); } catch (err) { if (/Cancelled/i.test(err && (err.message || err.stderr || ''))) { return; @@ -2599,16 +2338,13 @@ export class CommandCenter { @command('git._syncAll') async syncAll(): Promise { await Promise.all(this.model.repositories.map(async repository => { - const config = workspace.getConfiguration('git', Uri.file(repository.root)); - const rebase = config.get('rebaseWhenSync', false) === true; - const HEAD = repository.HEAD; if (!HEAD || !HEAD.upstream) { return; } - await repository.sync(HEAD, rebase); + await repository.sync(HEAD); })); } @@ -2730,21 +2466,6 @@ export class CommandCenter { await commands.executeCommand('revealInExplorer', resourceState.resourceUri); } - @command('git.revealFileInOS.linux') - @command('git.revealFileInOS.mac') - @command('git.revealFileInOS.windows') - async revealFileInOS(resourceState: SourceControlResourceState): Promise { - if (!resourceState) { - return; - } - - if (!(resourceState.resourceUri instanceof Uri)) { - return; - } - - await commands.executeCommand('revealFileInOS', resourceState.resourceUri); - } - private async _stash(repository: Repository, includeUntracked = false): Promise { const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0 && (!includeUntracked || repository.untrackedGroup.resourceStates.length === 0); @@ -3034,7 +2755,13 @@ export class CommandCenter { @command('git.closeAllDiffEditors', { repository: true }) closeDiffEditors(repository: Repository): void { - repository.closeDiffEditors(undefined, undefined, true); + const resources = [ + ...repository.indexGroup.resourceStates.map(r => r.resourceUri.fsPath), + ...repository.workingTreeGroup.resourceStates.map(r => r.resourceUri.fsPath), + ...repository.untrackedGroup.resourceStates.map(r => r.resourceUri.fsPath) + ]; + + repository.closeDiffEditors(resources, resources, true); } private createCommand(id: string, key: string, method: Function, options: ScmCommandOptions): (...args: any[]) => any { @@ -3067,8 +2794,7 @@ export class CommandCenter { /* __GDPR__ "git.command" : { - "owner": "lszomoru", - "command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The command id of the command being executed" } + "command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ this.telemetryReporter.sendTelemetryEvent('git.command', { command: id }); @@ -3079,12 +2805,12 @@ export class CommandCenter { }; let message: string; - let type: 'error' | 'warning' | 'information' = 'error'; + let type: 'error' | 'warning' = 'error'; const choices = new Map void>(); const openOutputChannelChoice = localize('open git log', "Open Git Log"); - const outputChannelLogger = this.outputChannelLogger; - choices.set(openOutputChannelChoice, () => outputChannelLogger.showOutputChannel()); + const outputChannel = this.outputChannel as OutputChannel; + choices.set(openOutputChannelChoice, () => outputChannel.show()); const showCommandOutputChoice = localize('show command output', "Show Command Output"); if (err.stderr) { @@ -3142,12 +2868,6 @@ export class CommandCenter { message = localize('missing user info', "Make sure you configure your 'user.name' and 'user.email' in git."); choices.set(localize('learn more', "Learn More"), () => commands.executeCommand('vscode.open', Uri.parse('https://aka.ms/vscode-setup-git'))); break; - case GitErrorCodes.EmptyCommitMessage: - message = localize('empty commit', "Commit operation was cancelled due to empty commit message."); - choices.clear(); - type = 'information'; - options.modal = false; - break; default: { const hint = (err.stderr || err.message || String(err)) .replace(/^error: /mi, '') @@ -3169,25 +2889,17 @@ export class CommandCenter { return; } - let result: string | undefined; const allChoices = Array.from(choices.keys()); - - switch (type) { - case 'error': - result = await window.showErrorMessage(message, options, ...allChoices); - break; - case 'warning': - result = await window.showWarningMessage(message, options, ...allChoices); - break; - case 'information': - result = await window.showInformationMessage(message, options, ...allChoices); - break; - } + const result = type === 'error' + ? await window.showErrorMessage(message, options, ...allChoices) + : await window.showWarningMessage(message, options, ...allChoices); if (result) { const resultFn = choices.get(result); - resultFn?.(); + if (resultFn) { + resultFn(); + } } }); }; @@ -3201,10 +2913,10 @@ export class CommandCenter { private getSCMResource(uri?: Uri): Resource | undefined { uri = uri ? uri : (window.activeTextEditor && window.activeTextEditor.document.uri); - this.outputChannelLogger.logDebug(`git.getSCMResource.uri ${uri && uri.toString()}`); + this.outputChannel.appendLine(`${logTimestamp()} git.getSCMResource.uri ${uri && uri.toString()}`); for (const r of this.model.repositories.map(r => r.root)) { - this.outputChannelLogger.logDebug(`repo root ${r}`); + this.outputChannel.appendLine(`${logTimestamp()} repo root ${r}`); } if (!uri) { diff --git a/extensions/git/src/decorationProvider.ts b/extensions/git/src/decorationProvider.ts index eacb45fdc5..7b9f4b17f6 100644 --- a/extensions/git/src/decorationProvider.ts +++ b/extensions/git/src/decorationProvider.ts @@ -106,7 +106,7 @@ class GitDecorationProvider implements FileDecorationProvider { } private onDidRunGitStatus(): void { - const newDecorations = new Map(); + let newDecorations = new Map(); this.collectSubmoduleDecorationData(newDecorations); this.collectDecorationData(this.repository.indexGroup, newDecorations); diff --git a/extensions/git/src/encoding.ts b/extensions/git/src/encoding.ts index a74c9ec5ec..424f5312bb 100644 --- a/extensions/git/src/encoding.ts +++ b/extensions/git/src/encoding.ts @@ -50,7 +50,7 @@ const JSCHARDET_TO_ICONV_ENCODINGS: { [name: string]: string } = { }; export function detectEncoding(buffer: Buffer): string | null { - const result = detectEncodingByBOM(buffer); + let result = detectEncodingByBOM(buffer); if (result) { return result; diff --git a/extensions/git/src/git-editor-empty.sh b/extensions/git/src/git-editor-empty.sh deleted file mode 100755 index 1a2485251c..0000000000 --- a/extensions/git/src/git-editor-empty.sh +++ /dev/null @@ -1 +0,0 @@ -#!/bin/sh diff --git a/extensions/git/src/git-editor-main.ts b/extensions/git/src/git-editor-main.ts deleted file mode 100644 index 978ac6b610..0000000000 --- a/extensions/git/src/git-editor-main.ts +++ /dev/null @@ -1,21 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import { IPCClient } from './ipc/ipcClient'; - -function fatal(err: any): void { - console.error(err); - process.exit(1); -} - -function main(argv: string[]): void { - const ipcClient = new IPCClient('git-editor'); - const commitMessagePath = argv[argv.length - 1]; - - ipcClient.call({ commitMessagePath }).then(() => { - setTimeout(() => process.exit(0), 0); - }).catch(err => fatal(err)); -} - -main(process.argv); diff --git a/extensions/git/src/git-editor.sh b/extensions/git/src/git-editor.sh deleted file mode 100755 index d7e0d2deec..0000000000 --- a/extensions/git/src/git-editor.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -ELECTRON_RUN_AS_NODE="1" \ -"$VSCODE_GIT_EDITOR_NODE" "$VSCODE_GIT_EDITOR_MAIN" $VSCODE_GIT_EDITOR_EXTRA_ARGS "$@" diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 28008d24ca..3233a06f07 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -354,7 +354,7 @@ function sanitizePath(path: string): string { return path.replace(/^([a-z]):\\/i, (_, letter) => `${letter.toUpperCase()}:\\`); } -const COMMIT_FORMAT = '%H%n%aN%n%aE%n%at%n%ct%n%P%n%D%n%B'; +const COMMIT_FORMAT = '%H%n%aN%n%aE%n%at%n%ct%n%P%n%B'; /*export interface ICloneOptions { {{SQL CARBON EDIT}} moved to git.d.ts readonly parentPath: string; @@ -406,7 +406,7 @@ export class Git { } async clone(url: string, options: ICloneOptions, cancellationToken?: CancellationToken): Promise { - const baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository'; + let baseFolderName = decodeURI(url).replace(/[\/]+$/, '').replace(/^.*[\/\\]/, '').replace(/\.git$/, '') || 'repository'; let folderName = baseFolderName; let folderPath = path.join(options.parentPath, folderName); let count = 1; @@ -447,7 +447,7 @@ export class Git { }; try { - const command = ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath, '--progress']; + let command = ['clone', url.includes(' ') ? encodeURI(url) : url, folderPath, '--progress']; if (options.recursive) { command.push('--recursive'); } @@ -475,14 +475,13 @@ export class Git { const repoPath = path.normalize(result.stdout.trimLeft().replace(/[\r\n]+$/, '')); if (isWindows) { - // On Git 2.25+ if you call `rev-parse --show-toplevel` on a mapped drive, instead of getting the mapped - // drive path back, you get the UNC path for the mapped drive. So we will try to normalize it back to the - // mapped drive path, if possible + // On Git 2.25+ if you call `rev-parse --show-toplevel` on a mapped drive, instead of getting the mapped drive path back, you get the UNC path for the mapped drive. + // So we will try to normalize it back to the mapped drive path, if possible const repoUri = Uri.file(repoPath); const pathUri = Uri.file(repositoryPath); if (repoUri.authority.length !== 0 && pathUri.authority.length === 0) { // eslint-disable-next-line code-no-look-behind-regex - const match = /(?<=^\/?)([a-zA-Z])(?=:\/)/.exec(pathUri.path); + let match = /(?<=^\/?)([a-zA-Z])(?=:\/)/.exec(pathUri.path); if (match !== null) { const [, letter] = match; @@ -505,13 +504,6 @@ export class Git { return path.normalize(pathUri.fsPath); } - - // On Windows, there are cases in which the normalized path for a mapped folder contains a trailing `\` - // character (ex: \\server\folder\) due to the implementation of `path.normalize()`. This behaviour is - // by design as documented in https://github.com/nodejs/node/issues/1765. - if (repoUri.authority.length !== 0) { - return repoPath.replace(/\\$/, ''); - } } return repoPath; @@ -564,7 +556,9 @@ export class Git { private async _exec(args: string[], options: SpawnOptions = {}): Promise> { const child = this.spawn(args, options); - options.onSpawn?.(child); + if (options.onSpawn) { + options.onSpawn(child); + } if (options.input) { child.stdin!.end(options.input, 'utf8'); @@ -666,7 +660,6 @@ export interface Commit { authorName?: string; authorEmail?: string; commitDate?: Date; - refNames: string[]; } export class GitStatusParser { @@ -797,10 +790,10 @@ export function parseGitmodules(raw: string): Submodule[] { return result; } -const commitRegex = /([0-9a-f]{40})\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)(?:\n([^]*?))?(?:\x00)/gm; +const commitRegex = /([0-9a-f]{40})\n(.*)\n(.*)\n(.*)\n(.*)\n(.*)(?:\n([^]*?))?(?:\x00)/gm; export function parseGitCommits(data: string): Commit[] { - const commits: Commit[] = []; + let commits: Commit[] = []; let ref; let authorName; @@ -808,7 +801,6 @@ export function parseGitCommits(data: string): Commit[] { let authorDate; let commitDate; let parents; - let refNames; let message; let match; @@ -818,7 +810,7 @@ export function parseGitCommits(data: string): Commit[] { break; } - [, ref, authorName, authorEmail, authorDate, commitDate, parents, refNames, message] = match; + [, ref, authorName, authorEmail, authorDate, commitDate, parents, message] = match; if (message[message.length - 1] === '\n') { message = message.substr(0, message.length - 1); @@ -833,7 +825,6 @@ export function parseGitCommits(data: string): Commit[] { authorName: ` ${authorName}`.substr(1), authorEmail: ` ${authorEmail}`.substr(1), commitDate: new Date(Number(commitDate) * 1000), - refNames: refNames.split(',').map(s => s.trim()) }); } while (true); @@ -1406,37 +1397,20 @@ export class Repository { } async commit(message: string | undefined, opts: CommitOptions = Object.create(null)): Promise { - const args = ['commit', '--quiet']; - const options: SpawnOptions = {}; - - if (message) { - options.input = message; - args.push('--allow-empty-message', '--file', '-'); - } - - if (opts.verbose) { - args.push('--verbose'); - } + const args = ['commit', '--quiet', '--allow-empty-message']; if (opts.all) { args.push('--all'); } - if (opts.amend) { + if (opts.amend && message) { args.push('--amend'); } - if (!opts.useEditor) { - if (!message) { - if (opts.amend) { - args.push('--no-edit'); - } else { - options.input = ''; - args.push('--file', '-'); - } - } - - args.push('--allow-empty-message'); + if (opts.amend && !message) { + args.push('--amend', '--no-edit'); + } else { + args.push('--file', '-'); } if (opts.signoff) { @@ -1461,7 +1435,7 @@ export class Repository { } try { - await this.exec(args, options); + await this.exec(args, !opts.amend || message ? { input: message || '' } : {}); } catch (commitErr) { await this.handleCommitError(commitErr); } @@ -1475,7 +1449,7 @@ export class Repository { const args = ['rebase', '--continue']; try { - await this.exec(args, { env: { GIT_EDITOR: 'true' } }); + await this.exec(args); } catch (commitErr) { await this.handleCommitError(commitErr); } @@ -1485,9 +1459,6 @@ export class Repository { if (/not possible because you have unmerged files/.test(commitErr.stderr || '')) { commitErr.gitErrorCode = GitErrorCodes.UnmergedChanges; throw commitErr; - } else if (/Aborting commit due to empty commit message/.test(commitErr.stderr || '')) { - commitErr.gitErrorCode = GitErrorCodes.EmptyCommitMessage; - throw commitErr; } try { @@ -1569,7 +1540,7 @@ export class Repository { } async deleteTag(name: string): Promise { - const args = ['tag', '-d', name]; + let args = ['tag', '-d', name]; await this.exec(args); } @@ -1793,12 +1764,12 @@ export class Repository { } catch (err) { if (/^error: failed to push some refs to\b/m.test(err.stderr || '')) { err.gitErrorCode = GitErrorCodes.PushRejected; - } else if (/Permission.*denied/.test(err.stderr || '')) { - err.gitErrorCode = GitErrorCodes.PermissionDenied; } else if (/Could not read from remote repository/.test(err.stderr || '')) { err.gitErrorCode = GitErrorCodes.RemoteConnectionError; } else if (/^fatal: The current branch .* has no upstream branch/.test(err.stderr || '')) { err.gitErrorCode = GitErrorCodes.NoUpstreamBranch; + } else if (/Permission.*denied/.test(err.stderr || '')) { + err.gitErrorCode = GitErrorCodes.PermissionDenied; } throw err; diff --git a/extensions/git/src/gitEditor.ts b/extensions/git/src/gitEditor.ts deleted file mode 100644 index 6e401bdb14..0000000000 --- a/extensions/git/src/gitEditor.ts +++ /dev/null @@ -1,63 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import * as path from 'path'; -import { TabInputText, Uri, window, workspace } from 'vscode'; -import { IIPCHandler, IIPCServer } from './ipc/ipcServer'; -import { ITerminalEnvironmentProvider } from './terminal'; -import { EmptyDisposable, IDisposable } from './util'; - -interface GitEditorRequest { - commitMessagePath?: string; -} - -export class GitEditor implements IIPCHandler, ITerminalEnvironmentProvider { - - private env: { [key: string]: string }; - private disposable: IDisposable = EmptyDisposable; - - constructor(ipc?: IIPCServer) { - if (ipc) { - this.disposable = ipc.registerHandler('git-editor', this); - } - - this.env = { - GIT_EDITOR: `"${path.join(__dirname, ipc ? 'git-editor.sh' : 'git-editor-empty.sh')}"`, - VSCODE_GIT_EDITOR_NODE: process.execPath, - VSCODE_GIT_EDITOR_EXTRA_ARGS: (process.versions['electron'] && process.versions['microsoft-build']) ? '--ms-enable-electron-run-as-node' : '', - VSCODE_GIT_EDITOR_MAIN: path.join(__dirname, 'git-editor-main.js') - }; - } - - async handle({ commitMessagePath }: GitEditorRequest): Promise { - if (commitMessagePath) { - const uri = Uri.file(commitMessagePath); - const doc = await workspace.openTextDocument(uri); - await window.showTextDocument(doc, { preview: false }); - - return new Promise((c) => { - const onDidClose = window.tabGroups.onDidChangeTabs(async (tabs) => { - if (tabs.closed.some(t => t.input instanceof TabInputText && t.input.uri.toString() === uri.toString())) { - onDidClose.dispose(); - return c(true); - } - }); - }); - } - } - - getEnv(): { [key: string]: string } { - const config = workspace.getConfiguration('git'); - return config.get('useEditorAsCommitInput') ? this.env : {}; - } - - getTerminalEnv(): { [key: string]: string } { - const config = workspace.getConfiguration('git'); - return config.get('useEditorAsCommitInput') && config.get('terminalGitEditor') ? this.env : {}; - } - - dispose(): void { - this.disposable.dispose(); - } -} diff --git a/extensions/git/src/ipc/ipcServer.ts b/extensions/git/src/ipc/ipcServer.ts index 977b31eb78..1b30098166 100644 --- a/extensions/git/src/ipc/ipcServer.ts +++ b/extensions/git/src/ipc/ipcServer.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from 'vscode'; -import { ITerminalEnvironmentProvider } from '../terminal'; import { toDisposable } from '../util'; import * as path from 'path'; import * as http from 'http'; @@ -28,7 +27,7 @@ export interface IIPCHandler { handle(request: any): Promise; } -export async function createIPCServer(context?: string): Promise { +export async function createIPCServer(context?: string): Promise { const server = http.createServer(); const hash = crypto.createHash('sha1'); @@ -66,7 +65,7 @@ export interface IIPCServer extends Disposable { registerHandler(name: string, handler: IIPCHandler): Disposable; } -export class IPCServer implements IIPCServer, ITerminalEnvironmentProvider, Disposable { +class IPCServer implements IIPCServer, Disposable { private handlers = new Map(); get ipcHandlePath(): string { return this._ipcHandlePath; } @@ -111,10 +110,6 @@ export class IPCServer implements IIPCServer, ITerminalEnvironmentProvider, Disp return { VSCODE_GIT_IPC_HANDLE: this.ipcHandlePath }; } - getTerminalEnv(): { [key: string]: string } { - return { VSCODE_GIT_IPC_HANDLE: this.ipcHandlePath }; - } - dispose(): void { this.handlers.clear(); this.server.close(); diff --git a/extensions/git/src/log.ts b/extensions/git/src/log.ts index 17e3eefc95..7f18054bef 100644 --- a/extensions/git/src/log.ts +++ b/extensions/git/src/log.ts @@ -3,11 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -const localize = nls.loadMessageBundle(); - -import { commands, Disposable, Event, EventEmitter, OutputChannel, window, workspace } from 'vscode'; -import { dispose } from './util'; +import { Event, EventEmitter } from 'vscode'; /** * The severity level of a log message @@ -22,94 +18,33 @@ export enum LogLevel { Off = 7 } -/** - * Output channel logger - */ -export class OutputChannelLogger { +let _logLevel: LogLevel = LogLevel.Info; +const _onDidChangeLogLevel = new EventEmitter(); - private _onDidChangeLogLevel = new EventEmitter(); - readonly onDidChangeLogLevel: Event = this._onDidChangeLogLevel.event; +export const Log = { + /** + * Current logging level. + */ + get logLevel(): LogLevel { + return _logLevel; + }, - private _currentLogLevel!: LogLevel; - get currentLogLevel(): LogLevel { - return this._currentLogLevel; - } - set currentLogLevel(value: LogLevel) { - if (this._currentLogLevel === value) { + /** + * Current logging level. + */ + set logLevel(logLevel: LogLevel) { + if (_logLevel === logLevel) { return; } - this._currentLogLevel = value; - this._onDidChangeLogLevel.fire(value); + _logLevel = logLevel; + _onDidChangeLogLevel.fire(logLevel); + }, - this.log(localize('gitLogLevel', "Log level: {0}", LogLevel[value])); + /** + * An [event](#Event) that fires when the log level has changed. + */ + get onDidChangeLogLevel(): Event { + return _onDidChangeLogLevel.event; } - - private _defaultLogLevel!: LogLevel; - get defaultLogLevel(): LogLevel { - return this._defaultLogLevel; - } - - private _outputChannel: OutputChannel; - private _disposables: Disposable[] = []; - - constructor() { - // Output channel - this._outputChannel = window.createOutputChannel('Git'); - commands.registerCommand('git.showOutput', () => this.showOutputChannel()); - this._disposables.push(this._outputChannel); - - this._disposables.push(workspace.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('git.logLevel')) { - this.onLogLevelChange(); - } - })); - this.onLogLevelChange(); - } - - private onLogLevelChange(): void { - const config = workspace.getConfiguration('git'); - const logLevel: keyof typeof LogLevel = config.get('logLevel', 'Info'); - this.currentLogLevel = this._defaultLogLevel = LogLevel[logLevel] ?? LogLevel.Info; - } - - log(message: string, logLevel?: LogLevel): void { - if (logLevel && logLevel < this._currentLogLevel) { - return; - } - - this._outputChannel.appendLine(`[${new Date().toISOString()}]${logLevel ? ` [${LogLevel[logLevel].toLowerCase()}]` : ''} ${message}`); - } - - logCritical(message: string): void { - this.log(message, LogLevel.Critical); - } - - logDebug(message: string): void { - this.log(message, LogLevel.Debug); - } - - logError(message: string): void { - this.log(message, LogLevel.Error); - } - - logInfo(message: string): void { - this.log(message, LogLevel.Info); - } - - logTrace(message: string): void { - this.log(message, LogLevel.Trace); - } - - logWarning(message: string): void { - this.log(message, LogLevel.Warning); - } - - showOutputChannel(): void { - this._outputChannel.show(); - } - - dispose(): void { - this._disposables = dispose(this._disposables); - } -} +}; diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 33c102ebc3..ecef7fcdfd 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -6,14 +6,14 @@ import * as nls from 'vscode-nls'; const localize = nls.loadMessageBundle(); -import { ExtensionContext, workspace, Disposable, commands } from 'vscode'; +import { ExtensionContext, workspace, window, Disposable, commands, OutputChannel } from 'vscode'; import { findGit, Git } from './git'; import { Model } from './model'; import { CommandCenter } from './commands'; import { GitFileSystemProvider } from './fileSystemProvider'; import { GitDecorations } from './decorationProvider'; import { Askpass } from './askpass'; -import { toDisposable, filterEvent, eventToPromise } from './util'; +import { toDisposable, filterEvent, eventToPromise, logTimestamp } from './util'; import TelemetryReporter from '@vscode/extension-telemetry'; import { GitExtension } from './api/git'; import { GitProtocolHandler } from './protocolHandler'; @@ -24,9 +24,6 @@ import * as os from 'os'; import { GitTimelineProvider } from './timelineProvider'; import { registerAPICommands } from './api/api1'; import { TerminalEnvironmentManager } from './terminal'; -import { OutputChannelLogger } from './log'; -import { createIPCServer, IPCServer } from './ipc/ipcServer'; -import { GitEditor } from './gitEditor'; const deactivateTasks: { (): Promise }[] = []; @@ -36,7 +33,7 @@ export async function deactivate(): Promise { } } -async function createModel(context: ExtensionContext, outputChannelLogger: OutputChannelLogger, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise { +async function createModel(context: ExtensionContext, outputChannel: OutputChannel, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise { const pathValue = workspace.getConfiguration('git').get('path'); let pathHints = Array.isArray(pathValue) ? pathValue : pathValue ? [pathValue] : []; @@ -49,7 +46,7 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu } const info = await findGit(pathHints, gitPath => { - outputChannelLogger.logInfo(localize('validating', "Validating found git in: {0}", gitPath)); + outputChannel.appendLine(localize('validating', "{0} Validating found git in: {1}", logTimestamp(), gitPath)); if (excludes.length === 0) { return true; } @@ -57,30 +54,18 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu const normalized = path.normalize(gitPath).replace(/[\r\n]+$/, ''); const skip = excludes.some(e => normalized.startsWith(e)); if (skip) { - outputChannelLogger.logInfo(localize('skipped', "Skipped found git in: {0}", gitPath)); + outputChannel.appendLine(localize('skipped', "{0} Skipped found git in: {1}", logTimestamp(), gitPath)); } return !skip; }); - let ipcServer: IPCServer | undefined = undefined; - - try { - ipcServer = await createIPCServer(context.storagePath); - } catch (err) { - outputChannelLogger.logError(`Failed to create git IPC: ${err}`); - } - - const askpass = new Askpass(ipcServer); + const askpass = await Askpass.create(outputChannel, context.storagePath); disposables.push(askpass); - const gitEditor = new GitEditor(ipcServer); - disposables.push(gitEditor); - - const environment = { ...askpass.getEnv(), ...gitEditor.getEnv(), ...ipcServer?.getEnv() }; - const terminalEnvironmentManager = new TerminalEnvironmentManager(context, [askpass, gitEditor, ipcServer]); + const environment = askpass.getEnv(); + const terminalEnvironmentManager = new TerminalEnvironmentManager(context, environment); disposables.push(terminalEnvironmentManager); - outputChannelLogger.logInfo(localize('using git', "Using git {0} from {1}", info.version, info.path)); const git = new Git({ gitPath: info.path, @@ -88,7 +73,7 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu version: info.version, env: environment, }); - const model = new Model(git, askpass, context.globalState, outputChannelLogger, telemetryReporter); + const model = new Model(git, askpass, context.globalState, outputChannel, telemetryReporter); disposables.push(model); const onRepository = () => commands.executeCommand('setContext', 'gitOpenRepositoryCount', `${model.repositories.length}`); @@ -96,6 +81,8 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu model.onDidCloseRepository(onRepository, null, disposables); onRepository(); + outputChannel.appendLine(localize('using git', "{0} Using git {1} from {2}", logTimestamp(), info.version, info.path)); + const onOutput = (str: string) => { const lines = str.split(/\r?\n/mg); @@ -103,12 +90,12 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu lines.pop(); } - outputChannelLogger.log(lines.join('\n')); + outputChannel.appendLine(`${logTimestamp()} ${lines.join('\n')}`); }; git.onOutput.addListener('log', onOutput); disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput))); - const cc = new CommandCenter(git, model, outputChannelLogger, telemetryReporter); + const cc = new CommandCenter(git, model, outputChannel, telemetryReporter); disposables.push( cc, new GitFileSystemProvider(model), @@ -117,9 +104,6 @@ async function createModel(context: ExtensionContext, outputChannelLogger: Outpu new GitTimelineProvider(model, cc) ); - // const postCommitCommandsProvider = new GitPostCommitCommandsProvider(); {{SQL CARBON TODO}} lewissanchez - Do we need this? - // model.registerPostCommitCommandsProvider(postCommitCommandsProvider); {{SQL CARBON TODO}} lewissanchez - Do we need this? - // checkGitVersion(info); {{SQL CARBON EDIT}} Don't check git version return model; @@ -178,8 +162,9 @@ export async function _activate(context: ExtensionContext): Promise Disposable.from(...disposables).dispose())); - const outputChannelLogger = new OutputChannelLogger(); - disposables.push(outputChannelLogger); + const outputChannel = window.createOutputChannel('Git'); + commands.registerCommand('git.showOutput', () => outputChannel.show()); + disposables.push(outputChannel); const { name, version, aiKey } = require('../package.json') as { name: string; version: string; aiKey: string }; const telemetryReporter = new TelemetryReporter(name, version, aiKey); @@ -193,12 +178,12 @@ export async function _activate(context: ExtensionContext): Promise workspace.getConfiguration('git', null).get('enabled') === true); const result = new GitExtensionImpl(); - eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannelLogger, telemetryReporter, disposables)); + eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannel, telemetryReporter, disposables)); return result; } try { - const model = await createModel(context, outputChannelLogger, telemetryReporter, disposables); + const model = await createModel(context, outputChannel, telemetryReporter, disposables); return new GitExtensionImpl(model); } catch (err) { if (!/Git installation not found/.test(err.message || '')) { @@ -209,9 +194,7 @@ export async function _activate(context: ExtensionContext): Promise(); readonly onDidOpenRepository: Event = this._onDidOpenRepository.event; @@ -106,17 +105,12 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand private _onDidRemoveRemoteSourcePublisher = new EventEmitter(); readonly onDidRemoveRemoteSourcePublisher = this._onDidRemoveRemoteSourcePublisher.event; - private postCommitCommandsProviders = new Set(); - - private _onDidChangePostCommitCommandsProviders = new EventEmitter(); - readonly onDidChangePostCommitCommandsProviders = this._onDidChangePostCommitCommandsProviders.event; - private showRepoOnHomeDriveRootWarning = true; private pushErrorHandlers = new Set(); private disposables: Disposable[] = []; - constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannelLogger: OutputChannelLogger, private telemetryReporter: TelemetryReporter) { + constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannel: OutputChannel, private telemetryReporter: TelemetryReporter) { workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables); window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables); workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables); @@ -149,7 +143,11 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand private async scanWorkspaceFolders(): Promise { const config = workspace.getConfiguration('git'); const autoRepositoryDetection = config.get('autoRepositoryDetection'); - this.outputChannelLogger.logTrace(`[swsf] Scan workspace sub folders. autoRepositoryDetection=${autoRepositoryDetection}`); + + // Log repository scan settings + if (Log.logLevel <= LogLevel.Trace) { + this.outputChannel.appendLine(`${logTimestamp()} Trace: autoRepositoryDetection="${autoRepositoryDetection}"`); + } if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'subFolders') { return; @@ -157,7 +155,6 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand await Promise.all((workspace.workspaceFolders || []).map(async folder => { const root = folder.uri.fsPath; - this.outputChannelLogger.logTrace(`[swsf] Workspace folder: ${root}`); // Workspace folder children const repositoryScanMaxDepth = (workspace.isTrusted ? workspace.getConfiguration('git', folder.uri) : config).get('repositoryScanMaxDepth', 1); @@ -167,25 +164,19 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand // Repository scan folders const scanPaths = (workspace.isTrusted ? workspace.getConfiguration('git', folder.uri) : config).get('scanRepositories') || []; - this.outputChannelLogger.logTrace(`[swsf] Workspace scan settings: repositoryScanMaxDepth=${repositoryScanMaxDepth}; repositoryScanIgnoredFolders=[${repositoryScanIgnoredFolders.join(', ')}]; scanRepositories=[${scanPaths.join(', ')}]`); - for (const scanPath of scanPaths) { if (scanPath === '.git') { - this.outputChannelLogger.logTrace('[swsf] \'.git\' not supported in \'git.scanRepositories\' setting.'); continue; } if (path.isAbsolute(scanPath)) { - const notSupportedMessage = localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting."); - this.outputChannelLogger.logWarning(notSupportedMessage); - console.warn(notSupportedMessage); + console.warn(localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting.")); continue; } subfolders.add(path.join(root, scanPath)); } - this.outputChannelLogger.logTrace(`[swsf] Workspace scan sub folders: [${[...subfolders].join(', ')}]`); await Promise.all([...subfolders].map(f => this.openRepository(f))); })); } @@ -256,7 +247,6 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand .filter(r => !(workspace.workspaceFolders || []).some(f => isDescendant(f.uri.fsPath, r!.repository.root))) as OpenRepository[]; openRepositoriesToDispose.forEach(r => r.dispose()); - this.outputChannelLogger.logTrace(`[swf] Scan workspace folders: [${possibleRepositoryFolders.map(p => p.uri.fsPath).join(', ')}]`); await Promise.all(possibleRepositoryFolders.map(p => this.openRepository(p.uri.fsPath))); } @@ -270,20 +260,17 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand .filter(({ root }) => workspace.getConfiguration('git', root).get('enabled') !== true) .map(({ repository }) => repository); - this.outputChannelLogger.logTrace(`[swf] Scan workspace folders: [${possibleRepositoryFolders.map(p => p.uri.fsPath).join(', ')}]`); possibleRepositoryFolders.forEach(p => this.openRepository(p.uri.fsPath)); openRepositoriesToDispose.forEach(r => r.dispose()); } private async onDidChangeVisibleTextEditors(editors: readonly TextEditor[]): Promise { if (!workspace.isTrusted) { - this.outputChannelLogger.logTrace('[svte] Workspace is not trusted.'); return; } const config = workspace.getConfiguration('git'); const autoRepositoryDetection = config.get('autoRepositoryDetection'); - this.outputChannelLogger.logTrace(`[svte] Scan visible text editors. autoRepositoryDetection=${autoRepositoryDetection}`); if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'openEditors') { return; @@ -299,20 +286,16 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand const repository = this.getRepository(uri); if (repository) { - this.outputChannelLogger.logTrace(`[svte] Repository for editor resource ${uri.fsPath} already exists: ${repository.root}`); return; } - this.outputChannelLogger.logTrace(`[svte] Open repository for editor resource ${uri.fsPath}`); await this.openRepository(path.dirname(uri.fsPath)); })); } @sequentialize async openRepository(repoPath: string): Promise { - this.outputChannelLogger.logTrace(`Opening repository: ${repoPath}`); if (this.getRepository(repoPath)) { - this.outputChannelLogger.logTrace(`Repository for path ${repoPath} already exists`); return; } @@ -320,7 +303,6 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand const enabled = config.get('enabled') === true; if (!enabled) { - this.outputChannelLogger.logTrace('Git is not enabled'); return; } @@ -330,7 +312,6 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand fs.accessSync(path.join(repoPath, 'HEAD'), fs.constants.F_OK); const result = await this.git.exec(repoPath, ['-C', repoPath, 'rev-parse', '--show-cdup']); if (result.stderr.trim() === '' && result.stdout.trim() === '') { - this.outputChannelLogger.logTrace(`Bare repository: ${repoPath}`); return; } } catch { @@ -345,15 +326,12 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand // case insensitive file systems // https://github.com/microsoft/vscode/issues/33498 const repositoryRoot = Uri.file(rawRoot).fsPath; - this.outputChannelLogger.logTrace(`Repository root: ${repositoryRoot}`); if (this.getRepository(repositoryRoot)) { - this.outputChannelLogger.logTrace(`Repository for path ${repositoryRoot} already exists`); return; } if (this.shouldRepositoryBeIgnored(rawRoot)) { - this.outputChannelLogger.logTrace(`Repository for path ${repositoryRoot} is ignored`); return; } @@ -369,19 +347,20 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand this.showRepoOnHomeDriveRootWarning = false; } - this.outputChannelLogger.logTrace(`Repository for path ${repositoryRoot} is on the root of the HOMEDRIVE`); return; } } const dotGit = await this.git.getRepositoryDotGit(repositoryRoot); - const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this, this.globalState, this.outputChannelLogger, this.telemetryReporter); + const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this.globalState, this.outputChannel, this.telemetryReporter); this.open(repository); repository.status(); // do not await this, we want SCM to know about the repo asap } catch (ex) { // noop - this.outputChannelLogger.logTrace(`Opening repository for path='${repoPath}' failed; ex=${ex}`); + if (Log.logLevel <= LogLevel.Trace) { + this.outputChannel.appendLine(`${logTimestamp()} Trace: Opening repository for path='${repoPath}' failed; ex=${ex}`); + } } } @@ -407,7 +386,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand } private open(repository: Repository): void { - this.outputChannelLogger.logInfo(`Open repository: ${repository.root}`); + this.outputChannel.appendLine(`${logTimestamp()} Open repository: ${repository.root}`); const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed); const disappearListener = onDidDisappearRepository(() => dispose()); @@ -464,7 +443,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand return; } - this.outputChannelLogger.logInfo(`Close repository: ${repository.root}`); + this.outputChannel.appendLine(`${logTimestamp()} Close repository: ${repository.root}`); openRepository.dispose(); } @@ -512,10 +491,6 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand return this.openRepositories.filter(r => r.repository === hint)[0]; } - if (hint instanceof ApiRepository) { - return this.openRepositories.filter(r => r.repository === hint.repository)[0]; - } - if (typeof hint === 'string') { hint = Uri.file(hint); } @@ -592,20 +567,6 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand return [...this.remoteSourcePublishers.values()]; } - registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): Disposable { - this.postCommitCommandsProviders.add(provider); - this._onDidChangePostCommitCommandsProviders.fire(); - - return toDisposable(() => { - this.postCommitCommandsProviders.delete(provider); - this._onDidChangePostCommitCommandsProviders.fire(); - }); - } - - getPostCommitCommandsProviders(): PostCommitCommandsProvider[] { - return [...this.postCommitCommandsProviders.values()]; - } - registerCredentialsProvider(provider: CredentialsProvider): Disposable { return this.askpass.registerCredentialsProvider(provider); } diff --git a/extensions/git/src/postCommitCommands.ts b/extensions/git/src/postCommitCommands.ts deleted file mode 100644 index 43028a8533..0000000000 --- a/extensions/git/src/postCommitCommands.ts +++ /dev/null @@ -1,32 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as nls from 'vscode-nls'; -import { Command, Disposable, Event } from 'vscode'; -import { PostCommitCommandsProvider } from './api/git'; - -export interface IPostCommitCommandsProviderRegistry { - readonly onDidChangePostCommitCommandsProviders: Event; - - getPostCommitCommandsProviders(): PostCommitCommandsProvider[]; - registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): Disposable; -} - -const localize = nls.loadMessageBundle(); - -export class GitPostCommitCommandsProvider implements PostCommitCommandsProvider { - getCommands(): Command[] { - return [ - { - command: 'git.push', - title: localize('scm secondary button commit and push', "Commit & Push") - }, - { - command: 'git.sync', - title: localize('scm secondary button commit and sync', "Commit & Sync") - }, - ]; - } -} diff --git a/extensions/git/src/protocolHandler.ts b/extensions/git/src/protocolHandler.ts index 228375b74e..3a82b3ab25 100644 --- a/extensions/git/src/protocolHandler.ts +++ b/extensions/git/src/protocolHandler.ts @@ -38,15 +38,7 @@ export class GitProtocolHandler implements UriHandler { let cloneUri: Uri; try { - let rawUri = Array.isArray(data.url) ? data.url[0] : data.url; - - // Handle SSH Uri - // Ex: git@github.com:microsoft/vscode.git - rawUri = rawUri.replace(/^(git@[^\/:]+)(:)/i, 'ssh://$1/'); - - cloneUri = Uri.parse(rawUri, true); - - // Validate against supported schemes + cloneUri = Uri.parse(Array.isArray(data.url) ? data.url[0] : data.url, true); if (!schemes.has(cloneUri.scheme.toLowerCase())) { throw new Error('Unsupported scheme.'); } diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index c03dd255ca..d2e39bdb47 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,8 +5,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import * as picomatch from 'picomatch'; -import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern } from 'vscode'; +import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern } from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; import * as nls from 'vscode-nls'; import { Branch, Change, ForcePushMode, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions, BranchQuery, FetchOptions } from './api/git'; @@ -15,14 +14,13 @@ import { debounce, memoize, throttle } from './decorators'; import { Commit, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions } from './git'; import { StatusBarCommands } from './statusbar'; import { toGitUri } from './uri'; -import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent, pathEquals, relativePath } from './util'; +import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, logTimestamp, onceEvent, pathEquals, relativePath } from './util'; import { IFileWatcher, watch } from './watch'; -import { LogLevel, OutputChannelLogger } from './log'; +import { Log, LogLevel } from './log'; import { IPushErrorHandlerRegistry } from './pushError'; import { ApiRepository } from './api/api1'; import { IRemoteSourcePublisherRegistry } from './remotePublisher'; import { ActionButtonCommand } from './actionButton'; -import { IPostCommitCommandsProviderRegistry } from './postCommitCommands'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); @@ -298,10 +296,6 @@ export class Resource implements SourceControlResourceState { const command = this._commandResolver.resolveChangeCommand(this); await commands.executeCommand(command.command, ...(command.arguments || [])); } - - clone() { - return new Resource(this._commandResolver, this._resourceGroupType, this._resourceUri, this._type, this._useIcons, this._renameResourceUri); - } } export const enum Operation { @@ -456,13 +450,6 @@ class ProgressManager { const onDidChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git', Uri.file(this.repository.root))); onDidChange(_ => this.updateEnablement()); this.updateEnablement(); - - this.repository.onDidChangeOperations(() => { - const commitInProgress = this.repository.operations.isRunning(Operation.Commit); - - this.repository.sourceControl.inputBox.enabled = !commitInProgress; - commands.executeCommand('setContext', 'commitInProgress', commitInProgress); - }); } private updateEnablement(): void { @@ -517,10 +504,10 @@ class FileEventLogger { constructor( private onWorkspaceWorkingTreeFileChange: Event, private onDotGitFileChange: Event, - private outputChannelLogger: OutputChannelLogger + private outputChannel: OutputChannel ) { - this.logLevelDisposable = outputChannelLogger.onDidChangeLogLevel(this.onDidChangeLogLevel, this); - this.onDidChangeLogLevel(outputChannelLogger.currentLogLevel); + this.logLevelDisposable = Log.onDidChangeLogLevel(this.onDidChangeLogLevel, this); + this.onDidChangeLogLevel(Log.logLevel); } private onDidChangeLogLevel(level: LogLevel): void { @@ -531,8 +518,8 @@ class FileEventLogger { } this.eventDisposable = combinedDisposable([ - this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannelLogger.logDebug(`[wt] Change: ${uri.fsPath}`)), - this.onDotGitFileChange(uri => this.outputChannelLogger.logDebug(`[.git] Change: ${uri.fsPath}`)) + this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannel.appendLine(`${logTimestamp()} [debug] [wt] Change: ${uri.fsPath}`)), + this.onDotGitFileChange(uri => this.outputChannel.appendLine(`${logTimestamp()} [debug] [.git] Change: ${uri.fsPath}`)) ]); } @@ -552,14 +539,14 @@ class DotGitWatcher implements IFileWatcher { constructor( private repository: Repository, - private outputChannelLogger: OutputChannelLogger + private outputChannel: OutputChannel ) { const rootWatcher = watch(repository.dotGit.path); this.disposables.push(rootWatcher); // Ignore changes to the "index.lock" file, and watchman fsmonitor hook (https://git-scm.com/docs/githooks#_fsmonitor_watchman) cookie files. // Watchman creates a cookie file inside the git directory whenever a query is run (https://facebook.github.io/watchman/docs/cookies.html). - const filteredRootWatcher = filterEvent(rootWatcher.event, uri => uri.scheme === 'file' && !/\/\.git(\/index\.lock)?$|\/\.watchman-cookie-/.test(uri.path)); + const filteredRootWatcher = filterEvent(rootWatcher.event, uri => !/\/\.git(\/index\.lock)?$|\/\.watchman-cookie-/.test(uri.path)); this.event = anyEvent(filteredRootWatcher, this.emitter.event); repository.onDidRunGitStatus(this.updateTransientWatchers, this, this.disposables); @@ -583,7 +570,9 @@ class DotGitWatcher implements IFileWatcher { this.transientDisposables.push(upstreamWatcher); upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables); } catch (err) { - this.outputChannelLogger.logWarning(`Failed to watch ref '${upstreamPath}', is most likely packed.`); + if (Log.logLevel <= LogLevel.Error) { + this.outputChannel.appendLine(`${logTimestamp()} Warning: Failed to watch ref '${upstreamPath}', is most likely packed.`); + } } } @@ -616,20 +605,11 @@ class ResourceCommandResolver { const title = this.getTitle(resource); if (!resource.leftUri) { - const bothModified = resource.type === Status.BOTH_MODIFIED; - if (resource.rightUri && workspace.getConfiguration('git').get('mergeEditor', false) && (bothModified || resource.type === Status.BOTH_ADDED)) { - return { - command: '_git.openMergeEditor', - title: localize('open.merge', "Open Merge"), - arguments: [resource.rightUri] - }; - } else { - return { - command: 'vscode.open', - title: localize('open', "Open"), - arguments: [resource.rightUri, { override: bothModified ? false : undefined }, title] - }; - } + return { + command: 'vscode.open', + title: localize('open', "Open"), + arguments: [resource.rightUri, { override: resource.type === Status.BOTH_MODIFIED ? false : undefined }, title] + }; } else { return { command: 'vscode.diff', @@ -869,7 +849,6 @@ export class Repository implements Disposable { private isRepositoryHuge: false | { limit: number } = false; private didWarnAboutLimit = false; - private isBranchProtectedMatcher: picomatch.Matcher | undefined; private resourceCommandResolver = new ResourceCommandResolver(this); private disposables: Disposable[] = []; @@ -877,9 +856,8 @@ export class Repository implements Disposable { private readonly repository: BaseRepository, private pushErrorHandlerRegistry: IPushErrorHandlerRegistry, remoteSourcePublisherRegistry: IRemoteSourcePublisherRegistry, - postCommitCommandsProviderRegistry: IPostCommitCommandsProviderRegistry, globalState: Memento, - outputChannelLogger: OutputChannelLogger, + outputChannel: OutputChannel, private telemetryReporter: TelemetryReporter ) { const repositoryWatcher = workspace.createFileSystemWatcher(new RelativePattern(Uri.file(repository.root), '**')); @@ -891,11 +869,13 @@ export class Repository implements Disposable { let onRepositoryDotGitFileChange: Event; try { - const dotGitFileWatcher = new DotGitWatcher(this, outputChannelLogger); + const dotGitFileWatcher = new DotGitWatcher(this, outputChannel); onRepositoryDotGitFileChange = dotGitFileWatcher.event; this.disposables.push(dotGitFileWatcher); } catch (err) { - outputChannelLogger.logError(`Failed to watch path:'${this.dotGit.path}' or commonPath:'${this.dotGit.commonPath}', reverting to legacy API file watched. Some events might be lost.\n${err.stack || err}`); + if (Log.logLevel <= LogLevel.Error) { + outputChannel.appendLine(`${logTimestamp()} Failed to watch path:'${this.dotGit.path}' or commonPath:'${this.dotGit.commonPath}', reverting to legacy API file watched. Some events might be lost.\n${err.stack || err}`); + } onRepositoryDotGitFileChange = filterEvent(onRepositoryFileChange, uri => /\.git($|\/)/.test(uri.path)); } @@ -909,7 +889,7 @@ export class Repository implements Disposable { // Relevate repository changes should trigger virtual document change events onRepositoryDotGitFileChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables); - this.disposables.push(new FileEventLogger(onRepositoryWorkingTreeFileChange, onRepositoryDotGitFileChange, outputChannelLogger)); + this.disposables.push(new FileEventLogger(onRepositoryWorkingTreeFileChange, onRepositoryDotGitFileChange, outputChannel)); const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); @@ -936,19 +916,13 @@ export class Repository implements Disposable { onConfigListener(updateIndexGroupVisibility, this, this.disposables); updateIndexGroupVisibility(); - workspace.onDidChangeConfiguration(e => { - if (e.affectsConfiguration('git.mergeEditor')) { - this.mergeGroup.resourceStates = this.mergeGroup.resourceStates.map(r => r.clone()); - } - }, undefined, this.disposables); - filterEvent(workspace.onDidChangeConfiguration, e => - e.affectsConfiguration('git.branchProtection', root) - || e.affectsConfiguration('git.branchSortOrder', root) + e.affectsConfiguration('git.branchSortOrder', root) || e.affectsConfiguration('git.untrackedChanges', root) || e.affectsConfiguration('git.ignoreSubmodules', root) || e.affectsConfiguration('git.openDiffOnClick', root) - || e.affectsConfiguration('git.showActionButton', root) + || e.affectsConfiguration('git.rebaseWhenSync', root) + || e.affectsConfiguration('git.showUnpublishedCommitsButton', root) )(this.updateModelState, this, this.disposables); const updateInputBoxVisibility = () => { @@ -989,16 +963,12 @@ export class Repository implements Disposable { } }, null, this.disposables); - const onDidChangeBranchProtection = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.branchProtection', root)); - onDidChangeBranchProtection(this.updateBranchProtectionMatcher, this, this.disposables); - this.updateBranchProtectionMatcher(); - const statusBar = new StatusBarCommands(this, remoteSourcePublisherRegistry); this.disposables.push(statusBar); statusBar.onDidChange(() => this._sourceControl.statusBarCommands = statusBar.commands, null, this.disposables); this._sourceControl.statusBarCommands = statusBar.commands; - const actionButton = new ActionButtonCommand(this, postCommitCommandsProviderRegistry); + const actionButton = new ActionButtonCommand(this); this.disposables.push(actionButton); actionButton.onDidChange(() => this._sourceControl.actionButton = actionButton.button); this._sourceControl.actionButton = actionButton.button; @@ -1044,7 +1014,7 @@ export class Repository implements Disposable { } let lineNumber = 0; - let start = 0; + let start = 0, end; let match: RegExpExecArray | null; const regex = /\r?\n/g; @@ -1053,7 +1023,7 @@ export class Repository implements Disposable { lineNumber++; } - const end = match ? match.index : text.length; + end = match ? match.index : text.length; const line = text.substring(start, end); @@ -1297,7 +1267,7 @@ export class Repository implements Disposable { }); } - closeDiffEditors(indexResources: string[] | undefined, workingTreeResources: string[] | undefined, ignoreSetting: boolean = false): void { + closeDiffEditors(indexResources: string[], workingTreeResources: string[], ignoreSetting: boolean = false): void { const config = workspace.getConfiguration('git', Uri.file(this.root)); if (!config.get('closeDiffOnOperation', false) && !ignoreSetting) { return; } @@ -1306,11 +1276,11 @@ export class Repository implements Disposable { for (const tab of window.tabGroups.all.map(g => g.tabs).flat()) { const { input } = tab; if (input instanceof TabInputTextDiff || input instanceof TabInputNotebookDiff) { - if (input.modified.scheme === 'git' && (indexResources === undefined || indexResources.some(r => pathEquals(r, input.modified.fsPath)))) { + if (input.modified.scheme === 'git' && indexResources.some(r => pathEquals(r, input.modified.fsPath))) { // Index diffEditorTabsToClose.push(tab); } - if (input.modified.scheme === 'file' && input.original.scheme === 'git' && (workingTreeResources === undefined || workingTreeResources.some(r => pathEquals(r, input.modified.fsPath)))) { + if (input.modified.scheme === 'file' && input.original.scheme === 'git' && workingTreeResources.some(r => pathEquals(r, input.modified.fsPath))) { // Working Tree diffEditorTabsToClose.push(tab); } @@ -1416,15 +1386,15 @@ export class Repository implements Disposable { } @throttle - async fetchAll(cancellationToken?: CancellationToken): Promise { - await this._fetch({ all: true, cancellationToken }); + async fetchAll(): Promise { + await this._fetch({ all: true }); } async fetch(options: FetchOptions): Promise { await this._fetch(options); } - private async _fetch(options: { remote?: string; ref?: string; all?: boolean; prune?: boolean; depth?: number; silent?: boolean; cancellationToken?: CancellationToken } = {}): Promise { + private async _fetch(options: { remote?: string; ref?: string; all?: boolean; prune?: boolean; depth?: number; silent?: boolean } = {}): Promise { if (!options.prune) { const config = workspace.getConfiguration('git', Uri.file(this.root)); const prune = config.get('pruneOnFetch'); @@ -1469,7 +1439,7 @@ export class Repository implements Disposable { // When fetchOnPull is enabled, fetch all branches when pulling if (fetchOnPull) { - await this.fetchAll(); + await this.repository.fetch({ all: true }); } if (await this.checkIfMaybeRebased(this.HEAD?.name)) { @@ -1509,8 +1479,13 @@ export class Repository implements Disposable { } @throttle - sync(head: Branch, rebase: boolean): Promise { - return this._sync(head, rebase); + sync(head: Branch): Promise { + return this._sync(head, false); + } + + @throttle + async syncRebase(head: Branch): Promise { + return this._sync(head, true); } private async _sync(head: Branch, rebase: boolean): Promise { @@ -1535,7 +1510,7 @@ export class Repository implements Disposable { const fn = async (cancellationToken?: CancellationToken) => { // When fetchOnPull is enabled, fetch all branches when pulling if (fetchOnPull) { - await this.fetchAll(cancellationToken); + await this.repository.fetch({ all: true, cancellationToken }); } if (await this.checkIfMaybeRebased(this.HEAD?.name)) { @@ -1893,10 +1868,9 @@ export class Repository implements Disposable { if (didHitLimit) { /* __GDPR__ "statusLimit" : { - "owner": "lszomoru", - "ignoreSubmodules": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "Setting indicating whether submodules are ignored" }, - "limit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Setting indicating the limit of status entries" }, - "statusLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "comment": "Total number of status entries" } + "ignoreSubmodules": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "limit": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, + "statusLength": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } } */ this.telemetryReporter.sendTelemetryEvent('statusLimit', { ignoreSubmodules: String(ignoreSubmodules) }, { limit, statusLength }); @@ -2028,9 +2002,6 @@ export class Repository implements Disposable { // set count badge this.setCountBadge(); - // set mergeChanges context - commands.executeCommand('setContext', 'git.mergeChanges', merge.map(item => item.resourceUri.toString())); - this._onDidChangeStatus.fire(); this._sourceControl.commitTemplate = await this.getInputTemplate(); @@ -2217,21 +2188,6 @@ export class Repository implements Disposable { } } - private updateBranchProtectionMatcher(): void { - const scopedConfig = workspace.getConfiguration('git', Uri.file(this.repository.root)); - const branchProtectionGlobs = scopedConfig.get('branchProtection')!.map(bp => bp.trim()).filter(bp => bp !== ''); - - if (branchProtectionGlobs.length === 0) { - this.isBranchProtectedMatcher = undefined; - } else { - this.isBranchProtectedMatcher = picomatch(branchProtectionGlobs); - } - } - - public isBranchProtected(name: string = this.HEAD?.name ?? ''): boolean { - return this.isBranchProtectedMatcher ? this.isBranchProtectedMatcher(name) : false; - } - dispose(): void { this.disposables = dispose(this.disposables); } diff --git a/extensions/git/src/staging.ts b/extensions/git/src/staging.ts index 1a478436ac..0605fc1b3b 100644 --- a/extensions/git/src/staging.ts +++ b/extensions/git/src/staging.ts @@ -9,7 +9,7 @@ export function applyLineChanges(original: TextDocument, modified: TextDocument, const result: string[] = []; let currentLine = 0; - for (const diff of diffs) { + for (let diff of diffs) { const isInsertion = diff.originalEndLineNumber === 0; const isDeletion = diff.modifiedEndLineNumber === 0; diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index a178f4c2c1..0e41d6ee87 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -24,8 +24,7 @@ class CheckoutStatusBar { get command(): Command | undefined { const rebasing = !!this.repository.rebaseCommit; - const isBranchProtected = this.repository.isBranchProtected(); - const title = `${isBranchProtected ? '$(lock)' : '$(git-branch)'} ${this.repository.headLabel}${rebasing ? ` (${localize('rebasing', 'Rebasing')})` : ''}`; + const title = `$(git-branch) ${this.repository.headLabel}${rebasing ? ` (${localize('rebasing', 'Rebasing')})` : ''}`; return { command: 'git.checkout', @@ -145,7 +144,10 @@ class SyncStatusBar { text += this.repository.syncLabel; } - command = 'git.sync'; + const config = workspace.getConfiguration('git', Uri.file(this.repository.root)); + const rebaseWhenSync = config.get('rebaseWhenSync'); + + command = rebaseWhenSync ? 'git.syncRebase' : 'git.sync'; tooltip = this.repository.syncTooltip; } else { icon = '$(cloud-upload)'; diff --git a/extensions/git/src/terminal.ts b/extensions/git/src/terminal.ts index b473152056..780d52eb49 100644 --- a/extensions/git/src/terminal.ts +++ b/extensions/git/src/terminal.ts @@ -6,15 +6,27 @@ import { ExtensionContext, workspace } from 'vscode'; import { filterEvent, IDisposable } from './util'; -export interface ITerminalEnvironmentProvider { - getTerminalEnv(): { [key: string]: string }; -} - export class TerminalEnvironmentManager { private readonly disposable: IDisposable; - constructor(private readonly context: ExtensionContext, private readonly envProviders: (ITerminalEnvironmentProvider | undefined)[]) { + private _enabled = false; + private set enabled(enabled: boolean) { + if (this._enabled === enabled) { + return; + } + + this._enabled = enabled; + this.context.environmentVariableCollection.clear(); + + if (enabled) { + for (const name of Object.keys(this.env)) { + this.context.environmentVariableCollection.replace(name, this.env[name]); + } + } + } + + constructor(private readonly context: ExtensionContext, private readonly env: { [key: string]: string }) { this.disposable = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git')) (this.refresh, this); @@ -23,19 +35,7 @@ export class TerminalEnvironmentManager { private refresh(): void { const config = workspace.getConfiguration('git', null); - this.context.environmentVariableCollection.clear(); - - if (!config.get('enabled', true)) { - return; - } - - for (const envProvider of this.envProviders) { - const terminalEnv = envProvider?.getTerminalEnv() ?? {}; - - for (const name of Object.keys(terminalEnv)) { - this.context.environmentVariableCollection.replace(name, terminalEnv[name]); - } - } + this.enabled = config.get('enabled', true) && config.get('terminalAuthentication', true); } dispose(): void { diff --git a/extensions/git/src/test/git.test.ts b/extensions/git/src/test/git.test.ts index 5d394abe54..137be34a41 100644 --- a/extensions/git/src/test/git.test.ts +++ b/extensions/git/src/test/git.test.ts @@ -205,7 +205,6 @@ john.doe@mail.com 1580811030 1580811031 8e5a374372b8393906c7e380dbb09349c5385554 -main,branch This is a commit message.\x00`; assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_SINGLE_PARENT), [{ @@ -216,7 +215,6 @@ This is a commit message.\x00`; authorName: 'John Doe', authorEmail: 'john.doe@mail.com', commitDate: new Date(1580811031000), - refNames: ['main', 'branch'], }]); }); @@ -227,7 +225,6 @@ john.doe@mail.com 1580811030 1580811031 8e5a374372b8393906c7e380dbb09349c5385554 df27d8c75b129ab9b178b386077da2822101b217 -main This is a commit message.\x00`; assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_MULTIPLE_PARENTS), [{ @@ -238,7 +235,6 @@ This is a commit message.\x00`; authorName: 'John Doe', authorEmail: 'john.doe@mail.com', commitDate: new Date(1580811031000), - refNames: ['main'], }]); }); @@ -249,7 +245,6 @@ john.doe@mail.com 1580811030 1580811031 -main This is a commit message.\x00`; assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_NO_PARENTS), [{ @@ -260,7 +255,6 @@ This is a commit message.\x00`; authorName: 'John Doe', authorEmail: 'john.doe@mail.com', commitDate: new Date(1580811031000), - refNames: ['main'], }]); }); }); diff --git a/extensions/git/src/uri.ts b/extensions/git/src/uri.ts index 7e3b2cf9a4..1731329fe0 100644 --- a/extensions/git/src/uri.ts +++ b/extensions/git/src/uri.ts @@ -51,14 +51,3 @@ export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Ur query: JSON.stringify(params) }); } - -/** - * Assuming `uri` is being merged it creates uris for `base`, `ours`, and `theirs` - */ -export function toMergeUris(uri: Uri): { base: Uri; ours: Uri; theirs: Uri } { - return { - base: toGitUri(uri, ':1'), - ours: toGitUri(uri, ':2'), - theirs: toGitUri(uri, ':3'), - }; -} diff --git a/extensions/git/src/util.ts b/extensions/git/src/util.ts index c7082cd41a..a6dc15399f 100644 --- a/extensions/git/src/util.ts +++ b/extensions/git/src/util.ts @@ -16,6 +16,10 @@ export function log(...args: any[]): void { console.log.apply(console, ['git:', ...args]); } +export function logTimestamp(): string { + return `[${new Date().toISOString()}]`; +} + export interface IDisposable { dispose(): void; } @@ -51,7 +55,9 @@ export function anyEvent(...events: Event[]): Event { return (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]) => { const result = combinedDisposable(events.map(event => event(i => listener.call(thisArgs, i)))); - disposables?.push(result); + if (disposables) { + disposables.push(result); + } return result; }; @@ -87,7 +93,7 @@ export function eventToPromise(event: Event): Promise { } export function once(fn: (...args: any[]) => any): (...args: any[]) => any { - const didRun = false; + let didRun = false; return (...args) => { if (didRun) { @@ -217,11 +223,11 @@ export async function grep(filename: string, pattern: RegExp): Promise export function readBytes(stream: Readable, bytes: number): Promise { return new Promise((complete, error) => { let done = false; - const buffer = Buffer.allocUnsafe(bytes); + let buffer = Buffer.allocUnsafe(bytes); let bytesRead = 0; stream.on('data', (data: Buffer) => { - const bytesToRead = Math.min(bytes - bytesRead, data.length); + let bytesToRead = Math.min(bytes - bytesRead, data.length); data.copy(buffer, bytesRead, 0, bytesToRead); bytesRead += bytesToRead; diff --git a/extensions/git/tsconfig.json b/extensions/git/tsconfig.json index c62c25401f..1399727505 100644 --- a/extensions/git/tsconfig.json +++ b/extensions/git/tsconfig.json @@ -14,7 +14,7 @@ "../../src/vscode-dts/vscode.proposed.scmActionButton.d.ts", "../../src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts", "../../src/vscode-dts/vscode.proposed.scmValidation.d.ts", - "../../src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts", + "../../src/vscode-dts/vscode.proposed.tabs.d.ts", "../../src/vscode-dts/vscode.proposed.timeline.d.ts", "../types/lib.textEncoder.d.ts" ] diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index f58d3d4b07..aaa2dd0edf 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -2,47 +2,6 @@ # yarn lockfile v1 -"@joaomoreno/unique-names-generator@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@joaomoreno/unique-names-generator/-/unique-names-generator-5.0.0.tgz#a67fe66e3d825c929fc97abfdf17fd80a72beab0" - integrity sha512-3kP6z7aoGEoM3tvhTBZioYa1QFkovOU8uxAlVclnZlXivwF/WTE5EcOzvoDdM+jtjJyWvCMDR1Q4RBjDqupD3A== - -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - "@tokenizer/token@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" @@ -70,23 +29,15 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== -"@types/picomatch@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" - integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== - "@types/which@^1.0.28": version "1.0.28" resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6" integrity sha1-AW44dim4gXvtZT/jLqtdESecjfY= -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.4.10": + version "0.4.10" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.4.10.tgz#be960c05bdcbea0933866346cf244acad6cac910" + integrity sha512-XgyUoWWRQExTmd9DynIIUQo1NPex/zIeetdUAXeBjVuW9ioojM1TcDaSqOa/5QLC7lx+oEXwSU1r0XSBgzyz6w== "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" @@ -107,6 +58,7 @@ file-type@16.5.4: strtok3 "^6.2.4" token-types "^4.1.1" + ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -116,7 +68,6 @@ inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -132,11 +83,6 @@ peek-readable@^4.1.0: resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== -picomatch@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" diff --git a/extensions/github-authentication/package.json b/extensions/github-authentication/package.json index a130c19992..7f7888de72 100644 --- a/extensions/github-authentication/package.json +++ b/extensions/github-authentication/package.json @@ -48,7 +48,7 @@ } } }, - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "main": "./out/extension.js", "browser": "./dist/browser/extension.js", "scripts": { @@ -61,9 +61,9 @@ "dependencies": { "node-fetch": "2.6.7", "uuid": "8.1.0", - "@vscode/extension-telemetry": "0.6.2", + "@vscode/extension-telemetry": "0.4.10", "vscode-nls": "^5.0.0", - "vscode-tas-client": "^0.1.47" + "vscode-tas-client": "^0.1.42" }, "devDependencies": { "@types/node": "16.x", diff --git a/extensions/github-authentication/src/common/utils.ts b/extensions/github-authentication/src/common/utils.ts index a11dc6fbdd..3be4c12909 100644 --- a/extensions/github-authentication/src/common/utils.ts +++ b/extensions/github-authentication/src/common/utils.ts @@ -51,7 +51,7 @@ export function promiseFromEvent( event: Event, adapter: PromiseAdapter = passthrough): { promise: Promise; cancel: EventEmitter } { let subscription: Disposable; - const cancel = new EventEmitter(); + let cancel = new EventEmitter(); return { promise: new Promise((resolve, reject) => { cancel.event(_ => reject('Cancelled')); diff --git a/extensions/github-authentication/src/github.ts b/extensions/github-authentication/src/github.ts index 7c917e6f34..7e55fc3a20 100644 --- a/extensions/github-authentication/src/github.ts +++ b/extensions/github-authentication/src/github.ts @@ -153,7 +153,8 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid const scopesSeen = new Set(); const sessionPromises = sessionData.map(async (session: SessionData) => { // For GitHub scope list, order doesn't matter so we immediately sort the scopes - const scopesStr = [...session.scopes].sort().join(' '); + const sortedScopes = session.scopes.sort(); + const scopesStr = sortedScopes.join(' '); if (scopesSeen.has(scopesStr)) { return undefined; } @@ -180,9 +181,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid : userInfo?.accountName ?? '', id: session.account?.id ?? userInfo?.id ?? '' }, - // we set this to session.scopes to maintain the original order of the scopes requested - // by the extension that called getSession() - scopes: session.scopes, + scopes: sortedScopes, accessToken: session.accessToken }; }); @@ -209,25 +208,22 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid public async createSession(scopes: string[]): Promise { try { - // For GitHub scope list, order doesn't matter so we use a sorted scope to determine - // if we've got a session already. - const sortedScopes = [...scopes].sort(); + // For GitHub scope list, order doesn't matter so we immediately sort the scopes + const sortedScopes = scopes.sort(); /* __GDPR__ "login" : { - "owner": "TylerLeonhardt", - "comment": "Used to determine how much usage the GitHub Auth Provider gets.", - "scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." } + "scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ this._telemetryReporter?.sendTelemetryEvent('login', { - scopes: JSON.stringify(scopes), + scopes: JSON.stringify(sortedScopes), }); const scopeString = sortedScopes.join(' '); const token = await this._githubServer.login(scopeString); - const session = await this.tokenToSession(token, scopes); + const session = await this.tokenToSession(token, sortedScopes); this.afterSessionLoad(session); const sessions = await this._sessionsPromise; @@ -248,14 +244,14 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid // If login was cancelled, do not notify user. if (e === 'Cancelled' || e.message === 'Cancelled') { /* __GDPR__ - "loginCancelled" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users cancel the login flow." } + "loginCancelled" : { } */ this._telemetryReporter?.sendTelemetryEvent('loginCancelled'); throw e; } /* __GDPR__ - "loginFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into an error login flow." } + "loginFailed" : { } */ this._telemetryReporter?.sendTelemetryEvent('loginFailed'); @@ -278,7 +274,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid public async removeSession(id: string) { try { /* __GDPR__ - "logout" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out of an account." } + "logout" : { } */ this._telemetryReporter?.sendTelemetryEvent('logout'); @@ -298,7 +294,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid } } catch (e) { /* __GDPR__ - "logoutFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often logging out of an account fails." } + "logoutFailed" : { } */ this._telemetryReporter?.sendTelemetryEvent('logoutFailed'); diff --git a/extensions/github-authentication/src/githubServer.ts b/extensions/github-authentication/src/githubServer.ts index 2ccf5e2530..c9460f211b 100644 --- a/extensions/github-authentication/src/githubServer.ts +++ b/extensions/github-authentication/src/githubServer.ts @@ -496,7 +496,6 @@ export class GitHubServer implements IGitHubServer { /* __GDPR__ "session" : { - "owner": "TylerLeonhardt", "isEdu": { "classification": "NonIdentifiableDemographicInfo", "purpose": "FeatureInsight" } } */ @@ -531,7 +530,6 @@ export class GitHubServer implements IGitHubServer { /* __GDPR__ "ghe-session" : { - "owner": "TylerLeonhardt", "version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ @@ -603,7 +601,6 @@ export class GitHubEnterpriseServer implements IGitHubServer { /* __GDPR__ "ghe-session" : { - "owner": "TylerLeonhardt", "version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } */ diff --git a/extensions/github-authentication/yarn.lock b/extensions/github-authentication/yarn.lock index f515adebd2..4a8e456dac 100644 --- a/extensions/github-authentication/yarn.lock +++ b/extensions/github-authentication/yarn.lock @@ -2,42 +2,6 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - "@types/node-fetch@^2.5.7": version "2.5.7" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" @@ -61,13 +25,10 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.4.10": + version "0.4.10" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.4.10.tgz#be960c05bdcbea0933866346cf244acad6cac910" + integrity sha512-XgyUoWWRQExTmd9DynIIUQo1NPex/zIeetdUAXeBjVuW9ioojM1TcDaSqOa/5QLC7lx+oEXwSU1r0XSBgzyz6w== asynckit@^0.4.0: version "0.4.0" @@ -126,10 +87,10 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" -tas-client@0.1.58: - version "0.1.58" - resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.58.tgz#67d66bf0e27df5276ebc751105e6ad47791c36d8" - integrity sha512-fOWii4wQXuo9Zl0oXgvjBzZWzKc5MmUR6XQWX93WU2c1SaP1plPo/zvXP8kpbZ9fvegFOHdapszYqMTRq/SRtg== +tas-client@0.1.45: + version "0.1.45" + resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.45.tgz#83bbf73f8458a0f527f9a389f7e1c37f63a64a76" + integrity sha512-IG9UmCpDbDPK23UByQ27rLybkRZYEx2eC9EkieXdwPKKjZPD2zPwfQmyGnZrZet4FUt3yj0ytkwz+liR9Nz/nA== dependencies: axios "^0.26.1" @@ -148,12 +109,12 @@ vscode-nls@^5.0.0: resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== -vscode-tas-client@^0.1.47: - version "0.1.63" - resolved "https://registry.yarnpkg.com/vscode-tas-client/-/vscode-tas-client-0.1.63.tgz#df89e67e9bf7ecb46471a0fb8a4a522d2aafad65" - integrity sha512-TY5TPyibzi6rNmuUB7eRVqpzLzNfQYrrIl/0/F8ukrrbzOrKVvS31hM3urE+tbaVrnT+TMYXL16GhX57vEowhA== +vscode-tas-client@^0.1.42: + version "0.1.47" + resolved "https://registry.yarnpkg.com/vscode-tas-client/-/vscode-tas-client-0.1.47.tgz#d66795cbbaa231aba659b6c40d43927d73596375" + integrity sha512-SlEPDi+0gwxor4ANzBtXwqROPQdQkClHeVJgnkvdDF5Xnl407htCsabTPAq4Di8muObORtLchqQS/k1ocaGDEg== dependencies: - tas-client "0.1.58" + tas-client "0.1.45" webidl-conversions@^3.0.0: version "3.0.1" diff --git a/extensions/github/package.json b/extensions/github/package.json index a5de87a74b..af7b544f59 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -25,33 +25,11 @@ "supported": true } }, - "enabledApiProposals": [ - "contribShareMenu", - "contribEditSessions" - ], "contributes": { "commands": [ { "command": "github.publish", "title": "Publish to GitHub" - }, - { - "command": "github.copyVscodeDevLink", - "title": "Copy vscode.dev Link" - }, - { - "command": "github.copyVscodeDevLinkFile", - "title": "Copy vscode.dev Link" - }, - { - "command": "github.openOnVscodeDev", - "title": "Open on vscode.dev" - } - ], - "continueEditSession": [ - { - "command": "github.openOnVscodeDev", - "when": "github.hasGitHubRepo" } ], "menus": { @@ -59,30 +37,6 @@ { "command": "github.publish", "when": "git-base.gitEnabled" - }, - { - "command": "github.copyVscodeDevLink", - "when": "false" - }, - { - "command": "github.copyVscodeDevLinkFile", - "when": "false" - }, - { - "command": "github.openOnVscodeDev", - "when": "false" - } - ], - "file/share": [ - { - "command": "github.copyVscodeDevLinkFile", - "when": "github.hasGitHubRepo" - } - ], - "editor/context/share": [ - { - "command": "github.copyVscodeDevLink", - "when": "github.hasGitHubRepo && resourceScheme != untitled" } ] }, diff --git a/extensions/github/package.nls.json b/extensions/github/package.nls.json index 2e4869a234..7e769b96d3 100644 --- a/extensions/github/package.nls.json +++ b/extensions/github/package.nls.json @@ -6,8 +6,6 @@ "welcome.publishFolder": { "message": "You can also directly publish this folder to a GitHub repository. Once published, you'll have access to source control features powered by git and GitHub.\n[$(github) Publish to GitHub](command:github.publish)", "comment": [ - "{Locked='$(github)'}", - "Do not translate '$(github)'. It will be rendered as an icon", "{Locked='](command:github.publish'}", "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" @@ -16,8 +14,6 @@ "welcome.publishWorkspaceFolder": { "message": "You can also directly publish a workspace folder to a GitHub repository. Once published, you'll have access to source control features powered by git and GitHub.\n[$(github) Publish to GitHub](command:github.publish)", "comment": [ - "{Locked='$(github)'}", - "Do not translate '$(github)'. It will be rendered as an icon", "{Locked='](command:github.publish'}", "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" diff --git a/extensions/github/src/auth.ts b/extensions/github/src/auth.ts index d143423ccd..2f66e40295 100644 --- a/extensions/github/src/auth.ts +++ b/extensions/github/src/auth.ts @@ -24,7 +24,7 @@ function getAgent(url: string | undefined = process.env.HTTPS_PROXY): Agent { } } -const scopes = ['repo', 'workflow', 'user:email', 'read:user']; +const scopes = ['repo', 'workflow']; export async function getSession(): Promise { return await authentication.getSession('github', scopes, { createIfNone: true }); diff --git a/extensions/github/src/commands.ts b/extensions/github/src/commands.ts index bd7b0a48d4..71e6eb7756 100644 --- a/extensions/github/src/commands.ts +++ b/extensions/github/src/commands.ts @@ -7,32 +7,6 @@ import * as vscode from 'vscode'; import { API as GitAPI } from './typings/git'; import { publishRepository } from './publish'; import { DisposableStore } from './util'; -import { getPermalink } from './links'; - -function getVscodeDevHost(): string { - return `https://${vscode.env.appName.toLowerCase().includes('insiders') ? 'insiders.' : ''}vscode.dev/github`; -} - -async function copyVscodeDevLink(gitAPI: GitAPI, useSelection: boolean) { - try { - const permalink = getPermalink(gitAPI, useSelection, getVscodeDevHost()); - if (permalink) { - return vscode.env.clipboard.writeText(permalink); - } - } catch (err) { - vscode.window.showErrorMessage(err.message); - } -} - -async function openVscodeDevLink(gitAPI: GitAPI): Promise { - try { - const permalink = getPermalink(gitAPI, true, getVscodeDevHost()); - return permalink ? vscode.Uri.parse(permalink) : undefined; - } catch (err) { - vscode.window.showErrorMessage(err.message); - return undefined; - } -} export function registerCommands(gitAPI: GitAPI): vscode.Disposable { const disposables = new DisposableStore(); @@ -45,17 +19,5 @@ export function registerCommands(gitAPI: GitAPI): vscode.Disposable { } })); - disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLink', async () => { - return copyVscodeDevLink(gitAPI, true); - })); - - disposables.add(vscode.commands.registerCommand('github.copyVscodeDevLinkFile', async () => { - return copyVscodeDevLink(gitAPI, false); - })); - - disposables.add(vscode.commands.registerCommand('github.openOnVscodeDev', async () => { - return openVscodeDevLink(gitAPI); - })); - return disposables; } diff --git a/extensions/github/src/extension.ts b/extensions/github/src/extension.ts index cdb8e6c299..aa1697e83e 100644 --- a/extensions/github/src/extension.ts +++ b/extensions/github/src/extension.ts @@ -5,10 +5,10 @@ import { commands, Disposable, ExtensionContext, extensions } from 'vscode'; import { GithubRemoteSourceProvider } from './remoteSourceProvider'; -import { API, GitExtension } from './typings/git'; +import { GitExtension } from './typings/git'; import { registerCommands } from './commands'; import { GithubCredentialProviderManager } from './credentialProvider'; -import { DisposableStore, repositoryHasGitHubRemote } from './util'; +import { DisposableStore } from './util'; import { GithubPushErrorHandler } from './pushErrorHandler'; import { GitBaseExtension } from './typings/git-base'; import { GithubRemoteSourcePublisher } from './remoteSourcePublisher'; @@ -48,21 +48,6 @@ function initializeGitBaseExtension(): Disposable { return disposables; } -function setGitHubContext(gitAPI: API, disposables: DisposableStore) { - if (gitAPI.repositories.find(repo => repositoryHasGitHubRemote(repo))) { - commands.executeCommand('setContext', 'github.hasGitHubRepo', true); - } else { - const openRepoDisposable = gitAPI.onDidOpenRepository(async e => { - await e.status(); - if (repositoryHasGitHubRemote(e)) { - commands.executeCommand('setContext', 'github.hasGitHubRepo', true); - openRepoDisposable.dispose(); - } - }); - disposables.add(openRepoDisposable); - } -} - function initializeGitExtension(): Disposable { const disposables = new DisposableStore(); @@ -79,7 +64,6 @@ function initializeGitExtension(): Disposable { disposables.add(new GithubCredentialProviderManager(gitAPI)); disposables.add(gitAPI.registerPushErrorHandler(new GithubPushErrorHandler())); disposables.add(gitAPI.registerRemoteSourcePublisher(new GithubRemoteSourcePublisher(gitAPI))); - setGitHubContext(gitAPI, disposables); commands.executeCommand('setContext', 'git-base.gitEnabled', true); } else { diff --git a/extensions/github/src/links.ts b/extensions/github/src/links.ts deleted file mode 100644 index 51e88652f4..0000000000 --- a/extensions/github/src/links.ts +++ /dev/null @@ -1,135 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { API as GitAPI, Repository } from './typings/git'; -import { getRepositoryFromUrl } from './util'; - -export function isFileInRepo(repository: Repository, file: vscode.Uri): boolean { - return file.path.toLowerCase() === repository.rootUri.path.toLowerCase() || - (file.path.toLowerCase().startsWith(repository.rootUri.path.toLowerCase()) && - file.path.substring(repository.rootUri.path.length).startsWith('/')); -} - -export function getRepositoryForFile(gitAPI: GitAPI, file: vscode.Uri): Repository | undefined { - for (const repository of gitAPI.repositories) { - if (isFileInRepo(repository, file)) { - return repository; - } - } - return undefined; -} - -enum LinkType { - File = 1, - Notebook = 2 -} - -interface IFilePosition { - type: LinkType.File; - uri: vscode.Uri; - range: vscode.Range | undefined; -} - -interface INotebookPosition { - type: LinkType.Notebook; - uri: vscode.Uri; - cellIndex: number; - range: vscode.Range | undefined; -} - -function getFileAndPosition(): IFilePosition | INotebookPosition | undefined { - let uri: vscode.Uri | undefined; - let range: vscode.Range | undefined; - if (vscode.window.activeTextEditor) { - uri = vscode.window.activeTextEditor.document.uri; - - if (uri.scheme === 'vscode-notebook-cell' && vscode.window.activeNotebookEditor?.notebook.uri.fsPath === uri.fsPath) { - // if the active editor is a notebook editor and the focus is inside any a cell text editor - // generate deep link for text selection for the notebook cell. - const cell = vscode.window.activeNotebookEditor.notebook.getCells().find(cell => cell.document.uri.fragment === uri?.fragment); - const cellIndex = cell?.index ?? vscode.window.activeNotebookEditor.selection.start; - const range = cell !== undefined ? vscode.window.activeTextEditor.selection : undefined; - return { type: LinkType.Notebook, uri, cellIndex, range }; - } else { - // the active editor is a text editor - range = vscode.window.activeTextEditor.selection; - return { type: LinkType.File, uri, range }; - } - } - - if (vscode.window.activeNotebookEditor) { - // if the active editor is a notebook editor but the focus is not inside any cell text editor, generate deep link for the cell selection in the notebook document. - return { type: LinkType.Notebook, uri: vscode.window.activeNotebookEditor.notebook.uri, cellIndex: vscode.window.activeNotebookEditor.selection.start, range: undefined }; - } - - return undefined; -} - -function rangeString(range: vscode.Range | undefined) { - if (!range) { - return ''; - } - let hash = `#L${range.start.line + 1}`; - if (range.start.line !== range.end.line) { - hash += `-L${range.end.line + 1}`; - } - return hash; -} - -export function notebookCellRangeString(index: number | undefined, range: vscode.Range | undefined) { - if (index === undefined) { - return ''; - } - - if (!range) { - return `#C${index + 1}`; - } - - let hash = `#C${index + 1}:L${range.start.line + 1}`; - if (range.start.line !== range.end.line) { - hash += `-L${range.end.line + 1}`; - } - return hash; -} - -export function getPermalink(gitAPI: GitAPI, useSelection: boolean, hostPrefix?: string): string | undefined { - hostPrefix = hostPrefix ?? 'https://github.com'; - const fileAndPosition = getFileAndPosition(); - if (!fileAndPosition) { - return; - } - const uri = fileAndPosition.uri; - - // Use the first repo if we cannot determine a repo from the uri. - const gitRepo = (uri ? getRepositoryForFile(gitAPI, uri) : gitAPI.repositories[0]) ?? gitAPI.repositories[0]; - if (!gitRepo) { - return; - } - let repo: { owner: string; repo: string } | undefined; - gitRepo.state.remotes.find(remote => { - if (remote.fetchUrl) { - const foundRepo = getRepositoryFromUrl(remote.fetchUrl); - if (foundRepo && (remote.name === gitRepo.state.HEAD?.upstream?.remote)) { - repo = foundRepo; - return; - } else if (foundRepo && !repo) { - repo = foundRepo; - } - } - return; - }); - if (!repo) { - return; - } - - const commitHash = (gitRepo.state.HEAD?.ahead === 0) ? `/blob/${gitRepo.state.HEAD?.commit}` : ''; - const fileSegments = fileAndPosition.type === LinkType.File - ? (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${rangeString(fileAndPosition.range)}` : '') - : (useSelection ? `${uri.path.substring(gitRepo.rootUri.path.length)}${notebookCellRangeString(fileAndPosition.cellIndex, fileAndPosition.range)}` : ''); - - return `${hostPrefix}/${repo.owner}/${repo.repo}${commitHash - }${fileSegments}`; -} diff --git a/extensions/github/src/pushErrorHandler.ts b/extensions/github/src/pushErrorHandler.ts index 435abf3d62..c1083a563c 100644 --- a/extensions/github/src/pushErrorHandler.ts +++ b/extensions/github/src/pushErrorHandler.ts @@ -21,9 +21,8 @@ export function isInCodespaces(): boolean { async function handlePushError(repository: Repository, remote: Remote, refspec: string, owner: string, repo: string): Promise { const yes = localize('create a fork', "Create Fork"); const no = localize('no', "No"); - const askFork = localize('fork', "You don't have permissions to push to '{0}/{1}' on GitHub. Would you like to create a fork and push to it instead?", owner, repo); - const answer = await window.showInformationMessage(askFork, yes, no); + const answer = await window.showInformationMessage(localize('fork', "You don't have permissions to push to '{0}/{1}' on GitHub. Would you like to create a fork and push to it instead?", owner, repo), yes, no); if (answer !== yes) { return; } @@ -103,19 +102,18 @@ async function handlePushError(repository: Repository, remote: Remote, refspec: let title = `Update ${remoteName}`; const head = repository.state.HEAD?.name; - let body: string | undefined; - if (head) { const commit = await repository.getCommit(head); - title = commit.message.split('\n')[0]; - body = commit.message.slice(title.length + 1).trim(); + title = commit.message.replace(/\n.*$/m, ''); } + let body: string | undefined; + const templates = await findPullRequestTemplates(repository.rootUri); if (templates.length > 0) { templates.sort((a, b) => a.path.localeCompare(b.path)); - const template = await pickPullRequestTemplate(repository.rootUri, templates); + const template = await pickPullRequestTemplate(templates); if (template) { body = new TextDecoder('utf-8').decode(await workspace.fs.readFile(template)); @@ -192,8 +190,8 @@ export async function findPullRequestTemplates(repositoryRootUri: Uri): Promise< return results.flatMap(x => x.status === 'fulfilled' && x.value || []); } -export async function pickPullRequestTemplate(repositoryRootUri: Uri, templates: Uri[]): Promise { - const quickPickItemFromUri = (x: Uri) => ({ label: path.relative(repositoryRootUri.path, x.path), template: x }); +export async function pickPullRequestTemplate(templates: Uri[]): Promise { + const quickPickItemFromUri = (x: Uri) => ({ label: x.path, template: x }); const quickPickItems = [ { label: localize('no pr template', "No template"), @@ -203,8 +201,7 @@ export async function pickPullRequestTemplate(repositoryRootUri: Uri, templates: ...templates.map(quickPickItemFromUri) ]; const quickPickOptions: QuickPickOptions = { - placeHolder: localize('select pr template', "Select the Pull Request template"), - ignoreFocusOut: true + placeHolder: localize('select pr template', "Select the Pull Request template") }; const pickedTemplate = await window.showQuickPick(quickPickItems, quickPickOptions); return pickedTemplate?.template; @@ -222,7 +219,7 @@ export class GithubPushErrorHandler implements PushErrorHandler { return false; } - const match = /^(?:https:\/\/github\.com\/|git@github\.com:)([^\/]+)\/([^\/.]+)/i.exec(remoteUrl); + const match = /^(?:https:\/\/github\.com\/|git@github\.com:)([^/]+)\/([^/.]+)(?:\.git)?$/i.exec(remoteUrl); if (!match) { return false; } diff --git a/extensions/github/src/remoteSourceProvider.ts b/extensions/github/src/remoteSourceProvider.ts index a7e8d231b6..5da7bca356 100644 --- a/extensions/github/src/remoteSourceProvider.ts +++ b/extensions/github/src/remoteSourceProvider.ts @@ -7,7 +7,17 @@ import { workspace } from 'vscode'; import { RemoteSourceProvider, RemoteSource } from './typings/git-base'; import { getOctokit } from './auth'; import { Octokit } from '@octokit/rest'; -import { getRepositoryFromQuery, getRepositoryFromUrl } from './util'; + +function getRepositoryFromUrl(url: string): { owner: string; repo: string } | undefined { + const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\.git/i.exec(url) + || /^git@github\.com:([^/]+)\/([^/]+)\.git/i.exec(url); + return match ? { owner: match[1], repo: match[2] } : undefined; +} + +function getRepositoryFromQuery(query: string): { owner: string; repo: string } | undefined { + const match = /^([^/]+)\/([^/]+)$/i.exec(query); + return match ? { owner: match[1], repo: match[2] } : undefined; +} function asRemoteSource(raw: any): RemoteSource { const protocol = workspace.getConfiguration('github').get<'https' | 'ssh'>('gitProtocol'); @@ -97,7 +107,7 @@ export class GithubRemoteSourceProvider implements RemoteSourceProvider { let page = 1; while (true) { - const res = await octokit.repos.listBranches({ ...repository, per_page: 100, page }); + let res = await octokit.repos.listBranches({ ...repository, per_page: 100, page }); if (res.data.length === 0) { break; diff --git a/extensions/github/src/test/github.test.ts b/extensions/github/src/test/github.test.ts index cac622810d..c9da68ed30 100644 --- a/extensions/github/src/test/github.test.ts +++ b/extensions/github/src/test/github.test.ts @@ -18,15 +18,15 @@ suite('github smoke test', function () { test('should find all templates', async function () { const expectedValuesSorted = [ - 'PULL_REQUEST_TEMPLATE/a.md', - 'PULL_REQUEST_TEMPLATE/b.md', - 'docs/PULL_REQUEST_TEMPLATE.md', - 'docs/PULL_REQUEST_TEMPLATE/a.md', - 'docs/PULL_REQUEST_TEMPLATE/b.md', - '.github/PULL_REQUEST_TEMPLATE.md', - '.github/PULL_REQUEST_TEMPLATE/a.md', - '.github/PULL_REQUEST_TEMPLATE/b.md', - 'PULL_REQUEST_TEMPLATE.md' + '/PULL_REQUEST_TEMPLATE/a.md', + '/PULL_REQUEST_TEMPLATE/b.md', + '/docs/PULL_REQUEST_TEMPLATE.md', + '/docs/PULL_REQUEST_TEMPLATE/a.md', + '/docs/PULL_REQUEST_TEMPLATE/b.md', + '/.github/PULL_REQUEST_TEMPLATE.md', + '/.github/PULL_REQUEST_TEMPLATE/a.md', + '/.github/PULL_REQUEST_TEMPLATE/b.md', + '/PULL_REQUEST_TEMPLATE.md' ]; expectedValuesSorted.sort(); @@ -43,7 +43,7 @@ suite('github smoke test', function () { const template1 = Uri.file("some-imaginary-template-1"); const templates = [template0, template1]; - const pick = pickPullRequestTemplate(Uri.file("/"), templates); + const pick = pickPullRequestTemplate(templates); await commands.executeCommand('workbench.action.quickOpenSelectNext'); await commands.executeCommand('workbench.action.quickOpenSelectNext'); @@ -55,7 +55,7 @@ suite('github smoke test', function () { test('selecting first quick-pick item should return undefined', async () => { const templates = [Uri.file("some-imaginary-file")]; - const pick = pickPullRequestTemplate(Uri.file("/"), templates); + const pick = pickPullRequestTemplate(templates); await commands.executeCommand('workbench.action.quickOpenSelectNext'); await commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); diff --git a/extensions/github/src/util.ts b/extensions/github/src/util.ts index 7069d1e53b..ea41cc6173 100644 --- a/extensions/github/src/util.ts +++ b/extensions/github/src/util.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { Repository } from './typings/git'; export class DisposableStore { @@ -22,18 +21,3 @@ export class DisposableStore { this.disposables.clear(); } } - -export function getRepositoryFromUrl(url: string): { owner: string; repo: string } | undefined { - const match = /^https:\/\/github\.com\/([^/]+)\/([^/]+?)(\.git)?$/i.exec(url) - || /^git@github\.com:([^/]+)\/([^/]+?)(\.git)?$/i.exec(url); - return match ? { owner: match[1], repo: match[2] } : undefined; -} - -export function getRepositoryFromQuery(query: string): { owner: string; repo: string } | undefined { - const match = /^([^/]+)\/([^/]+)$/i.exec(query); - return match ? { owner: match[1], repo: match[2] } : undefined; -} - -export function repositoryHasGitHubRemote(repository: Repository) { - return !!repository.state.remotes.find(remote => remote.fetchUrl ? getRepositoryFromUrl(remote.fetchUrl) : undefined); -} diff --git a/extensions/html-language-features/client/src/languageParticipants.ts b/extensions/html-language-features/client/src/languageParticipants.ts deleted file mode 100644 index 005299308d..0000000000 --- a/extensions/html-language-features/client/src/languageParticipants.ts +++ /dev/null @@ -1,87 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { DocumentSelector } from 'vscode-languageclient'; -import { Event, EventEmitter, extensions } from 'vscode'; - -/** - * HTML language participant contribution. - */ -interface LanguageParticipantContribution { - /** - * The id of the language which participates with the HTML language server. - */ - languageId: string; - /** - * true if the language activates the auto insertion and false otherwise. - */ - autoInsert?: boolean; -} - -export interface LanguageParticipants { - readonly onDidChange: Event; - readonly documentSelector: DocumentSelector; - hasLanguage(languageId: string): boolean; - useAutoInsert(languageId: string): boolean; - dispose(): void; -} - -export function getLanguageParticipants(): LanguageParticipants { - const onDidChangeEmmiter = new EventEmitter(); - let languages = new Set(); - let autoInsert = new Set(); - - function update() { - const oldLanguages = languages, oldAutoInsert = autoInsert; - - languages = new Set(); - languages.add('html'); - autoInsert = new Set(); - autoInsert.add('html'); - - for (const extension of extensions.allAcrossExtensionHosts) { - const htmlLanguageParticipants = extension.packageJSON?.contributes?.htmlLanguageParticipants as LanguageParticipantContribution[]; - if (Array.isArray(htmlLanguageParticipants)) { - for (const htmlLanguageParticipant of htmlLanguageParticipants) { - const languageId = htmlLanguageParticipant.languageId; - if (typeof languageId === 'string') { - languages.add(languageId); - if (htmlLanguageParticipant.autoInsert !== false) { - autoInsert.add(languageId); - } - } - } - } - } - return !isEqualSet(languages, oldLanguages) || !isEqualSet(oldLanguages, oldAutoInsert); - } - update(); - - const changeListener = extensions.onDidChange(_ => { - if (update()) { - onDidChangeEmmiter.fire(); - } - }); - - return { - onDidChange: onDidChangeEmmiter.event, - get documentSelector() { return Array.from(languages); }, - hasLanguage(languageId: string) { return languages.has(languageId); }, - useAutoInsert(languageId: string) { return autoInsert.has(languageId); }, - dispose: () => changeListener.dispose() - }; -} - -function isEqualSet(s1: Set, s2: Set) { - if (s1.size !== s2.size) { - return false; - } - for (const e of s1) { - if (!s2.has(e)) { - return false; - } - } - return true; -} diff --git a/extensions/html-language-features/server/src/utils/validation.ts b/extensions/html-language-features/server/src/utils/validation.ts deleted file mode 100644 index 5738e7e501..0000000000 --- a/extensions/html-language-features/server/src/utils/validation.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken, Connection, Diagnostic, Disposable, DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportKind, TextDocuments } from 'vscode-languageserver'; -import { TextDocument } from 'vscode-html-languageservice'; -import { formatError, runSafe } from './runner'; -import { RuntimeEnvironment } from '../htmlServer'; - -export type Validator = (textDocument: TextDocument) => Promise; -export type DiagnosticsSupport = { - dispose(): void; - requestRefresh(): void; -}; - -export function registerDiagnosticsPushSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { - - const pendingValidationRequests: { [uri: string]: Disposable } = {}; - const validationDelayMs = 500; - - const disposables: Disposable[] = []; - - // The content of a text document has changed. This event is emitted - // when the text document first opened or when its content has changed. - documents.onDidChangeContent(change => { - triggerValidation(change.document); - }, undefined, disposables); - - // a document has closed: clear all diagnostics - documents.onDidClose(event => { - cleanPendingValidation(event.document); - connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] }); - }, undefined, disposables); - - function cleanPendingValidation(textDocument: TextDocument): void { - const request = pendingValidationRequests[textDocument.uri]; - if (request) { - request.dispose(); - delete pendingValidationRequests[textDocument.uri]; - } - } - - function triggerValidation(textDocument: TextDocument): void { - cleanPendingValidation(textDocument); - const request = pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(async () => { - if (request === pendingValidationRequests[textDocument.uri]) { - try { - const diagnostics = await validate(textDocument); - if (request === pendingValidationRequests[textDocument.uri]) { - connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); - } - delete pendingValidationRequests[textDocument.uri]; - } catch (e) { - connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e)); - } - } - }, validationDelayMs); - } - - return { - requestRefresh: () => { - documents.all().forEach(triggerValidation); - }, - dispose: () => { - disposables.forEach(d => d.dispose()); - disposables.length = 0; - const keys = Object.keys(pendingValidationRequests); - for (const key of keys) { - pendingValidationRequests[key].dispose(); - delete pendingValidationRequests[key]; - } - } - }; -} - -export function registerDiagnosticsPullSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { - - function newDocumentDiagnosticReport(diagnostics: Diagnostic[]): DocumentDiagnosticReport { - return { - kind: DocumentDiagnosticReportKind.Full, - items: diagnostics - }; - } - - const registration = connection.languages.diagnostics.on(async (params: DocumentDiagnosticParams, token: CancellationToken) => { - return runSafe(runtime, async () => { - const document = documents.get(params.textDocument.uri); - if (document) { - return newDocumentDiagnosticReport(await validate(document)); - } - return newDocumentDiagnosticReport([]); - - }, newDocumentDiagnosticReport([]), `Error while computing diagnostics for ${params.textDocument.uri}`, token); - }); - - function requestRefresh(): void { - connection.languages.diagnostics.refresh(); - } - - return { - requestRefresh, - dispose: () => { - registration.dispose(); - } - }; - -} diff --git a/extensions/image-preview/media/main.js b/extensions/image-preview/media/main.js index 66cee34b5d..8805db1ede 100644 --- a/extensions/image-preview/media/main.js +++ b/extensions/image-preview/media/main.js @@ -259,7 +259,7 @@ firstZoom(); } - const delta = e.deltaY > 0 ? 1 : -1; + let delta = e.deltaY > 0 ? 1 : -1; updateScale(scale * (1 - delta * SCALE_PINCH_FACTOR)); }, { passive: false }); diff --git a/extensions/image-preview/package.json b/extensions/image-preview/package.json index 1ad296a990..57bbb33821 100644 --- a/extensions/image-preview/package.json +++ b/extensions/image-preview/package.json @@ -10,7 +10,7 @@ "publisher": "vscode", "icon": "icon.png", "license": "MIT", - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "^1.39.0" }, @@ -79,7 +79,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.6.2", + "@vscode/extension-telemetry": "0.4.10", "vscode-nls": "^5.0.0" }, "repository": { diff --git a/extensions/image-preview/yarn.lock b/extensions/image-preview/yarn.lock index da44f29eaa..2e316e14a9 100644 --- a/extensions/image-preview/yarn.lock +++ b/extensions/image-preview/yarn.lock @@ -2,49 +2,10 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.4.10": + version "0.4.10" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.4.10.tgz#be960c05bdcbea0933866346cf244acad6cac910" + integrity sha512-XgyUoWWRQExTmd9DynIIUQo1NPex/zIeetdUAXeBjVuW9ioojM1TcDaSqOa/5QLC7lx+oEXwSU1r0XSBgzyz6w== vscode-nls@^5.0.0: version "5.0.0" diff --git a/extensions/ipynb/.gitignore b/extensions/ipynb/.gitignore index 8c0ca40ca2..170d890802 100644 --- a/extensions/ipynb/.gitignore +++ b/extensions/ipynb/.gitignore @@ -2,4 +2,3 @@ out dist node_modules *.vsix -notebook-out diff --git a/extensions/ipynb/.vscodeignore b/extensions/ipynb/.vscodeignore index f45314d0c1..08245c0148 100644 --- a/extensions/ipynb/.vscodeignore +++ b/extensions/ipynb/.vscodeignore @@ -6,4 +6,4 @@ extension.webpack.config.js extension-browser.webpack.config.js yarn.lock .gitignore -esbuild.js + diff --git a/extensions/ipynb/esbuild.js b/extensions/ipynb/esbuild.js deleted file mode 100644 index 182f55ef6d..0000000000 --- a/extensions/ipynb/esbuild.js +++ /dev/null @@ -1,47 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -//@ts-check - -const path = require('path'); -const fse = require('fs-extra'); -const esbuild = require('esbuild'); - -const args = process.argv.slice(2); - -const isWatch = args.indexOf('--watch') >= 0; - -let outputRoot = __dirname; -const outputRootIndex = args.indexOf('--outputRoot'); -if (outputRootIndex >= 0) { - outputRoot = args[outputRootIndex + 1]; -} - -const srcDir = path.join(__dirname, 'src'); -const outDir = path.join(outputRoot, 'notebook-out'); - -async function build() { - await esbuild.build({ - entryPoints: [ - path.join(srcDir, 'cellAttachmentRenderer.ts'), - ], - bundle: true, - minify: false, - sourcemap: false, - format: 'esm', - outdir: outDir, - platform: 'browser', - target: ['es2020'], - }); -} - - -build().catch(() => process.exit(1)); - -if (isWatch) { - const watcher = require('@parcel/watcher'); - watcher.subscribe(srcDir, () => { - return build(); - }); -} diff --git a/extensions/ipynb/package.json b/extensions/ipynb/package.json index 29c7742e41..c8feabc17a 100644 --- a/extensions/ipynb/package.json +++ b/extensions/ipynb/package.json @@ -52,16 +52,6 @@ "priority": "default" } ], - "notebookRenderer": [ - { - "id": "vscode.markdown-it-cell-attachment-renderer", - "displayName": "Markdown it ipynb Cell Attachment renderer", - "entrypoint": { - "extends": "vscode.markdown-it-renderer", - "path": "./notebook-out/cellAttachmentRenderer.js" - } - } - ], "menus": { "file/newFile": [ { @@ -81,9 +71,8 @@ } }, "scripts": { - "compile": "npx gulp compile-extension:ipynb && npm run build-notebook", - "watch": "npx gulp watch-extension:ipynb", - "build-notebook": "node ./esbuild" + "compile": "npx gulp compile-extension:ipynb", + "watch": "npx gulp watch-extension:ipynb" }, "dependencies": { "@enonic/fnv-plus": "^1.3.0", @@ -92,7 +81,6 @@ }, "devDependencies": { "@jupyterlab/nbformat": "^3.2.9", - "@types/markdown-it": "12.2.3", "@types/uuid": "^8.3.1" }, "repository": { diff --git a/extensions/ipynb/src/cellAttachmentRenderer.ts b/extensions/ipynb/src/cellAttachmentRenderer.ts deleted file mode 100644 index 844e2293a0..0000000000 --- a/extensions/ipynb/src/cellAttachmentRenderer.ts +++ /dev/null @@ -1,47 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type * as MarkdownIt from 'markdown-it'; -import type * as MarkdownItToken from 'markdown-it/lib/token'; -import type { RendererContext } from 'vscode-notebook-renderer'; - -interface MarkdownItRenderer { - extendMarkdownIt(fn: (md: MarkdownIt) => void): void; -} - -export async function activate(ctx: RendererContext) { - const markdownItRenderer = (await ctx.getRenderer('vscode.markdown-it-renderer')) as MarkdownItRenderer | any; - if (!markdownItRenderer) { - throw new Error(`Could not load 'vscode.markdown-it-renderer'`); - } - - markdownItRenderer.extendMarkdownIt((md: MarkdownIt) => { - const original = md.renderer.rules.image; - md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => { - const token = tokens[idx]; - const src = token.attrGet('src'); - const attachments: Record> = env.outputItem.metadata?.custom?.attachments; // this stores attachment entries for every image in the cell - if (attachments && src) { - const imageAttachment = attachments[src.replace('attachment:', '')]; - if (imageAttachment) { - // objEntries will always be length 1, with objEntries[0] holding [0]=mime,[1]=b64 - // if length = 0, something is wrong with the attachment, mime/b64 weren't copied over - const objEntries = Object.entries(imageAttachment); - if (objEntries.length) { - const [attachmentKey, attachmentVal] = objEntries[0]; - const b64Markdown = 'data:' + attachmentKey + ';base64,' + attachmentVal; - token.attrSet('src', b64Markdown); - } - } - } - - if (original) { - return original(tokens, idx, options, env, self); - } else { - return self.renderToken(tokens, idx, options); - } - }; - }); -} diff --git a/extensions/ipynb/yarn.lock b/extensions/ipynb/yarn.lock index 7b5488e710..c932570ecc 100644 --- a/extensions/ipynb/yarn.lock +++ b/extensions/ipynb/yarn.lock @@ -8,39 +8,21 @@ integrity sha512-BCN9uNWH8AmiP7BXBJqEinUY9KXalmRzo+L0cB/mQsmFfzODxwQrbvxCHXUNH2iP+qKkWYtB4vyy8N62PViMFw== "@jupyterlab/nbformat@^3.2.9": - version "3.4.3" - resolved "https://registry.yarnpkg.com/@jupyterlab/nbformat/-/nbformat-3.4.3.tgz#cbab1bf507677b7f0f309d8353fc83fe5a973c82" - integrity sha512-i/yADrwhhAJJCUOTa+fEBMyJO7fvX9Y73I0B7V6dQhGcrmrEKLC3wk4yOo63+jRntd5+dupbiOtz3w1ncIXwIA== + version "3.2.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/nbformat/-/nbformat-3.2.9.tgz#e7d854719612133498af4280d9a8caa0873205b0" + integrity sha512-WSf9OQo8yfFjyodbXRdFoaNwMkaAL5jFZiD6V2f8HqI380ipansWrrV7R9CGzPfgKHpUGZMO1tYKmUwzMhvZ4w== dependencies: - "@lumino/coreutils" "^1.11.0" + "@lumino/coreutils" "^1.5.3" -"@lumino/coreutils@^1.11.0": +"@lumino/coreutils@^1.5.3": version "1.12.0" resolved "https://registry.yarnpkg.com/@lumino/coreutils/-/coreutils-1.12.0.tgz#fbdef760f736eaf2bd396a5c6fc3a68a4b449b15" integrity sha512-DSglh4ylmLi820CNx9soJmDJCpUgymckdWeGWuN0Ash5g60oQvrQDfosVxEhzmNvtvXv45WZEqSBzDP6E5SEmQ== -"@types/linkify-it@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" - integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== - -"@types/markdown-it@12.2.3": - version "12.2.3" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" - integrity sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ== - dependencies: - "@types/linkify-it" "*" - "@types/mdurl" "*" - -"@types/mdurl@*": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" - integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== - "@types/uuid@^8.3.1": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + version "8.3.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f" + integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg== detect-indent@^6.0.0: version "6.1.0" diff --git a/extensions/javascript/javascript-language-configuration.json b/extensions/javascript/javascript-language-configuration.json index 72997cc3ec..8fa9cb9786 100644 --- a/extensions/javascript/javascript-language-configuration.json +++ b/extensions/javascript/javascript-language-configuration.json @@ -107,7 +107,7 @@ } }, "wordPattern": { - "pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>/\\?\\s]+)", + "pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>/\\?\\s]+)", }, "indentationRules": { "decreaseIndentPattern": { diff --git a/extensions/javascript/snippets/javascript.code-snippets b/extensions/javascript/snippets/javascript.code-snippets index 9448fd140d..47a6f40d20 100644 --- a/extensions/javascript/snippets/javascript.code-snippets +++ b/extensions/javascript/snippets/javascript.code-snippets @@ -190,14 +190,5 @@ "console.error($1);" ], "description": "Log error to the console" - }, - "new Promise": { - "prefix": "newpromise", - "body": [ - "new Promise((resolve, reject) => {", - "\t$TM_SELECTED_TEXT$0", - "})" - ], - "description": "Create a new Promise" } } diff --git a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json index e957c06c1b..04a23eca11 100644 --- a/extensions/javascript/syntaxes/JavaScript.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScript.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0dfae8cc4807fecfbf8f1add095d9817df824c95", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/4d30ff834ec324f56291addd197aa1e423cedfdd", "name": "JavaScript (with React support)", "scopeName": "source.js", "patterns": [ @@ -2271,47 +2271,11 @@ "name": "keyword.control.from.js", "match": "\\bfrom\\b" }, - { - "include": "#import-export-assert-clause" - }, { "include": "#import-export-clause" } ] }, - "import-export-assert-clause": { - "begin": "(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.js" @@ -5128,7 +5092,7 @@ "patterns": [ { "name": "entity.other.attribute-name.directive.js", - "match": "path|types|no-default-lib|lib|name|resolution-mode" + "match": "path|types|no-default-lib|lib|name" }, { "name": "keyword.operator.assignment.js", diff --git a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json index 90476c2a91..5d3448bdfe 100644 --- a/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json +++ b/extensions/javascript/syntaxes/JavaScriptReact.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/0dfae8cc4807fecfbf8f1add095d9817df824c95", + "version": "https://github.com/microsoft/TypeScript-TmLanguage/commit/4d30ff834ec324f56291addd197aa1e423cedfdd", "name": "JavaScript (with React support)", "scopeName": "source.js.jsx", "patterns": [ @@ -2271,47 +2271,11 @@ "name": "keyword.control.from.js.jsx", "match": "\\bfrom\\b" }, - { - "include": "#import-export-assert-clause" - }, { "include": "#import-export-clause" } ] }, - "import-export-assert-clause": { - "begin": "(?\\s*$)", + "begin": "^(///)\\s*(?=<(reference|amd-dependency|amd-module)(\\s+(path|types|no-default-lib|lib|name)\\s*=\\s*((\\'([^\\'\\\\]|\\\\.)*\\')|(\\\"([^\\\"\\\\]|\\\\.)*\\\")|(\\`([^\\`\\\\]|\\\\.)*\\`)))+\\s*/>\\s*$)", "beginCaptures": { "1": { "name": "punctuation.definition.comment.js.jsx" @@ -5128,7 +5092,7 @@ "patterns": [ { "name": "entity.other.attribute-name.directive.js.jsx", - "match": "path|types|no-default-lib|lib|name|resolution-mode" + "match": "path|types|no-default-lib|lib|name" }, { "name": "keyword.operator.assignment.js.jsx", diff --git a/extensions/json-language-features/client/src/browser/jsonClientMain.ts b/extensions/json-language-features/client/src/browser/jsonClientMain.ts index 42a792f9f6..e3863900a1 100644 --- a/extensions/json-language-features/client/src/browser/jsonClientMain.ts +++ b/extensions/json-language-features/client/src/browser/jsonClientMain.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ExtensionContext, Uri } from 'vscode'; -import { BaseLanguageClient, LanguageClientOptions } from 'vscode-languageclient'; +import { LanguageClientOptions } from 'vscode-languageclient'; import { startClient, LanguageClientConstructor, SchemaRequestService } from '../jsonClient'; import { LanguageClient } from 'vscode-languageclient/browser'; @@ -14,10 +14,8 @@ declare const Worker: { declare function fetch(uri: string, options: any): any; -let client: BaseLanguageClient | undefined; - // this method is called when vs code is activated -export async function activate(context: ExtensionContext) { +export function activate(context: ExtensionContext) { const serverMain = Uri.joinPath(context.extensionUri, 'server/dist/browser/jsonServerMain.js'); try { const worker = new Worker(serverMain.toString()); @@ -34,16 +32,9 @@ export async function activate(context: ExtensionContext) { } }; - client = await startClient(context, newLanguageClient, { schemaRequests }); + startClient(context, newLanguageClient, { schemaRequests }); } catch (e) { console.log(e); } } - -export async function deactivate(): Promise { - if (client) { - await client.stop(); - client = undefined; - } -} diff --git a/extensions/json-language-features/client/src/jsonClient.ts b/extensions/json-language-features/client/src/jsonClient.ts index ccfe6da151..40ceda25e8 100644 --- a/extensions/json-language-features/client/src/jsonClient.ts +++ b/extensions/json-language-features/client/src/jsonClient.ts @@ -9,19 +9,18 @@ const localize = nls.loadMessageBundle(); export type JSONLanguageStatus = { schemas: string[] }; import { - workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation, - Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange, - ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation + workspace, window, languages, commands, ExtensionContext, extensions, Uri, + Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, + ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, } from 'vscode'; import { LanguageClientOptions, RequestType, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams, - DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature + DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, CommonLanguageClient } from 'vscode-languageclient'; - import { hash } from './utils/hash'; -import { createDocumentColorsLimitItem, createDocumentSymbolsLimitItem, createFoldingRangeLimitItem, createLanguageStatusItem, createLimitStatusItem } from './languageStatus'; +import { createLanguageStatusItem } from './languageStatus'; namespace VSCodeContentRequest { export const type: RequestType = new RequestType('vscode/content'); @@ -53,11 +52,14 @@ namespace SchemaAssociationNotification { export const type: NotificationType = new NotificationType('json/schemaAssociations'); } -type Settings = { +namespace ResultLimitReachedNotification { + export const type: NotificationType = new NotificationType('json/resultLimitReached'); +} + +interface Settings { json?: { schemas?: JSONSchemaSettings[]; format?: { enable?: boolean }; - keepLines?: { enable?: boolean }; validate?: { enable?: boolean }; resultLimit?: number; }; @@ -65,22 +67,25 @@ type Settings = { proxy?: string; proxyStrictSSL?: boolean; }; -}; +} -export type JSONSchemaSettings = { +export interface JSONSchemaSettings { fileMatch?: string[]; url?: string; schema?: any; -}; +} -export namespace SettingIds { +namespace SettingIds { export const enableFormatter = 'json.format.enable'; - export const enableKeepLines = 'json.format.keepLines'; export const enableValidation = 'json.validate.enable'; export const enableSchemaDownload = 'json.schemaDownload.enable'; export const maxItemsComputed = 'json.maxItemsComputed'; } +namespace StorageIds { + export const maxItemsExceededInformation = 'json.maxItemsExceededInformation'; +} + export interface TelemetryReporter { sendTelemetryEvent(eventName: string, properties?: { [key: string]: string; @@ -89,7 +94,7 @@ export interface TelemetryReporter { }): void; } -export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient; +export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => CommonLanguageClient; export interface Runtime { schemaRequests: SchemaRequestService; @@ -103,9 +108,7 @@ export interface SchemaRequestService { export const languageServerDescription = localize('jsonserver.name', 'JSON Language Server'); -let resultLimit = 5000; - -export async function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime): Promise { +export function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime) { const toDispose = context.subscriptions; @@ -123,11 +126,6 @@ export async function startClient(context: ExtensionContext, newLanguageClient: let isClientReady = false; - const foldingRangeLimitStatusBarItem = createLimitStatusItem((limit: number) => createFoldingRangeLimitItem(documentSelector, SettingIds.maxItemsComputed, limit)); - const documentSymbolsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentSymbolsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit)); - const documentColorsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentColorsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit)); - toDispose.push(foldingRangeLimitStatusBarItem, documentSymbolsLimitStatusbarItem, documentColorsLimitStatusbarItem); - toDispose.push(commands.registerCommand('json.clearCache', async () => { if (isClientReady && runtime.schemaRequests.clearCache) { const cachedSchemas = await runtime.schemaRequests.clearCache(); @@ -212,60 +210,6 @@ export async function startClient(context: ExtensionContext, newLanguageClient: return r.then(updateHover); } return updateHover(r); - }, - provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken, next: ProvideFoldingRangeSignature) { - function checkLimit(r: FoldingRange[] | null | undefined): FoldingRange[] | null | undefined { - if (Array.isArray(r) && r.length > resultLimit) { - r.length = resultLimit; // truncate - foldingRangeLimitStatusBarItem.update(document, resultLimit); - } else { - foldingRangeLimitStatusBarItem.update(document, false); - } - return r; - } - const r = next(document, context, token); - if (isThenable(r)) { - return r.then(checkLimit); - } - return checkLimit(r); - }, - provideDocumentColors(document: TextDocument, token: CancellationToken, next: ProvideDocumentColorsSignature) { - function checkLimit(r: ColorInformation[] | null | undefined): ColorInformation[] | null | undefined { - if (Array.isArray(r) && r.length > resultLimit) { - r.length = resultLimit; // truncate - documentColorsLimitStatusbarItem.update(document, resultLimit); - } else { - documentColorsLimitStatusbarItem.update(document, false); - } - return r; - } - const r = next(document, token); - if (isThenable(r)) { - return r.then(checkLimit); - } - return checkLimit(r); - }, - provideDocumentSymbols(document: TextDocument, token: CancellationToken, next: ProvideDocumentSymbolsSignature) { - type T = SymbolInformation[] | DocumentSymbol[]; - function countDocumentSymbols(symbols: DocumentSymbol[]): number { - return symbols.reduce((previousValue, s) => previousValue + 1 + countDocumentSymbols(s.children), 0); - } - function isDocumentSymbol(r: T): r is DocumentSymbol[] { - return r[0] instanceof DocumentSymbol; - } - function checkLimit(r: T | null | undefined): T | null | undefined { - if (Array.isArray(r) && (isDocumentSymbol(r) ? countDocumentSymbols(r) : r.length) > resultLimit) { - documentSymbolsLimitStatusbarItem.update(document, resultLimit); - } else { - documentSymbolsLimitStatusbarItem.update(document, false); - } - return r; - } - const r = next(document, token); - if (isThenable(r)) { - return r.then(checkLimit); - } - return checkLimit(r); } } }; @@ -274,162 +218,176 @@ export async function startClient(context: ExtensionContext, newLanguageClient: const client = newLanguageClient('json', languageServerDescription, clientOptions); client.registerProposedFeatures(); - const schemaDocuments: { [uri: string]: boolean } = {}; + const disposable = client.start(); + toDispose.push(disposable); + client.onReady().then(() => { + isClientReady = true; - // handle content request - client.onRequest(VSCodeContentRequest.type, (uriPath: string) => { - const uri = Uri.parse(uriPath); - if (uri.scheme === 'untitled') { - return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString()))); - } - if (uri.scheme !== 'http' && uri.scheme !== 'https') { - return workspace.openTextDocument(uri).then(doc => { - schemaDocuments[uri.toString()] = true; - return doc.getText(); - }, error => { - return Promise.reject(new ResponseError(2, error.toString())); - }); - } else if (schemaDownloadEnabled) { - if (runtime.telemetry && uri.authority === 'schema.management.azure.com') { - /* __GDPR__ - "json.schema" : { - "owner": "aeschli", - "comment": "Measure the use of the Azure resource manager schemas", - "schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The azure schema URL that was requested." } - } - */ - runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath }); + const schemaDocuments: { [uri: string]: boolean } = {}; + + // handle content request + client.onRequest(VSCodeContentRequest.type, (uriPath: string) => { + const uri = Uri.parse(uriPath); + if (uri.scheme === 'untitled') { + return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString()))); } - return runtime.schemaRequests.getContent(uriPath).catch(e => { - return Promise.reject(new ResponseError(4, e.toString())); - }); - } else { - return Promise.reject(new ResponseError(1, localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload))); - } - }); - - await client.start(); - - isClientReady = true; - - const handleContentChange = (uriString: string) => { - if (schemaDocuments[uriString]) { - client.sendNotification(SchemaContentChangeNotification.type, uriString); - return true; - } - return false; - }; - const handleActiveEditorChange = (activeEditor?: TextEditor) => { - if (!activeEditor) { - return; - } - - const activeDocUri = activeEditor.document.uri.toString(); - - if (activeDocUri && fileSchemaErrors.has(activeDocUri)) { - schemaResolutionErrorStatusBarItem.show(); - } else { - schemaResolutionErrorStatusBarItem.hide(); - } - }; - - toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri.toString()))); - toDispose.push(workspace.onDidCloseTextDocument(d => { - const uriString = d.uri.toString(); - if (handleContentChange(uriString)) { - delete schemaDocuments[uriString]; - } - fileSchemaErrors.delete(uriString); - })); - toDispose.push(window.onDidChangeActiveTextEditor(handleActiveEditorChange)); - - const handleRetryResolveSchemaCommand = () => { - if (window.activeTextEditor) { - schemaResolutionErrorStatusBarItem.text = '$(watch)'; - const activeDocUri = window.activeTextEditor.document.uri.toString(); - client.sendRequest(ForceValidateRequest.type, activeDocUri).then((diagnostics) => { - const schemaErrorIndex = diagnostics.findIndex(isSchemaResolveError); - if (schemaErrorIndex !== -1) { - // Show schema resolution errors in status bar only; ref: #51032 - const schemaResolveDiagnostic = diagnostics[schemaErrorIndex]; - fileSchemaErrors.set(activeDocUri, schemaResolveDiagnostic.message); - } else { - schemaResolutionErrorStatusBarItem.hide(); - } - schemaResolutionErrorStatusBarItem.text = '$(alert)'; - }); - } - }; - - toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand)); - - client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); - - toDispose.push(extensions.onDidChange(_ => { - client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); - })); - - // manually register / deregister format provider based on the `json.format.enable` setting avoiding issues with late registration. See #71652. - updateFormatterRegistration(); - toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() }); - - updateSchemaDownloadSetting(); - - toDispose.push(workspace.onDidChangeConfiguration(e => { - if (e.affectsConfiguration(SettingIds.enableFormatter)) { - updateFormatterRegistration(); - } else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) { - updateSchemaDownloadSetting(); - } - })); - - toDispose.push(createLanguageStatusItem(documentSelector, (uri: string) => client.sendRequest(LanguageStatusRequest.type, uri))); - - function updateFormatterRegistration() { - const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter); - if (!formatEnabled && rangeFormatting) { - rangeFormatting.dispose(); - rangeFormatting = undefined; - } else if (formatEnabled && !rangeFormatting) { - rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, { - provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { - const filesConfig = workspace.getConfiguration('files', document); - const fileFormattingOptions = { - trimTrailingWhitespace: filesConfig.get('trimTrailingWhitespace'), - trimFinalNewlines: filesConfig.get('trimFinalNewlines'), - insertFinalNewline: filesConfig.get('insertFinalNewline'), - }; - const params: DocumentRangeFormattingParams = { - textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), - range: client.code2ProtocolConverter.asRange(range), - options: client.code2ProtocolConverter.asFormattingOptions(options, fileFormattingOptions) - }; - - return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then( - client.protocol2CodeConverter.asTextEdits, - (error) => { - client.handleFailedRequest(DocumentRangeFormattingRequest.type, undefined, error, []); - return Promise.resolve([]); + if (uri.scheme !== 'http' && uri.scheme !== 'https') { + return workspace.openTextDocument(uri).then(doc => { + schemaDocuments[uri.toString()] = true; + return doc.getText(); + }, error => { + return Promise.reject(new ResponseError(2, error.toString())); + }); + } else if (schemaDownloadEnabled) { + if (runtime.telemetry && uri.authority === 'schema.management.azure.com') { + /* __GDPR__ + "json.schema" : { + "schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } } - ); + */ + runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath }); } - }); - } - } + return runtime.schemaRequests.getContent(uriPath).catch(e => { + return Promise.reject(new ResponseError(4, e.toString())); + }); + } else { + return Promise.reject(new ResponseError(1, localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload))); + } + }); - function updateSchemaDownloadSetting() { - schemaDownloadEnabled = workspace.getConfiguration().get(SettingIds.enableSchemaDownload) !== false; - if (schemaDownloadEnabled) { - schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema. Click to retry.'); - schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema'; - handleRetryResolveSchemaCommand(); - } else { - schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionDisabledMessage', 'Downloading schemas is disabled. Click to configure.'); - schemaResolutionErrorStatusBarItem.command = { command: 'workbench.action.openSettings', arguments: [SettingIds.enableSchemaDownload], title: '' }; - } - } + const handleContentChange = (uriString: string) => { + if (schemaDocuments[uriString]) { + client.sendNotification(SchemaContentChangeNotification.type, uriString); + return true; + } + return false; + }; + const handleActiveEditorChange = (activeEditor?: TextEditor) => { + if (!activeEditor) { + return; + } - return client; + const activeDocUri = activeEditor.document.uri.toString(); + + if (activeDocUri && fileSchemaErrors.has(activeDocUri)) { + schemaResolutionErrorStatusBarItem.show(); + } else { + schemaResolutionErrorStatusBarItem.hide(); + } + }; + + toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri.toString()))); + toDispose.push(workspace.onDidCloseTextDocument(d => { + const uriString = d.uri.toString(); + if (handleContentChange(uriString)) { + delete schemaDocuments[uriString]; + } + fileSchemaErrors.delete(uriString); + })); + toDispose.push(window.onDidChangeActiveTextEditor(handleActiveEditorChange)); + + const handleRetryResolveSchemaCommand = () => { + if (window.activeTextEditor) { + schemaResolutionErrorStatusBarItem.text = '$(watch)'; + const activeDocUri = window.activeTextEditor.document.uri.toString(); + client.sendRequest(ForceValidateRequest.type, activeDocUri).then((diagnostics) => { + const schemaErrorIndex = diagnostics.findIndex(isSchemaResolveError); + if (schemaErrorIndex !== -1) { + // Show schema resolution errors in status bar only; ref: #51032 + const schemaResolveDiagnostic = diagnostics[schemaErrorIndex]; + fileSchemaErrors.set(activeDocUri, schemaResolveDiagnostic.message); + } else { + schemaResolutionErrorStatusBarItem.hide(); + } + schemaResolutionErrorStatusBarItem.text = '$(alert)'; + }); + } + }; + + toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand)); + + client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); + + toDispose.push(extensions.onDidChange(_ => { + client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context)); + })); + + // manually register / deregister format provider based on the `json.format.enable` setting avoiding issues with late registration. See #71652. + updateFormatterRegistration(); + toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() }); + + updateSchemaDownloadSetting(); + + toDispose.push(workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration(SettingIds.enableFormatter)) { + updateFormatterRegistration(); + } else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) { + updateSchemaDownloadSetting(); + } + })); + + client.onNotification(ResultLimitReachedNotification.type, async message => { + const shouldPrompt = context.globalState.get(StorageIds.maxItemsExceededInformation) !== false; + if (shouldPrompt) { + const ok = localize('ok', "OK"); + const openSettings = localize('goToSetting', 'Open Settings'); + const neverAgain = localize('yes never again', "Don't Show Again"); + const pick = await window.showInformationMessage(`${message}\n${localize('configureLimit', 'Use setting \'{0}\' to configure the limit.', SettingIds.maxItemsComputed)}`, ok, openSettings, neverAgain); + if (pick === neverAgain) { + await context.globalState.update(StorageIds.maxItemsExceededInformation, false); + } else if (pick === openSettings) { + await commands.executeCommand('workbench.action.openSettings', SettingIds.maxItemsComputed); + } + } + }); + + toDispose.push(createLanguageStatusItem(documentSelector, (uri: string) => client.sendRequest(LanguageStatusRequest.type, uri))); + + function updateFormatterRegistration() { + const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter); + if (!formatEnabled && rangeFormatting) { + rangeFormatting.dispose(); + rangeFormatting = undefined; + } else if (formatEnabled && !rangeFormatting) { + rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, { + provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult { + const filesConfig = workspace.getConfiguration('files', document); + const fileFormattingOptions = { + trimTrailingWhitespace: filesConfig.get('trimTrailingWhitespace'), + trimFinalNewlines: filesConfig.get('trimFinalNewlines'), + insertFinalNewline: filesConfig.get('insertFinalNewline'), + }; + const params: DocumentRangeFormattingParams = { + textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), + range: client.code2ProtocolConverter.asRange(range), + options: client.code2ProtocolConverter.asFormattingOptions(options, fileFormattingOptions) + }; + + return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then( + client.protocol2CodeConverter.asTextEdits, + (error) => { + client.handleFailedRequest(DocumentRangeFormattingRequest.type, error, []); + return Promise.resolve([]); + } + ); + } + }); + } + } + + function updateSchemaDownloadSetting() { + schemaDownloadEnabled = workspace.getConfiguration().get(SettingIds.enableSchemaDownload) !== false; + if (schemaDownloadEnabled) { + schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema. Click to retry.'); + schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema'; + handleRetryResolveSchemaCommand(); + } else { + schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionDisabledMessage', 'Downloading schemas is disabled. Click to configure.'); + schemaResolutionErrorStatusBarItem.command = { command: 'workbench.action.openSettings', arguments: [SettingIds.enableSchemaDownload], title: '' }; + } + } + + }); } function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] { @@ -472,7 +430,7 @@ function getSettings(): Settings { const configuration = workspace.getConfiguration(); const httpSettings = workspace.getConfiguration('http'); - resultLimit = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get(SettingIds.maxItemsComputed)))) || 5000; + const resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get(SettingIds.maxItemsComputed)))) || 5000; const settings: Settings = { http: { @@ -482,9 +440,8 @@ function getSettings(): Settings { json: { validate: { enable: configuration.get(SettingIds.enableValidation) }, format: { enable: configuration.get(SettingIds.enableFormatter) }, - keepLines: { enable: configuration.get(SettingIds.enableKeepLines) }, schemas: [], - resultLimit: resultLimit + 1 // ask for one more so we can detect if the limit has been exceeded + resultLimit } }; const schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null); diff --git a/extensions/json-language-features/client/src/languageStatus.ts b/extensions/json-language-features/client/src/languageStatus.ts index 7b18cb6f86..ad63e17ec0 100644 --- a/extensions/json-language-features/client/src/languageStatus.ts +++ b/extensions/json-language-features/client/src/languageStatus.ts @@ -3,11 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { - window, languages, Uri, Disposable, commands, QuickPickItem, - extensions, workspace, Extension, WorkspaceFolder, QuickPickItemKind, - ThemeIcon, TextDocument, LanguageStatusSeverity -} from 'vscode'; +import { window, languages, Uri, LanguageStatusSeverity, Disposable, commands, QuickPickItem, extensions, workspace, Extension, WorkspaceFolder, QuickPickItemKind, ThemeIcon } from 'vscode'; import { JSONLanguageStatus, JSONSchemaSettings } from './jsonClient'; import * as nls from 'vscode-nls'; @@ -191,13 +187,13 @@ export function createLanguageStatusItem(documentSelector: string[], statusReque statusItem.detail = undefined; if (schemas.length === 0) { statusItem.text = localize('status.noSchema.short', "No Schema Validation"); - statusItem.detail = localize('status.noSchema', 'no JSON schema configured'); + statusItem.detail = localize('status.noSchema', 'No JSON schema configured.'); } else if (schemas.length === 1) { statusItem.text = localize('status.withSchema.short', "Schema Validated"); - statusItem.detail = localize('status.singleSchema', 'JSON schema configured'); + statusItem.detail = localize('status.singleSchema', 'JSON schema configured.'); } else { statusItem.text = localize('status.withSchemas.short', "Schema Validated"); - statusItem.detail = localize('status.multipleSchema', 'multiple JSON schemas configured'); + statusItem.detail = localize('status.multipleSchema', 'Multiple JSON schemas configured.'); } statusItem.command = { command: '_json.showAssociatedSchemaList', @@ -221,85 +217,3 @@ export function createLanguageStatusItem(documentSelector: string[], statusReque return Disposable.from(statusItem, activeEditorListener, showSchemasCommand); } -export function createLimitStatusItem(newItem: (limit: number) => Disposable) { - let statusItem: Disposable | undefined; - const activeLimits: Map = new Map(); - - const toDispose: Disposable[] = []; - toDispose.push(window.onDidChangeActiveTextEditor(textEditor => { - statusItem?.dispose(); - statusItem = undefined; - const doc = textEditor?.document; - if (doc) { - const limit = activeLimits.get(doc); - if (limit !== undefined) { - statusItem = newItem(limit); - } - } - })); - toDispose.push(workspace.onDidCloseTextDocument(document => { - activeLimits.delete(document); - })); - - function update(document: TextDocument, limitApplied: number | false) { - if (limitApplied === false) { - activeLimits.delete(document); - if (statusItem && document === window.activeTextEditor?.document) { - statusItem.dispose(); - statusItem = undefined; - } - } else { - activeLimits.set(document, limitApplied); - if (document === window.activeTextEditor?.document) { - if (!statusItem || limitApplied !== activeLimits.get(document)) { - statusItem?.dispose(); - statusItem = newItem(limitApplied); - } - } - } - } - return { - update, - dispose() { - statusItem?.dispose(); - toDispose.forEach(d => d.dispose()); - toDispose.length = 0; - statusItem = undefined; - activeLimits.clear(); - } - }; -} - -const openSettingsCommand = 'workbench.action.openSettings'; -const configureSettingsLabel = localize('status.button.configure', "Configure"); - -export function createFoldingRangeLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable { - const statusItem = languages.createLanguageStatusItem('json.foldingRangesStatus', documentSelector); - statusItem.name = localize('foldingRangesStatusItem.name', "JSON Folding Status"); - statusItem.severity = LanguageStatusSeverity.Warning; - statusItem.text = localize('status.limitedFoldingRanges.short', "Folding Ranges Limited"); - statusItem.detail = localize('status.limitedFoldingRanges.details', 'only {0} folding ranges shown', limit); - statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel }; - return Disposable.from(statusItem); -} - -export function createDocumentSymbolsLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable { - const statusItem = languages.createLanguageStatusItem('json.documentSymbolsStatus', documentSelector); - statusItem.name = localize('documentSymbolsStatusItem.name', "JSON Outline Status"); - statusItem.severity = LanguageStatusSeverity.Warning; - statusItem.text = localize('status.limitedDocumentSymbols.short', "Outline Limited"); - statusItem.detail = localize('status.limitedDocumentSymbols.details', 'only {0} document symbols shown', limit); - statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel }; - return Disposable.from(statusItem); -} - -export function createDocumentColorsLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable { - const statusItem = languages.createLanguageStatusItem('json.documentColorsStatus', documentSelector); - statusItem.name = localize('documentColorsStatusItem.name', "JSON Color Symbol Status"); - statusItem.severity = LanguageStatusSeverity.Warning; - statusItem.text = localize('status.limitedDocumentColors.short', "Color Symbols Limited"); - statusItem.detail = localize('status.limitedDocumentColors.details', 'only {0} color decorators shown', limit); - statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel }; - return Disposable.from(statusItem); -} - diff --git a/extensions/json-language-features/client/src/node/jsonClientMain.ts b/extensions/json-language-features/client/src/node/jsonClientMain.ts index 46a2e4cd58..6ba5724b15 100644 --- a/extensions/json-language-features/client/src/node/jsonClientMain.ts +++ b/extensions/json-language-features/client/src/node/jsonClientMain.ts @@ -5,7 +5,7 @@ import { ExtensionContext, OutputChannel, window, workspace } from 'vscode'; import { startClient, LanguageClientConstructor, SchemaRequestService, languageServerDescription } from '../jsonClient'; -import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient, BaseLanguageClient } from 'vscode-languageclient/node'; +import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient } from 'vscode-languageclient/node'; import { promises as fs } from 'fs'; import * as path from 'path'; @@ -15,7 +15,6 @@ import TelemetryReporter from '@vscode/extension-telemetry'; import { JSONSchemaCache } from './schemaCache'; let telemetry: TelemetryReporter | undefined; -let client: BaseLanguageClient | undefined; // this method is called when vs code is activated export async function activate(context: ExtensionContext) { @@ -46,15 +45,11 @@ export async function activate(context: ExtensionContext) { const schemaRequests = await getSchemaRequestService(context, log); - client = await startClient(context, newLanguageClient, { schemaRequests, telemetry }); + startClient(context, newLanguageClient, { schemaRequests, telemetry }); } -export async function deactivate(): Promise { - if (client) { - await client.stop(); - client = undefined; - } - telemetry?.dispose(); +export function deactivate(): Promise { + return telemetry ? telemetry.dispose() : Promise.resolve(null); } interface IPackageInfo { diff --git a/extensions/json-language-features/package.json b/extensions/json-language-features/package.json index 8f3345c2a6..25aef750a7 100644 --- a/extensions/json-language-features/package.json +++ b/extensions/json-language-features/package.json @@ -5,7 +5,7 @@ "version": "1.0.0", "publisher": "vscode", "license": "MIT", - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "0.10.x" }, @@ -85,12 +85,6 @@ "default": true, "description": "%json.format.enable.desc%" }, - "json.format.keepLines": { - "type": "boolean", - "scope": "window", - "default": false, - "description": "%json.format.keepLines.desc%" - }, "json.trace.server": { "type": "string", "scope": "window", @@ -153,10 +147,10 @@ ] }, "dependencies": { - "@vscode/extension-telemetry": "0.6.2", + "@vscode/extension-telemetry": "0.5.0", "request-light": "^0.5.8", - "vscode-languageclient": "^8.0.2-next.5", - "vscode-nls": "^5.0.1" + "vscode-languageclient": "^7.0.0", + "vscode-nls": "^5.0.0" }, "devDependencies": { "@types/node": "16.x" diff --git a/extensions/json-language-features/package.nls.json b/extensions/json-language-features/package.nls.json index e1c2c8e608..d732f6ed64 100644 --- a/extensions/json-language-features/package.nls.json +++ b/extensions/json-language-features/package.nls.json @@ -7,7 +7,6 @@ "json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' to match against when resolving JSON files to schemas.", "json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.", "json.format.enable.desc": "Enable/disable default JSON formatter", - "json.format.keepLines.desc" : "Keep all existing new lines when formatting.", "json.validate.enable.desc": "Enable/disable JSON validation.", "json.tracing.desc": "Traces the communication between Azure Data Studio and the JSON language server.", "json.colorDecorators.enable.desc": "Enables or disables color decorators", diff --git a/extensions/json-language-features/server/README.md b/extensions/json-language-features/server/README.md index bc9b22e4ff..e82ae06d77 100644 --- a/extensions/json-language-features/server/README.md +++ b/extensions/json-language-features/server/README.md @@ -188,6 +188,12 @@ Notification: ### Item Limit If the setting `resultLimit` is set, the JSON language server will limit the number of folding ranges and document symbols computed. +When the limit is reached, a notification `json/resultLimitReached` is sent that can be shown that can be shown to the user. + +Notification: +- method: 'json/resultLimitReached' +- params: a human readable string to show to the user. + ## Try diff --git a/extensions/json-language-features/server/package.json b/extensions/json-language-features/server/package.json index abae73c408..cd04f24c3a 100644 --- a/extensions/json-language-features/server/package.json +++ b/extensions/json-language-features/server/package.json @@ -12,10 +12,10 @@ }, "main": "./out/node/jsonServerMain", "dependencies": { - "jsonc-parser": "^3.1.0", + "jsonc-parser": "^3.0.0", "request-light": "^0.5.8", - "vscode-json-languageservice": "^5.1.0", - "vscode-languageserver": "^8.0.2-next.5", + "vscode-json-languageservice": "^4.2.1", + "vscode-languageserver": "^7.0.0", "vscode-uri": "^3.0.3" }, "devDependencies": { diff --git a/extensions/json-language-features/server/src/jsonServer.ts b/extensions/json-language-features/server/src/jsonServer.ts index db08e1dbf4..aaf8f8b53e 100644 --- a/extensions/json-language-features/server/src/jsonServer.ts +++ b/extensions/json-language-features/server/src/jsonServer.ts @@ -6,12 +6,11 @@ import { Connection, TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType, - DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic + DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions } from 'vscode-languageserver'; -import { runSafe, runSafeAsync } from './utils/runner'; -import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnosticsPushSupport } from './utils/validation'; -import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position } from 'vscode-json-languageservice'; +import { formatError, runSafe, runSafeAsync } from './utils/runner'; +import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Diagnostic, Range, Position } from 'vscode-json-languageservice'; import { getLanguageModelCache } from './languageModelCache'; import { Utils, URI } from 'vscode-uri'; @@ -31,6 +30,10 @@ namespace SchemaContentChangeNotification { export const type: NotificationType = new NotificationType('json/schemaContent'); } +namespace ResultLimitReachedNotification { + export const type: NotificationType = new NotificationType('json/resultLimitReached'); +} + namespace ForceValidateRequest { export const type: RequestType = new RequestType('json/validate'); } @@ -65,7 +68,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) function getSchemaRequestService(handledSchemas: string[] = ['https', 'http', 'file']) { const builtInHandlers: { [protocol: string]: RequestService | undefined } = {}; - for (const protocol of handledSchemas) { + for (let protocol of handledSchemas) { if (protocol === 'file') { builtInHandlers[protocol] = runtime.file; } else if (protocol === 'http' || protocol === 'https') { @@ -110,16 +113,11 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) let resultLimit = Number.MAX_VALUE; let formatterMaxNumberOfEdits = Number.MAX_VALUE; - let diagnosticsSupport: DiagnosticsSupport | undefined; - - // After the server has started the client sends an initialize request. The server receives // in the passed params the rootPath of the workspace plus the client capabilities. connection.onInitialize((params: InitializeParams): InitializeResult => { - const initializationOptions = params.initializationOptions as any || {}; - - const handledProtocols = initializationOptions?.handledSchemaProtocols; + const handledProtocols = params.initializationOptions?.handledSchemaProtocols; languageService = getLanguageService({ schemaRequestService: getSchemaRequestService(handledProtocols), @@ -141,18 +139,10 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) } clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false); - dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof initializationOptions.provideFormatter !== 'boolean'); + dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions?.provideFormatter !== 'boolean'); foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE); hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false); - formatterMaxNumberOfEdits = initializationOptions.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE; - - const supportsDiagnosticPull = getClientCapability('textDocument.diagnostic', undefined); - if (supportsDiagnosticPull === undefined) { - diagnosticsSupport = registerDiagnosticsPushSupport(documents, connection, runtime, validateTextDocument); - } else { - diagnosticsSupport = registerDiagnosticsPullSupport(documents, connection, runtime, validateTextDocument); - } - + formatterMaxNumberOfEdits = params.initializationOptions?.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE; const capabilities: ServerCapabilities = { textDocumentSync: TextDocumentSyncKind.Incremental, completionProvider: clientSnippetSupport ? { @@ -161,17 +151,12 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) } : undefined, hoverProvider: true, documentSymbolProvider: true, - documentRangeFormattingProvider: initializationOptions.provideFormatter === true, - documentFormattingProvider: initializationOptions.provideFormatter === true, + documentRangeFormattingProvider: params.initializationOptions?.provideFormatter === true, + documentFormattingProvider: params.initializationOptions?.provideFormatter === true, colorProvider: {}, foldingRangeProvider: true, selectionRangeProvider: true, - documentLinkProvider: {}, - diagnosticProvider: { - documentSelector: null, - interFileDependencies: false, - workspaceDiagnostics: false - } + documentLinkProvider: {} }; return { capabilities }; @@ -184,7 +169,6 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) json?: { schemas?: JSONSchemaSettings[]; format?: { enable?: boolean }; - keepLines?: { enable?: boolean }; validate?: { enable?: boolean }; resultLimit?: number; }; @@ -201,20 +185,58 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) } + const limitExceededWarnings = function () { + const pendingWarnings: { [uri: string]: { features: { [name: string]: string }; timeout?: Disposable } } = {}; + + const showLimitedNotification = (uri: string, resultLimit: number) => { + const warning = pendingWarnings[uri]; + connection.sendNotification(ResultLimitReachedNotification.type, `${Utils.basename(URI.parse(uri))}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`); + warning.timeout = undefined; + }; + + return { + cancel(uri: string) { + const warning = pendingWarnings[uri]; + if (warning && warning.timeout) { + warning.timeout.dispose(); + delete pendingWarnings[uri]; + } + }, + + onResultLimitExceeded(uri: string, resultLimit: number, name: string) { + return () => { + let warning = pendingWarnings[uri]; + if (warning) { + if (!warning.timeout) { + // already shown + return; + } + warning.features[name] = name; + warning.timeout.dispose(); + warning.timeout = runtime.timer.setTimeout(() => showLimitedNotification(uri, resultLimit), 2000); + } else { + warning = { features: { [name]: name } }; + warning.timeout = runtime.timer.setTimeout(() => showLimitedNotification(uri, resultLimit), 2000); + pendingWarnings[uri] = warning; + } + }; + } + }; + }(); let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined; let schemaAssociations: ISchemaAssociations | SchemaConfiguration[] | undefined = undefined; let formatterRegistrations: Thenable[] | null = null; let validateEnabled = true; - let keepLinesEnabled = false; - // The settings have changed. Is sent on server activation as well. + // The settings have changed. Is send on server activation as well. connection.onDidChangeConfiguration((change) => { - const settings = change.settings; - runtime.configureHttpRequests?.(settings?.http?.proxy, !!settings.http?.proxyStrictSSL); + let settings = change.settings; + if (runtime.configureHttpRequests) { + runtime.configureHttpRequests(settings?.http?.proxy, !!settings.http?.proxyStrictSSL); + } jsonConfigurationSettings = settings.json?.schemas; validateEnabled = !!settings.json?.validate?.enable; - keepLinesEnabled = settings.json?.keepLines?.enable || false; updateConfiguration(); foldingRangeLimit = Math.trunc(Math.max(settings.json?.resultLimit || foldingRangeLimitDefault, 0)); @@ -257,18 +279,25 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) needsRevalidation = languageService.resetSchema(uriOrUris); } if (needsRevalidation) { - diagnosticsSupport?.requestRefresh(); + for (const doc of documents.all()) { + triggerValidation(doc); + } } }); // Retry schema validation on all open documents - connection.onRequest(ForceValidateRequest.type, async uri => { - const document = documents.get(uri); - if (document) { - updateConfiguration(); - return await validateTextDocument(document); - } - return []; + connection.onRequest(ForceValidateRequest.type, uri => { + return new Promise(resolve => { + const document = documents.get(uri); + if (document) { + updateConfiguration(); + validateTextDocument(document, diagnostics => { + resolve(diagnostics); + }); + } else { + resolve([]); + } + }); }); connection.onRequest(LanguageStatusRequest.type, async uri => { @@ -314,16 +343,72 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) } languageService.configure(languageSettings); - diagnosticsSupport?.requestRefresh(); + // Revalidate any open text documents + documents.all().forEach(triggerValidation); } - async function validateTextDocument(textDocument: TextDocument): Promise { + // The content of a text document has changed. This event is emitted + // when the text document first opened or when its content has changed. + documents.onDidChangeContent((change) => { + limitExceededWarnings.cancel(change.document.uri); + triggerValidation(change.document); + }); + + // a document has closed: clear all diagnostics + documents.onDidClose(event => { + limitExceededWarnings.cancel(event.document.uri); + cleanPendingValidation(event.document); + connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] }); + }); + + const pendingValidationRequests: { [uri: string]: Disposable } = {}; + const validationDelayMs = 300; + + function cleanPendingValidation(textDocument: TextDocument): void { + const request = pendingValidationRequests[textDocument.uri]; + if (request) { + request.dispose(); + delete pendingValidationRequests[textDocument.uri]; + } + } + + function triggerValidation(textDocument: TextDocument): void { + cleanPendingValidation(textDocument); + if (validateEnabled) { + pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(() => { + delete pendingValidationRequests[textDocument.uri]; + validateTextDocument(textDocument); + }, validationDelayMs); + } else { + connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] }); + } + } + + function validateTextDocument(textDocument: TextDocument, callback?: (diagnostics: Diagnostic[]) => void): void { + const respond = (diagnostics: Diagnostic[]) => { + connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); + if (callback) { + callback(diagnostics); + } + }; if (textDocument.getText().length === 0) { - return []; // ignore empty documents + respond([]); // ignore empty documents + return; } const jsonDocument = getJSONDocument(textDocument); + const version = textDocument.version; + const documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'warning' } : { comments: 'error', trailingCommas: 'error' }; - return await languageService.doValidation(textDocument, jsonDocument, documentSettings); + languageService.doValidation(textDocument, jsonDocument, documentSettings).then(diagnostics => { + runtime.timer.setImmediate(() => { + const currDocument = documents.get(textDocument.uri); + if (currDocument && currDocument.version === version) { + respond(diagnostics); // Send the computed diagnostics to VSCode. + } + }); + }, error => { + connection.console.error(formatError(`Error while validating ${textDocument.uri}`, error)); + }); } connection.onDidChangeWatchedFiles((change) => { @@ -335,7 +420,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) } }); if (hasChanges) { - diagnosticsSupport?.requestRefresh(); + documents.all().forEach(triggerValidation); } }); @@ -378,10 +463,11 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) const document = documents.get(documentSymbolParams.textDocument.uri); if (document) { const jsonDocument = getJSONDocument(document); + const onResultLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document symbols'); if (hierarchicalDocumentSymbolSupport) { - return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit }); + return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit, onResultLimitExceeded }); } else { - return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit }); + return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit, onResultLimitExceeded }); } } return []; @@ -389,7 +475,6 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) }); function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] { - options.keepLines = keepLinesEnabled; const document = documents.get(textDocument.uri); if (document) { const edits = languageService.format(document, range ?? getFullRange(document), options); @@ -414,9 +499,9 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) return runSafeAsync(runtime, async () => { const document = documents.get(params.textDocument.uri); if (document) { - + const onResultLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document colors'); const jsonDocument = getJSONDocument(document); - return languageService.findDocumentColors(document, jsonDocument, { resultLimit }); + return languageService.findDocumentColors(document, jsonDocument, { resultLimit, onResultLimitExceeded }); } return []; }, [], `Error while computing document colors for ${params.textDocument.uri}`, token); @@ -437,7 +522,8 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment) return runSafe(runtime, () => { const document = documents.get(params.textDocument.uri); if (document) { - return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit }); + const onRangeLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, foldingRangeLimit, 'folding ranges'); + return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit, onRangeLimitExceeded }); } return null; }, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token); diff --git a/extensions/json-language-features/server/src/languageModelCache.ts b/extensions/json-language-features/server/src/languageModelCache.ts index dfe5bf2f37..461fa24d69 100644 --- a/extensions/json-language-features/server/src/languageModelCache.ts +++ b/extensions/json-language-features/server/src/languageModelCache.ts @@ -18,10 +18,10 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime let cleanupInterval: NodeJS.Timer | undefined = undefined; if (cleanupIntervalTimeInSec > 0) { cleanupInterval = setInterval(() => { - const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000; - const uris = Object.keys(languageModels); - for (const uri of uris) { - const languageModelInfo = languageModels[uri]; + let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000; + let uris = Object.keys(languageModels); + for (let uri of uris) { + let languageModelInfo = languageModels[uri]; if (languageModelInfo.cTime < cutoffTime) { delete languageModels[uri]; nModels--; @@ -32,14 +32,14 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime return { get(document: TextDocument): T { - const version = document.version; - const languageId = document.languageId; - const languageModelInfo = languageModels[document.uri]; + let version = document.version; + let languageId = document.languageId; + let languageModelInfo = languageModels[document.uri]; if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) { languageModelInfo.cTime = Date.now(); return languageModelInfo.languageModel; } - const languageModel = parse(document); + let languageModel = parse(document); languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() }; if (!languageModelInfo) { nModels++; @@ -48,8 +48,8 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime if (nModels === maxEntries) { let oldestTime = Number.MAX_VALUE; let oldestUri = null; - for (const uri in languageModels) { - const languageModelInfo = languageModels[uri]; + for (let uri in languageModels) { + let languageModelInfo = languageModels[uri]; if (languageModelInfo.cTime < oldestTime) { oldestUri = uri; oldestTime = languageModelInfo.cTime; @@ -64,7 +64,7 @@ export function getLanguageModelCache(maxEntries: number, cleanupIntervalTime }, onDocumentRemoved(document: TextDocument) { - const uri = document.uri; + let uri = document.uri; if (languageModels[uri]) { delete languageModels[uri]; nModels--; diff --git a/extensions/json-language-features/server/src/utils/runner.ts b/extensions/json-language-features/server/src/utils/runner.ts index c9ba641cd6..dc7f16415c 100644 --- a/extensions/json-language-features/server/src/utils/runner.ts +++ b/extensions/json-language-features/server/src/utils/runner.ts @@ -8,7 +8,7 @@ import { RuntimeEnvironment } from '../jsonServer'; export function formatError(message: string, err: any): string { if (err instanceof Error) { - const error = err; + let error = err; return `${message}: ${error.message}\n${error.stack}`; } else if (typeof err === 'string') { return `${message}: ${err}`; @@ -47,7 +47,7 @@ export function runSafe(runtime: RuntimeEnvironment, func: () => T, errorV resolve(cancelValue()); } else { try { - const result = func(); + let result = func(); if (token.isCancellationRequested) { resolve(cancelValue()); return; diff --git a/extensions/json-language-features/server/src/utils/strings.ts b/extensions/json-language-features/server/src/utils/strings.ts index 3faef1192e..62346a1da6 100644 --- a/extensions/json-language-features/server/src/utils/strings.ts +++ b/extensions/json-language-features/server/src/utils/strings.ts @@ -7,7 +7,7 @@ * Determines if haystack ends with needle. */ export function endsWith(haystack: string, needle: string): boolean { - const diff = haystack.length - needle.length; + let diff = haystack.length - needle.length; if (diff > 0) { return haystack.lastIndexOf(needle) === diff; } else if (diff === 0) { diff --git a/extensions/json-language-features/server/src/utils/validation.ts b/extensions/json-language-features/server/src/utils/validation.ts deleted file mode 100644 index 417bf63816..0000000000 --- a/extensions/json-language-features/server/src/utils/validation.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken, Connection, Diagnostic, Disposable, DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportKind, TextDocuments } from 'vscode-languageserver'; -import { TextDocument } from 'vscode-json-languageservice'; -import { formatError, runSafeAsync } from './runner'; -import { RuntimeEnvironment } from '../jsonServer'; - -export type Validator = (textDocument: TextDocument) => Promise; -export type DiagnosticsSupport = { - dispose(): void; - requestRefresh(): void; -}; - -export function registerDiagnosticsPushSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { - - const pendingValidationRequests: { [uri: string]: Disposable } = {}; - const validationDelayMs = 500; - - const disposables: Disposable[] = []; - - // The content of a text document has changed. This event is emitted - // when the text document first opened or when its content has changed. - documents.onDidChangeContent(change => { - triggerValidation(change.document); - }, undefined, disposables); - - // a document has closed: clear all diagnostics - documents.onDidClose(event => { - cleanPendingValidation(event.document); - connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] }); - }, undefined, disposables); - - function cleanPendingValidation(textDocument: TextDocument): void { - const request = pendingValidationRequests[textDocument.uri]; - if (request) { - request.dispose(); - delete pendingValidationRequests[textDocument.uri]; - } - } - - function triggerValidation(textDocument: TextDocument): void { - cleanPendingValidation(textDocument); - const request = pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(async () => { - if (request === pendingValidationRequests[textDocument.uri]) { - try { - const diagnostics = await validate(textDocument); - if (request === pendingValidationRequests[textDocument.uri]) { - connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); - } - delete pendingValidationRequests[textDocument.uri]; - } catch (e) { - connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e)); - } - } - }, validationDelayMs); - } - - return { - requestRefresh: () => { - documents.all().forEach(triggerValidation); - }, - dispose: () => { - disposables.forEach(d => d.dispose()); - disposables.length = 0; - const keys = Object.keys(pendingValidationRequests); - for (const key of keys) { - pendingValidationRequests[key].dispose(); - delete pendingValidationRequests[key]; - } - } - }; -} - -export function registerDiagnosticsPullSupport(documents: TextDocuments, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport { - - function newDocumentDiagnosticReport(diagnostics: Diagnostic[]): DocumentDiagnosticReport { - return { - kind: DocumentDiagnosticReportKind.Full, - items: diagnostics - }; - } - - const registration = connection.languages.diagnostics.on(async (params: DocumentDiagnosticParams, token: CancellationToken) => { - return runSafeAsync(runtime, async () => { - const document = documents.get(params.textDocument.uri); - if (document) { - return newDocumentDiagnosticReport(await validate(document)); - } - return newDocumentDiagnosticReport([]); - - }, newDocumentDiagnosticReport([]), `Error while computing diagnostics for ${params.textDocument.uri}`, token); - }); - - function requestRefresh(): void { - connection.languages.diagnostics.refresh(); - } - - return { - requestRefresh, - dispose: () => { - registration.dispose(); - } - }; - -} diff --git a/extensions/json-language-features/server/yarn.lock b/extensions/json-language-features/server/yarn.lock index e0b300c908..5cd1cf5f48 100644 --- a/extensions/json-language-features/server/yarn.lock +++ b/extensions/json-language-features/server/yarn.lock @@ -12,66 +12,61 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== -jsonc-parser@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d" - integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg== +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== request-light@^0.5.8: version "0.5.8" resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.8.tgz#8bf73a07242b9e7b601fac2fa5dc22a094abcc27" integrity sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg== -vscode-json-languageservice@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.1.0.tgz#b1f197a60338cb378189fcb41489a84846724dd9" - integrity sha512-D5612D7h/Gh4A0JmdttPveWzT9dur21WXvBHWKPdOt0sLO6ILz8vN6+IzWnvwDOVAEFTpzIAMVMZwbKZkwGGiA== +vscode-json-languageservice@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz#94b6f471ece193bf4a1ef37f6ab5cce86d50a8b4" + integrity sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA== dependencies: - jsonc-parser "^3.1.0" - vscode-languageserver-textdocument "^1.0.4" - vscode-languageserver-types "^3.17.1" - vscode-nls "^5.0.1" + jsonc-parser "^3.0.0" + vscode-languageserver-textdocument "^1.0.3" + vscode-languageserver-types "^3.16.0" + vscode-nls "^5.0.0" vscode-uri "^3.0.3" -vscode-jsonrpc@8.0.2-next.1: - version "8.0.2-next.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2-next.1.tgz#6bdc39fd194782032e34047eeefce562941259c6" - integrity sha512-sbbvGSWja7NVBLHPGawtgezc8DHYJaP4qfr/AaJiyDapWcSFtHyPtm18+LnYMLTmB7bhOUW/lf5PeeuLpP6bKA== +vscode-jsonrpc@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e" + integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg== -vscode-languageserver-protocol@3.17.2-next.6: - version "3.17.2-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.6.tgz#8f1dc0fcb29366b85f623a3f9af726de433b5fcc" - integrity sha512-WtsebNOOkWyNn4oFYoAMPC8Q/ZDoJ/K7Ja53OzTixiitvrl/RpXZETrtzH79R8P5kqCyx6VFBPb6KQILJfkDkA== +vscode-languageserver-protocol@3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821" + integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A== dependencies: - vscode-jsonrpc "8.0.2-next.1" - vscode-languageserver-types "3.17.2-next.2" + vscode-jsonrpc "6.0.0" + vscode-languageserver-types "3.16.0" -vscode-languageserver-textdocument@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz#3cd56dd14cec1d09e86c4bb04b09a246cb3df157" - integrity sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ== +vscode-languageserver-textdocument@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.3.tgz#879f2649bfa5a6e07bc8b392c23ede2dfbf43eff" + integrity sha512-ynEGytvgTb6HVSUwPJIAZgiHQmPCx8bZ8w5um5Lz+q5DjP0Zj8wTFhQpyg8xaMvefDytw2+HH5yzqS+FhsR28A== -vscode-languageserver-types@3.17.2-next.2: - version "3.17.2-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2-next.2.tgz#af5d6978eee7682aab87c1419323f5b141ac6596" - integrity sha512-TiAkLABgqkVWdAlC3XlOfdhdjIAdVU4YntPUm9kKGbXr+MGwpVnKz2KZMNBcvG0CFx8Hi8qliL0iq+ndPB720w== +vscode-languageserver-types@3.16.0, vscode-languageserver-types@^3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247" + integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA== -vscode-languageserver-types@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16" - integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ== - -vscode-languageserver@^8.0.2-next.5: - version "8.0.2-next.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.5.tgz#39a2dd4c504fb88042375e7ac706a714bdaab4e5" - integrity sha512-2ZDb7O/4atS9mJKufPPz637z+51kCyZfgnobFW5eSrUdS3c0UB/nMS4Ng1EavYTX84GVaVMKCrmP0f2ceLmR0A== +vscode-languageserver@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz#49b068c87cfcca93a356969d20f5d9bdd501c6b0" + integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw== dependencies: - vscode-languageserver-protocol "3.17.2-next.6" + vscode-languageserver-protocol "3.16.0" -vscode-nls@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2" - integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== +vscode-nls@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" + integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== vscode-uri@^3.0.3: version "3.0.3" diff --git a/extensions/json-language-features/yarn.lock b/extensions/json-language-features/yarn.lock index 61f19346fd..98216da36e 100644 --- a/extensions/json-language-features/yarn.lock +++ b/extensions/json-language-features/yarn.lock @@ -2,54 +2,15 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - "@types/node@16.x": version "16.11.6" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.5.0.tgz#8214171e550393d577fc56326fa986c6800b831b" + integrity sha512-27FsgeVJvC4zVw7Ar3Ub+7vJswDt8RoBFpbgBwf8Xq/B2gaT8G6a+gkw3s2pQmjWGIqyu7TRA8e9rS8/vxv6NQ== balanced-match@^1.0.0: version "1.0.0" @@ -88,44 +49,44 @@ request-light@^0.5.8: resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.8.tgz#8bf73a07242b9e7b601fac2fa5dc22a094abcc27" integrity sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg== -semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +semver@^7.3.4: + version "7.3.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" + integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== dependencies: lru-cache "^6.0.0" -vscode-jsonrpc@8.0.2-next.1: - version "8.0.2-next.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2-next.1.tgz#6bdc39fd194782032e34047eeefce562941259c6" - integrity sha512-sbbvGSWja7NVBLHPGawtgezc8DHYJaP4qfr/AaJiyDapWcSFtHyPtm18+LnYMLTmB7bhOUW/lf5PeeuLpP6bKA== +vscode-jsonrpc@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e" + integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg== -vscode-languageclient@^8.0.2-next.5: - version "8.0.2-next.5" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.2-next.5.tgz#3238a388585c3119e247f761b4355273cc2fd909" - integrity sha512-g87RJLHz0XlRyk6DOTbAk4JHcj8CKggXy4JiFL7OlhETkcYzTOR8d+Qdb4GqZr37PDs1Cl21omtTNK5LyR/RQg== +vscode-languageclient@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz#b505c22c21ffcf96e167799757fca07a6bad0fb2" + integrity sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg== dependencies: minimatch "^3.0.4" - semver "^7.3.5" - vscode-languageserver-protocol "3.17.2-next.6" + semver "^7.3.4" + vscode-languageserver-protocol "3.16.0" -vscode-languageserver-protocol@3.17.2-next.6: - version "3.17.2-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.6.tgz#8f1dc0fcb29366b85f623a3f9af726de433b5fcc" - integrity sha512-WtsebNOOkWyNn4oFYoAMPC8Q/ZDoJ/K7Ja53OzTixiitvrl/RpXZETrtzH79R8P5kqCyx6VFBPb6KQILJfkDkA== +vscode-languageserver-protocol@3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821" + integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A== dependencies: - vscode-jsonrpc "8.0.2-next.1" - vscode-languageserver-types "3.17.2-next.2" + vscode-jsonrpc "6.0.0" + vscode-languageserver-types "3.16.0" -vscode-languageserver-types@3.17.2-next.2: - version "3.17.2-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2-next.2.tgz#af5d6978eee7682aab87c1419323f5b141ac6596" - integrity sha512-TiAkLABgqkVWdAlC3XlOfdhdjIAdVU4YntPUm9kKGbXr+MGwpVnKz2KZMNBcvG0CFx8Hi8qliL0iq+ndPB720w== +vscode-languageserver-types@3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247" + integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA== -vscode-nls@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2" - integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== +vscode-nls@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" + integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== yallist@^4.0.0: version "4.0.0" diff --git a/extensions/json/language-configuration.json b/extensions/json/language-configuration.json index f9ec3fec78..8f270cd2b2 100644 --- a/extensions/json/language-configuration.json +++ b/extensions/json/language-configuration.json @@ -15,8 +15,9 @@ { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, { "open": "`", "close": "`", "notIn": ["string", "comment"] } ], + "wordPattern": "(\"(?:[^\\\\\\\"]*(?:\\\\.)?)*\"?)|[^\\s{}\\[\\],:]+", "indentationRules": { - "increaseIndentPattern": "({+(?=((\\\\.|[^\"\\\\])*\"(\\\\.|[^\"\\\\])*\")*[^\"}]*)$)|(\\[+(?=((\\\\.|[^\"\\\\])*\"(\\\\.|[^\"\\\\])*\")*[^\"\\]]*)$)", + "increaseIndentPattern": "({+(?=([^\"]*\"[^\"]*\")*[^\"}]*$))|(\\[+(?=([^\"]*\"[^\"]*\")*[^\"\\]]*$))", "decreaseIndentPattern": "^\\s*[}\\]],?\\s*$" } } diff --git a/extensions/markdown-basics/cgmanifest.json b/extensions/markdown-basics/cgmanifest.json index 46b4bae228..0a50694d7e 100644 --- a/extensions/markdown-basics/cgmanifest.json +++ b/extensions/markdown-basics/cgmanifest.json @@ -33,7 +33,7 @@ "git": { "name": "microsoft/vscode-markdown-tm-grammar", "repositoryUrl": "https://github.com/microsoft/vscode-markdown-tm-grammar", - "commitHash": "69d3321b4923ca2d5e8e900018887cc38b5fe04a" + "commitHash": "b068fcb2fbfa834e695505bfb02bbcc0b4edab8b" } }, "license": "MIT", diff --git a/extensions/markdown-basics/package.json b/extensions/markdown-basics/package.json index 69e4da10d2..281443efc2 100644 --- a/extensions/markdown-basics/package.json +++ b/extensions/markdown-basics/package.json @@ -67,7 +67,6 @@ "meta.embedded.block.javascript": "javascript", "meta.embedded.block.json": "json", "meta.embedded.block.jsonc": "jsonc", - "meta.embedded.block.latex": "latex", "meta.embedded.block.less": "less", "meta.embedded.block.objc": "objc", "meta.embedded.block.scss": "scss", @@ -92,8 +91,8 @@ ], "configurationDefaults": { "[markdown]": { - "editor.unicodeHighlight.ambiguousCharacters": false, - "editor.unicodeHighlight.invisibleCharacters": false + "editor.unicodeHighlight.ambiguousCharacters": false, + "editor.unicodeHighlight.invisibleCharacters": false } } }, diff --git a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json index 895836a188..a0dfdc270f 100644 --- a/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json +++ b/extensions/markdown-basics/syntaxes/markdown.tmLanguage.json @@ -4,7 +4,7 @@ "If you want to provide a fix or improvement, please create a pull request against the original repository.", "Once accepted there, we are happy to receive an update request." ], - "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/69d3321b4923ca2d5e8e900018887cc38b5fe04a", + "version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/b068fcb2fbfa834e695505bfb02bbcc0b4edab8b", "name": "Markdown", "scopeName": "text.html.markdown", "patterns": [ @@ -2774,50 +2774,47 @@ "5": { "name": "punctuation.definition.metadata.markdown" }, - "7": { + "6": { "name": "punctuation.definition.link.markdown" }, - "8": { + "7": { "name": "markup.underline.link.markdown" }, "9": { "name": "punctuation.definition.link.markdown" }, "10": { - "name": "markup.underline.link.markdown" + "name": "string.other.link.description.title.markdown" + }, + "11": { + "name": "punctuation.definition.string.begin.markdown" }, "12": { - "name": "string.other.link.description.title.markdown" + "name": "punctuation.definition.string.end.markdown" }, "13": { - "name": "punctuation.definition.string.begin.markdown" + "name": "string.other.link.description.title.markdown" }, "14": { - "name": "punctuation.definition.string.end.markdown" + "name": "punctuation.definition.string.begin.markdown" }, "15": { - "name": "string.other.link.description.title.markdown" + "name": "punctuation.definition.string.end.markdown" }, "16": { - "name": "punctuation.definition.string.begin.markdown" - }, - "17": { - "name": "punctuation.definition.string.end.markdown" - }, - "18": { "name": "string.other.link.description.title.markdown" }, - "19": { + "17": { "name": "punctuation.definition.string.begin.markdown" }, - "20": { + "18": { "name": "punctuation.definition.string.end.markdown" }, - "21": { + "19": { "name": "punctuation.definition.metadata.markdown" } }, - "match": "(?x)\n (\\[)((?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])\n # Match the link text.\n (\\() # Opening paren for url\n # The url\n [ \\t]*\n (\n (<)([^<>\\n]*)(>)\n | ((?(?>[^\\s()]+)|\\(\\g*\\))*)\n )\n [ \\t]*\n # The title \n (?:\n ((\\()[^()]*(\\))) # Match title in parens…\n | ((\")[^\"]*(\")) # or in double quotes…\n | ((')[^']*(')) # or in single quotes.\n )? # Title is optional\n \\s* # Optional whitespace\n (\\))\n", + "match": "(?x)\n (\\[)((?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])\n # Match the link text.\n (\\() # Opening paren for url\n ((?>[^\\s()]+)|\\(\\g*\\))*)(>?) # The url\n [ \\t]* # Optional whitespace\n (?:\n ((\\().+?(\\))) # Match title in parens…\n | ((\").+?(\")) # or in double quotes…\n | ((').+?(')) # or in single quotes.\n )? # Title is optional\n \\s* # Optional whitespace\n (\\))\n", "name": "meta.link.inline.markdown" }, "link-ref": { @@ -2841,7 +2838,7 @@ "name": "punctuation.definition.constant.end.markdown" } }, - "match": "(?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])(\\[)([^\\]]*+)(\\])", + "match": "(\\[)((?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])(\\[)([^\\]]*+)(\\])", "name": "meta.link.reference.markdown" }, "link-ref-literal": { @@ -2862,7 +2859,7 @@ "name": "punctuation.definition.constant.end.markdown" } }, - "match": "(?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])[ ]?(\\[)(\\])", + "match": "(\\[)((?[^\\[\\]\\\\]|\\\\.|\\[\\g*+\\])*+)(\\])[ ]?(\\[)(\\])", "name": "meta.link.reference.literal.markdown" }, "link-ref-shortcut": { @@ -2877,7 +2874,7 @@ "name": "punctuation.definition.link.title.end.markdown" } }, - "match": "(? = (ctx) => { @@ -127,7 +26,6 @@ export const activate: ActivationFunction = (ctx) => { markdownIt.linkify.set({ fuzzyLink: false }); addNamedHeaderRendering(markdownIt); - addLinkRenderer(markdownIt); const style = document.createElement('style'); style.textContent = ` @@ -308,9 +206,7 @@ export const activate: ActivationFunction = (ctx) => { previewNode.classList.remove('emptyMarkdownCell'); const markdownText = outputInfo.mime.startsWith('text/x-') ? `\`\`\`${outputInfo.mime.substr(7)}\n${text}\n\`\`\`` : (outputInfo.mime.startsWith('application/') ? `\`\`\`${outputInfo.mime.substr(12)}\n${text}\n\`\`\`` : text); - const unsanitizedRenderedMarkdown = markdownIt.render(markdownText, { - outputItem: outputInfo, - }); + const unsanitizedRenderedMarkdown = markdownIt.render(markdownText); previewNode.innerHTML = (ctx.workspace.isTrusted ? unsanitizedRenderedMarkdown : DOMPurify.sanitize(unsanitizedRenderedMarkdown, sanitizerOptions)) as string; @@ -329,12 +225,12 @@ function addNamedHeaderRendering(md: InstanceType): void { const originalHeaderOpen = md.renderer.rules.heading_open; md.renderer.rules.heading_open = (tokens: MarkdownItToken[], idx: number, options, env, self) => { const title = tokens[idx + 1].children!.reduce((acc, t) => acc + t.content, ''); - let slug = slugify(title); + let slug = slugFromHeading(title); if (slugCounter.has(slug)) { const count = slugCounter.get(slug)!; slugCounter.set(slug, count + 1); - slug = slugify(slug + '-' + (count + 1)); + slug = slugFromHeading(slug + '-' + (count + 1)); } else { slugCounter.set(slug, 0); } @@ -355,26 +251,9 @@ function addNamedHeaderRendering(md: InstanceType): void { }; } -function addLinkRenderer(md: MarkdownIt): void { - const original = md.renderer.rules.link_open; - - md.renderer.rules.link_open = (tokens: MarkdownItToken[], idx: number, options, env, self) => { - const token = tokens[idx]; - const href = token.attrGet('href'); - if (typeof href === 'string' && href.startsWith('#')) { - token.attrSet('href', '#' + slugify(href.slice(1))); - } - if (original) { - return original(tokens, idx, options, env, self); - } else { - return self.renderToken(tokens, idx, options); - } - }; -} - -function slugify(text: string): string { +function slugFromHeading(heading: string): string { const slugifiedHeading = encodeURI( - text.trim() + heading.trim() .toLowerCase() .replace(/\s+/g, '-') // Replace whitespace with - // allow-any-unicode-next-line diff --git a/extensions/markdown-language-features/package.json b/extensions/markdown-language-features/package.json index 952abb1a46..35aab1cc38 100644 --- a/extensions/markdown-language-features/package.json +++ b/extensions/markdown-language-features/package.json @@ -6,7 +6,7 @@ "icon": "icon.png", "publisher": "vscode", "license": "MIT", - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "^1.20.0" }, @@ -16,7 +16,7 @@ "Programming Languages" ], "enabledApiProposals": [ - "documentPaste" + "textEditorDrop" ], "activationEvents": [ "onLanguage:markdown", @@ -46,7 +46,7 @@ "contributes": { "notebookRenderer": [ { - "id": "vscode.markdown-it-renderer", + "id": "markdownItRenderer", "displayName": "Markdown it renderer", "entrypoint": "./notebook-out/index.js", "mimeTypes": [ @@ -398,116 +398,59 @@ "description": "%configuration.markdown.suggest.paths.enabled.description%", "scope": "resource" }, - "markdown.trace.extension": { + "markdown.trace": { "type": "string", "enum": [ "off", "verbose" ], "default": "off", - "description": "%markdown.trace.extension.desc%", + "description": "%markdown.trace.desc%", "scope": "window" }, - "markdown.trace.server": { - "type": "string", - "scope": "window", - "enum": [ - "off", - "messages", - "verbose" - ], - "default": "off", - "description": "%markdown.trace.server.desc%" - }, "markdown.editor.drop.enabled": { "type": "boolean", "default": true, "markdownDescription": "%configuration.markdown.editor.drop.enabled%", "scope": "resource" }, - "markdown.experimental.editor.pasteLinks.enabled": { - "type": "boolean", - "scope": "resource", - "markdownDescription": "%configuration.markdown.editor.pasteLinks.enabled%", - "default": true, - "tags": [ - "experimental" - ] - }, "markdown.experimental.validate.enabled": { "type": "boolean", "scope": "resource", "description": "%configuration.markdown.experimental.validate.enabled.description%", - "default": false, - "tags": [ - "experimental" - ] + "default": false }, - "markdown.experimental.validate.referenceLinks.enabled": { + "markdown.experimental.validate.referenceLinks": { "type": "string", "scope": "resource", - "markdownDescription": "%configuration.markdown.experimental.validate.referenceLinks.enabled.description%", + "description": "%configuration.markdown.experimental.validate.referenceLinks.description%", "default": "warning", "enum": [ "ignore", "warning", "error" - ], - "tags": [ - "experimental" ] }, - "markdown.experimental.validate.fragmentLinks.enabled": { + "markdown.experimental.validate.headerLinks": { "type": "string", "scope": "resource", - "markdownDescription": "%configuration.markdown.experimental.validate.fragmentLinks.enabled.description%", + "description": "%configuration.markdown.experimental.validate.headerLinks.description%", "default": "warning", "enum": [ "ignore", "warning", "error" - ], - "tags": [ - "experimental" ] }, - "markdown.experimental.validate.fileLinks.enabled": { + "markdown.experimental.validate.fileLinks": { "type": "string", "scope": "resource", - "markdownDescription": "%configuration.markdown.experimental.validate.fileLinks.enabled.description%", + "description": "%configuration.markdown.experimental.validate.fileLinks.description%", "default": "warning", "enum": [ "ignore", "warning", "error" - ], - "tags": [ - "experimental" - ] - }, - "markdown.experimental.validate.fileLinks.markdownFragmentLinks": { - "type": "string", - "scope": "resource", - "markdownDescription": "%configuration.markdown.experimental.validate.fileLinks.markdownFragmentLinks.description%", - "default": "ignore", - "enum": [ - "ignore", - "warning", - "error" - ], - "tags": [ - "experimental" - ] - }, - "markdown.experimental.validate.ignoreLinks": { - "type": "array", - "scope": "resource", - "markdownDescription": "%configuration.markdown.experimental.validate.ignoreLinks.description%", - "items": { - "type": "string" - }, - "tags": [ - "experimental" ] } } @@ -545,8 +488,8 @@ ] }, "scripts": { - "compile": "gulp compile-extension:markdown-language-features-languageService && gulp compile-extension:markdown-language-features-server && gulp compile-extension:markdown-language-features && npm run build-preview && npm run build-notebook", - "watch": "npm run build-preview && gulp watch-extension:markdown-language-features watch-extension:markdown-language-features-languageService watch-extension:markdown-language-features-server", + "compile": "gulp compile-extension:markdown-language-features && npm run build-preview && npm run build-notebook", + "watch": "npm run build-preview && gulp watch-extension:markdown-language-features", "vscode:prepublish": "npm run build-ext && npm run build-preview", "build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:markdown-language-features ./tsconfig.json", "build-notebook": "node ./esbuild-notebook", @@ -555,14 +498,12 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.6.2", - "dompurify": "^2.3.3", + "@vscode/extension-telemetry": "0.4.10", + "dompurify": "^2.3.1", "highlight.js": "^11.4.0", "markdown-it": "^12.3.2", "markdown-it-front-matter": "^0.2.1", "morphdom": "^2.6.1", - "picomatch": "^2.3.1", - "vscode-languageclient": "^8.0.1", "vscode-languageserver-textdocument": "^1.0.4", "vscode-nls": "^5.0.0", "vscode-uri": "^3.0.3" @@ -571,12 +512,9 @@ "@types/dompurify": "^2.3.1", "@types/lodash.throttle": "^4.1.3", "@types/markdown-it": "12.2.3", - "@types/picomatch": "^2.3.0", "@types/vscode-notebook-renderer": "^1.60.0", "@types/vscode-webview": "^1.57.0", - "lodash.throttle": "^4.1.1", - "vscode-languageserver-types": "^3.17.2", - "vscode-markdown-languageservice": "^0.0.0-alpha.10" + "lodash.throttle": "^4.1.1" }, "repository": { "type": "git", diff --git a/extensions/markdown-language-features/package.nls.json b/extensions/markdown-language-features/package.nls.json index 1c32e447e0..2d9ba25800 100644 --- a/extensions/markdown-language-features/package.nls.json +++ b/extensions/markdown-language-features/package.nls.json @@ -17,8 +17,7 @@ "markdown.showSource.title": "Show Source", "markdown.styles.dec": "A list of URLs or local paths to CSS style sheets to use from the Markdown preview. Relative paths are interpreted relative to the folder open in the Explorer. If there is no open folder, they are interpreted relative to the location of the Markdown file. All '\\' need to be written as '\\\\'.", "markdown.showPreviewSecuritySelector.title": "Change Preview Security Settings", - "markdown.trace.extension.desc": "Enable debug logging for the Markdown extension.", - "markdown.trace.server.desc": "Traces the communication between VS Code and the Markdown language server.", + "markdown.trace.desc": "Enable debug logging for the Markdown extension.", "markdown.preview.refresh.title": "Refresh Preview", "markdown.preview.toggleLock.title": "Toggle Preview Locking", "markdown.findAllFileReferences": "Find File References", @@ -29,13 +28,10 @@ "configuration.markdown.links.openLocation.currentGroup": "Open links in the active editor group.", "configuration.markdown.links.openLocation.beside": "Open links beside the active editor.", "configuration.markdown.suggest.paths.enabled.description": "Enable/disable path suggestions for markdown links", - "configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#editor.dropIntoEditor.enabled#`.", - "configuration.markdown.editor.pasteLinks.enabled": "Enable/disable pasting files into a Markdown editor inserts Markdown links. Requires enabling `#editor.experimental.pasteActions.enabled#`.", + "configuration.markdown.editor.drop.enabled": "Enable/disable dropping into the markdown editor to insert shift. Requires enabling `#workbenck.experimental.editor.dropIntoEditor.enabled#`.", "configuration.markdown.experimental.validate.enabled.description": "Enable/disable all error reporting in Markdown files.", - "configuration.markdown.experimental.validate.referenceLinks.enabled.description": "Validate reference links in Markdown files, e.g. `[link][ref]`. Requires enabling `#markdown.experimental.validate.enabled#`.", - "configuration.markdown.experimental.validate.fragmentLinks.enabled.description": "Validate fragment links to headers in the current Markdown file, e.g. `[link](#header)`. Requires enabling `#markdown.experimental.validate.enabled#`.", - "configuration.markdown.experimental.validate.fileLinks.enabled.description": "Validate links to other files in Markdown files, e.g. `[link](/path/to/file.md)`. This checks that the target files exists. Requires enabling `#markdown.experimental.validate.enabled#`.", - "configuration.markdown.experimental.validate.fileLinks.markdownFragmentLinks.description": "Validate the fragment part of links to headers in other files in Markdown files, e.g. `[link](/path/to/file.md#header)`. Inherits the setting value from `#markdown.experimental.validate.fragmentLinks.enabled#` by default.", - "configuration.markdown.experimental.validate.ignoreLinks.description": "Configure links that should not be validated. For example `/about` would not validate the link `[about](/about)`, while the glob `/assets/**/*.svg` would let you skip validation for any link to `.svg` files under the `assets` directory.", + "configuration.markdown.experimental.validate.referenceLinks.description": "Validate reference links in Markdown files, e.g. `[link][ref]`. Requires enabling `#markdown.experimental.validate.enabled#`.", + "configuration.markdown.experimental.validate.headerLinks.description": "Validate links to headers in Markdown files, e.g. `[link](#header)`. Requires enabling `#markdown.experimental.validate.enabled#`.", + "configuration.markdown.experimental.validate.fileLinks.description": "Validate links to other files in Markdown files, e.g. `[link](/path/to/file.md)`. This checks that the target files exists. Requires enabling `#markdown.experimental.validate.enabled#`.", "workspaceTrust": "Required for loading styles configured in the workspace." } diff --git a/extensions/markdown-language-features/preview-src/loading.ts b/extensions/markdown-language-features/preview-src/loading.ts index 9a797632dc..4c833c28ad 100644 --- a/extensions/markdown-language-features/preview-src/loading.ts +++ b/extensions/markdown-language-features/preview-src/loading.ts @@ -29,7 +29,9 @@ export class StyleLoadingMonitor { return; } this.finishedLoading = true; - this.poster?.postMessage('previewStyleLoadError', { unloadedStyles: this.unloadedStyles }); + if (this.poster) { + this.poster.postMessage('previewStyleLoadError', { unloadedStyles: this.unloadedStyles }); + } }); } diff --git a/extensions/markdown-language-features/server/.npmignore b/extensions/markdown-language-features/server/.npmignore deleted file mode 100644 index bfd4215998..0000000000 --- a/extensions/markdown-language-features/server/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -.vscode/ -.github/ -out/test/ -src/ -.eslintrc.js -.gitignore -tsconfig*.json -*.tsbuildinfo -*.map -example.cjs -CODE_OF_CONDUCT.md -SECURITY.md \ No newline at end of file diff --git a/extensions/markdown-language-features/server/.vscode/launch.json b/extensions/markdown-language-features/server/.vscode/launch.json deleted file mode 100644 index fd9033bffa..0000000000 --- a/extensions/markdown-language-features/server/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": "0.1.0", - // List of configurations. Add new configurations or edit existing ones. - "configurations": [ - { - "name": "Attach", - "type": "node", - "request": "attach", - "port": 7997, - "sourceMaps": true, - "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ] - } - ] -} \ No newline at end of file diff --git a/extensions/markdown-language-features/server/.vscode/settings.json b/extensions/markdown-language-features/server/.vscode/settings.json deleted file mode 100644 index 7a73a41bfd..0000000000 --- a/extensions/markdown-language-features/server/.vscode/settings.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} \ No newline at end of file diff --git a/extensions/markdown-language-features/server/.vscode/tasks.json b/extensions/markdown-language-features/server/.vscode/tasks.json deleted file mode 100644 index ecc951a7ba..0000000000 --- a/extensions/markdown-language-features/server/.vscode/tasks.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "2.0.0", - "command": "npm", - "args": [ - "run", - "watch" - ], - "isBackground": true, - "problemMatcher": "$tsc-watch", - "tasks": [ - { - "label": "npm", - "type": "shell", - "command": "npm", - "args": [ - "run", - "watch" - ], - "isBackground": true, - "problemMatcher": "$tsc-watch", - "group": { - "_id": "build", - "isDefault": false - } - } - ] -} \ No newline at end of file diff --git a/extensions/markdown-language-features/server/README.md b/extensions/markdown-language-features/server/README.md deleted file mode 100644 index de4e33926c..0000000000 --- a/extensions/markdown-language-features/server/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# Markdown Language Server - -> **❗ Import** This is still in development. While the language server is being used by VS Code, it has not yet been tested with other clients. - -The Markdown language server powers VS Code's built-in markdown support, providing tools for writing and browsing Markdown files. It runs as a separate executable and implements the [language server protocol](https://microsoft.github.io/language-server-protocol/overview). - -This server uses the [Markdown Language Service](https://github.com/microsoft/vscode-markdown-languageservice) to implement almost all of the language features. You can use that library if you need a library for working with Markdown instead of a full language server. - - -## Server capabilities - -- [Completions](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion) for Markdown links. - -- [Folding](https://microsoft.github.io/language-server-protocol/specification#textDocument_foldingRange) of Markdown regions, block elements, and header sections. - -- [Smart selection](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_selectionRange) for inline elements, block elements, and header sections. - -- [Document Symbols](https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol) for quick navigation to headers in a document. - -- [Workspace Symbols](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_symbol) for quick navigation to headers in the workspace - -- [Document links](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentLink) for making Markdown links in a document clickable. - -- [Find all references](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_references) to headers and links across all Markdown files in the workspace. - -- [Rename](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_rename) of headers and links across all Markdown files in the workspace. - -- [Go to definition](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_definition) from links to headers or link definitions. - -- (experimental) [Pull diagnostics (validation)](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics) for links. - - - -## Client requirements - -### Initialization options - -The client can send the following initialization options to the server: - -- `markdownFileExtensions` Array file extensions that should be considered as Markdown. These should not include the leading `.`. For example: `['md', 'mdown', 'markdown']`. - -### Settings - -Clients may send a `workspace/didChangeConfiguration` notification to notify the server of settings changes. -The server supports the following settings: - -- `markdown` - - `suggest` - - `paths` - - `enabled` — Enable/disable path suggestions. - - `experimental` - - `validate` - - `enabled` — Enable/disable all validation. - - `referenceLinks` - - `enabled` — Enable/disable validation of reference links: `[text][ref]` - - `fragmentLinks` - - `enabled` — Enable/disable validation of links to fragments in the current files: `[text](#head)` - - `fileLinks` - - `enabled` — Enable/disable validation of links to file in the workspace. - - `markdownFragmentLinks` — Enable/disable validation of links to headers in other Markdown files. - - `ignoreLinks` — Array of glob patterns for files that should not be validated. - -### Custom requests - -To support all of the features of the language server, the client needs to implement a few custom request types. The definitions of these request types can be found in [`protocol.ts`](./src/protocol.ts) - -#### `markdown/parse` - -Get the tokens for a Markdown file. Clients are expected to use [Markdown-it](https://github.com/markdown-it/markdown-it) for this. - -We require that clients bring their own version of Markdown-it so that they can customize/extend Markdown-it. - -#### `markdown/fs/readFile` - -Read the contents of a file in the workspace. - -#### `markdown/fs/readDirectory` - -Read the contents of a directory in the workspace. - -#### `markdown/fs/stat` - -Check if a given file/directory exists in the workspace. - -#### `markdown/fs/watcher/create` - -Create a file watcher. This is needed for diagnostics support. - -#### `markdown/fs/watcher/delete` - -Delete a previously created file watcher. - -#### `markdown/findMarkdownFilesInWorkspace` - -Get a list of all markdown files in the workspace. - - -## Contribute - -The source code of the Markdown language server can be found in the [VSCode repository](https://github.com/microsoft/vscode) at [extensions/markdown-language-features/server](https://github.com/microsoft/vscode/tree/master/extensions/markdown-language-features/server). - -File issues and pull requests in the [VSCode GitHub Issues](https://github.com/microsoft/vscode/issues). See the document [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) on how to build and run from source. - -Most of the functionality of the server is located in libraries: - -- [vscode-markdown-languageservice](https://github.com/microsoft/vscode-markdown-languageservice) contains the implementation of all features as a reusable library. -- [vscode-languageserver-node](https://github.com/microsoft/vscode-languageserver-node) contains the implementation of language server for NodeJS. - -Help on any of these projects is very welcome. - -## Code of Conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -## License - -Copyright (c) Microsoft Corporation. All rights reserved. - -Licensed under the [MIT](https://github.com/microsoft/vscode/blob/master/LICENSE.txt) License. - diff --git a/extensions/markdown-language-features/server/extension-browser.webpack.config.js b/extensions/markdown-language-features/server/extension-browser.webpack.config.js deleted file mode 100644 index 6a9bd10794..0000000000 --- a/extensions/markdown-language-features/server/extension-browser.webpack.config.js +++ /dev/null @@ -1,24 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -//@ts-check - -'use strict'; - -const withBrowserDefaults = require('../../shared.webpack.config').browser; -const path = require('path'); - -module.exports = withBrowserDefaults({ - context: __dirname, - entry: { - extension: './src/browser/main.ts', - }, - output: { - filename: 'main.js', - path: path.join(__dirname, 'dist', 'browser'), - libraryTarget: 'var', - library: 'serverExportVar' - } -}); diff --git a/extensions/markdown-language-features/server/extension.webpack.config.js b/extensions/markdown-language-features/server/extension.webpack.config.js deleted file mode 100644 index 6b4fdccfea..0000000000 --- a/extensions/markdown-language-features/server/extension.webpack.config.js +++ /dev/null @@ -1,22 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -//@ts-check - -'use strict'; - -const withDefaults = require('../../shared.webpack.config'); -const path = require('path'); - -module.exports = withDefaults({ - context: path.join(__dirname), - entry: { - extension: './src/node/main.ts', - }, - output: { - filename: 'main.js', - path: path.join(__dirname, 'dist', 'node'), - } -}); diff --git a/extensions/markdown-language-features/server/package.json b/extensions/markdown-language-features/server/package.json deleted file mode 100644 index a6ef241f4f..0000000000 --- a/extensions/markdown-language-features/server/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "vscode-markdown-languageserver", - "description": "Markdown language server", - "version": "0.0.0-alpha-1", - "author": "Microsoft Corporation", - "license": "MIT", - "engines": { - "node": "*" - }, - "main": "./out/node/main", - "browser": "./dist/browser/main", - "dependencies": { - "vscode-languageserver": "^8.0.2-next.5`", - "vscode-languageserver-textdocument": "^1.0.5", - "vscode-languageserver-types": "^3.17.1", - "vscode-markdown-languageservice": "^0.0.0-alpha.12", - "vscode-uri": "^3.0.3" - }, - "devDependencies": { - "@types/node": "16.x" - }, - "scripts": { - "compile": "gulp compile-extension:markdown-language-features-server", - "watch": "gulp watch-extension:markdown-language-features-server" - } -} diff --git a/extensions/markdown-language-features/server/src/browser/main.ts b/extensions/markdown-language-features/server/src/browser/main.ts deleted file mode 100644 index 8caa4c51e3..0000000000 --- a/extensions/markdown-language-features/server/src/browser/main.ts +++ /dev/null @@ -1,16 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { BrowserMessageReader, BrowserMessageWriter, createConnection } from 'vscode-languageserver/browser'; -import { startServer } from '../server'; - -declare let self: any; - -const messageReader = new BrowserMessageReader(self); -const messageWriter = new BrowserMessageWriter(self); - -const connection = createConnection(messageReader, messageWriter); - -startServer(connection); diff --git a/extensions/markdown-language-features/server/src/config.ts b/extensions/markdown-language-features/server/src/config.ts deleted file mode 100644 index 1da18dfe3a..0000000000 --- a/extensions/markdown-language-features/server/src/config.ts +++ /dev/null @@ -1,24 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface LsConfiguration { - /** - * List of file extensions should be considered as markdown. - * - * These should not include the leading `.`. - */ - readonly markdownFileExtensions: readonly string[]; -} - -const defaultConfig: LsConfiguration = { - markdownFileExtensions: ['md'], -}; - -export function getLsConfiguration(overrides: Partial): LsConfiguration { - return { - ...defaultConfig, - ...overrides, - }; -} diff --git a/extensions/markdown-language-features/server/src/configuration.ts b/extensions/markdown-language-features/server/src/configuration.ts deleted file mode 100644 index f63656a1ed..0000000000 --- a/extensions/markdown-language-features/server/src/configuration.ts +++ /dev/null @@ -1,59 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Connection, Emitter } from 'vscode-languageserver'; -import { Disposable } from './util/dispose'; - -export type ValidateEnabled = 'ignore' | 'warning' | 'error'; - -interface Settings { - readonly markdown: { - readonly suggest: { - readonly paths: { - readonly enabled: boolean; - }; - }; - - readonly experimental: { - readonly validate: { - readonly enabled: true; - readonly referenceLinks: { - readonly enabled: ValidateEnabled; - }; - readonly fragmentLinks: { - readonly enabled: ValidateEnabled; - }; - readonly fileLinks: { - readonly enabled: ValidateEnabled; - readonly markdownFragmentLinks: ValidateEnabled; - }; - readonly ignoreLinks: readonly string[]; - }; - }; - }; -} - - -export class ConfigurationManager extends Disposable { - - private readonly _onDidChangeConfiguration = this._register(new Emitter()); - public readonly onDidChangeConfiguration = this._onDidChangeConfiguration.event; - - private _settings?: Settings; - - constructor(connection: Connection) { - super(); - - // The settings have changed. Is send on server activation as well. - this._register(connection.onDidChangeConfiguration((change) => { - this._settings = change.settings; - this._onDidChangeConfiguration.fire(this._settings!); - })); - } - - public getSettings(): Settings | undefined { - return this._settings; - } -} diff --git a/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts deleted file mode 100644 index 11950bcc5e..0000000000 --- a/extensions/markdown-language-features/server/src/languageFeatures/diagnostics.ts +++ /dev/null @@ -1,95 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Connection, FullDocumentDiagnosticReport, UnchangedDocumentDiagnosticReport } from 'vscode-languageserver'; -import * as md from 'vscode-markdown-languageservice'; -import { disposeAll } from 'vscode-markdown-languageservice/out/util/dispose'; -import { Disposable } from 'vscode-notebook-renderer/events'; -import { URI } from 'vscode-uri'; -import { ConfigurationManager, ValidateEnabled } from '../configuration'; -import { VsCodeClientWorkspace } from '../workspace'; - -const defaultDiagnosticOptions: md.DiagnosticOptions = { - validateFileLinks: md.DiagnosticLevel.ignore, - validateReferences: md.DiagnosticLevel.ignore, - validateFragmentLinks: md.DiagnosticLevel.ignore, - validateMarkdownFileLinkFragments: md.DiagnosticLevel.ignore, - ignoreLinks: [], -}; - -function convertDiagnosticLevel(enabled: ValidateEnabled): md.DiagnosticLevel | undefined { - switch (enabled) { - case 'error': return md.DiagnosticLevel.error; - case 'warning': return md.DiagnosticLevel.warning; - case 'ignore': return md.DiagnosticLevel.ignore; - default: return md.DiagnosticLevel.ignore; - } -} - -function getDiagnosticsOptions(config: ConfigurationManager): md.DiagnosticOptions { - const settings = config.getSettings(); - if (!settings) { - return defaultDiagnosticOptions; - } - - return { - validateFileLinks: convertDiagnosticLevel(settings.markdown.experimental.validate.fileLinks.enabled), - validateReferences: convertDiagnosticLevel(settings.markdown.experimental.validate.referenceLinks.enabled), - validateFragmentLinks: convertDiagnosticLevel(settings.markdown.experimental.validate.fragmentLinks.enabled), - validateMarkdownFileLinkFragments: convertDiagnosticLevel(settings.markdown.experimental.validate.fileLinks.markdownFragmentLinks), - ignoreLinks: settings.markdown.experimental.validate.ignoreLinks, - }; -} - -export function registerValidateSupport( - connection: Connection, - workspace: VsCodeClientWorkspace, - ls: md.IMdLanguageService, - config: ConfigurationManager, -): Disposable { - let diagnosticOptions: md.DiagnosticOptions = defaultDiagnosticOptions; - function updateDiagnosticsSetting(): void { - diagnosticOptions = getDiagnosticsOptions(config); - } - - - const subs: Disposable[] = []; - const manager = ls.createPullDiagnosticsManager(); - subs.push(manager); - - subs.push(manager.onLinkedToFileChanged(() => { - // TODO: We only need to refresh certain files - connection.languages.diagnostics.refresh(); - })); - - connection.languages.diagnostics.on(async (params, token): Promise => { - if (!config.getSettings()?.markdown.experimental.validate.enabled) { - return { kind: 'full', items: [] }; - } - - const document = await workspace.openMarkdownDocument(URI.parse(params.textDocument.uri)); - if (!document) { - return { kind: 'full', items: [] }; - } - - const diagnostics = await manager.computeDiagnostics(document, diagnosticOptions, token); - return { - kind: 'full', - items: diagnostics, - }; - }); - - updateDiagnosticsSetting(); - subs.push(config.onDidChangeConfiguration(() => { - updateDiagnosticsSetting(); - connection.languages.diagnostics.refresh(); - })); - - return { - dispose: () => { - disposeAll(subs); - } - }; -} diff --git a/extensions/markdown-language-features/server/src/logging.ts b/extensions/markdown-language-features/server/src/logging.ts deleted file mode 100644 index 3d90d90b40..0000000000 --- a/extensions/markdown-language-features/server/src/logging.ts +++ /dev/null @@ -1,47 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ILogger, LogLevel } from 'vscode-markdown-languageservice'; - -export class LogFunctionLogger implements ILogger { - - private static now(): string { - const now = new Date(); - return String(now.getUTCHours()).padStart(2, '0') - + ':' + String(now.getMinutes()).padStart(2, '0') - + ':' + String(now.getUTCSeconds()).padStart(2, '0') + '.' + String(now.getMilliseconds()).padStart(3, '0'); - } - - private static data2String(data: any): string { - if (data instanceof Error) { - if (typeof data.stack === 'string') { - return data.stack; - } - return data.message; - } - if (typeof data === 'string') { - return data; - } - return JSON.stringify(data, undefined, 2); - } - - constructor( - private readonly _logFn: typeof console.log - ) { } - - - public log(level: LogLevel, title: string, message: string, data?: any): void { - this.appendLine(`[${level} ${LogFunctionLogger.now()}] ${title}: ${message}`); - if (data) { - this.appendLine(LogFunctionLogger.data2String(data)); - } - } - - private appendLine(value: string): void { - this._logFn(value); - } -} - -export const consoleLogger = new LogFunctionLogger(console.log); diff --git a/extensions/markdown-language-features/server/src/node/main.ts b/extensions/markdown-language-features/server/src/node/main.ts deleted file mode 100644 index 64c0a006cd..0000000000 --- a/extensions/markdown-language-features/server/src/node/main.ts +++ /dev/null @@ -1,19 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Connection, createConnection } from 'vscode-languageserver/node'; -import { startServer } from '../server'; - -// Create a connection for the server. -const connection: Connection = createConnection(); - -console.log = connection.console.log.bind(connection.console); -console.error = connection.console.error.bind(connection.console); - -process.on('unhandledRejection', (e: any) => { - connection.console.error(`Unhandled exception ${e}`); -}); - -startServer(connection); diff --git a/extensions/markdown-language-features/server/src/protocol.ts b/extensions/markdown-language-features/server/src/protocol.ts deleted file mode 100644 index 77084d9266..0000000000 --- a/extensions/markdown-language-features/server/src/protocol.ts +++ /dev/null @@ -1,27 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { RequestType } from 'vscode-languageserver'; -import type * as lsp from 'vscode-languageserver-types'; -import type * as md from 'vscode-markdown-languageservice'; - -//#region From server -export const parse = new RequestType<{ uri: string }, md.Token[], any>('markdown/parse'); - -export const fs_readFile = new RequestType<{ uri: string }, number[], any>('markdown/fs/readFile'); -export const fs_readDirectory = new RequestType<{ uri: string }, [string, { isDirectory: boolean }][], any>('markdown/fs/readDirectory'); -export const fs_stat = new RequestType<{ uri: string }, { isDirectory: boolean } | undefined, any>('markdown/fs/stat'); - -export const fs_watcher_create = new RequestType<{ id: number; uri: string; options: md.FileWatcherOptions }, void, any>('markdown/fs/watcher/create'); -export const fs_watcher_delete = new RequestType<{ id: number }, void, any>('markdown/fs/watcher/delete'); - -export const findMarkdownFilesInWorkspace = new RequestType<{}, string[], any>('markdown/findMarkdownFilesInWorkspace'); -//#endregion - -//#region To server -export const getReferencesToFileInWorkspace = new RequestType<{ uri: string }, lsp.Location[], any>('markdown/getReferencesToFileInWorkspace'); - -export const fs_watcher_onChange = new RequestType<{ id: number; uri: string; kind: 'create' | 'change' | 'delete' }, void, any>('markdown/fs/watcher/onChange'); -//#endregion diff --git a/extensions/markdown-language-features/server/src/server.ts b/extensions/markdown-language-features/server/src/server.ts deleted file mode 100644 index 6ed6cc692c..0000000000 --- a/extensions/markdown-language-features/server/src/server.ts +++ /dev/null @@ -1,252 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { CancellationToken, Connection, InitializeParams, InitializeResult, NotebookDocuments, TextDocuments } from 'vscode-languageserver'; -import { TextDocument } from 'vscode-languageserver-textdocument'; -import * as lsp from 'vscode-languageserver-types'; -import * as md from 'vscode-markdown-languageservice'; -import { IDisposable } from 'vscode-markdown-languageservice/out/util/dispose'; -import { URI } from 'vscode-uri'; -import { getLsConfiguration } from './config'; -import { ConfigurationManager } from './configuration'; -import { registerValidateSupport } from './languageFeatures/diagnostics'; -import { LogFunctionLogger } from './logging'; -import * as protocol from './protocol'; -import { VsCodeClientWorkspace } from './workspace'; - -export async function startServer(connection: Connection) { - const documents = new TextDocuments(TextDocument); - const notebooks = new NotebookDocuments(documents); - - const configurationManager = new ConfigurationManager(connection); - - let provider: md.IMdLanguageService | undefined; - let workspace: VsCodeClientWorkspace | undefined; - - connection.onInitialize((params: InitializeParams): InitializeResult => { - const parser = new class implements md.IMdParser { - slugifier = md.githubSlugifier; - - async tokenize(document: md.ITextDocument): Promise { - return await connection.sendRequest(protocol.parse, { uri: document.uri.toString() }); - } - }; - - const config = getLsConfiguration({ - markdownFileExtensions: params.initializationOptions.markdownFileExtensions, - }); - - const logger = new LogFunctionLogger(connection.console.log.bind(connection.console)); - workspace = new VsCodeClientWorkspace(connection, config, documents, notebooks, logger); - provider = md.createLanguageService({ - workspace, - parser, - logger, - markdownFileExtensions: config.markdownFileExtensions, - }); - - registerCompletionsSupport(connection, documents, provider, configurationManager); - registerValidateSupport(connection, workspace, provider, configurationManager); - - workspace.workspaceFolders = (params.workspaceFolders ?? []).map(x => URI.parse(x.uri)); - return { - capabilities: { - diagnosticProvider: { - documentSelector: null, - identifier: 'markdown', - interFileDependencies: true, - workspaceDiagnostics: false, - }, - completionProvider: { triggerCharacters: ['.', '/', '#'] }, - definitionProvider: true, - documentLinkProvider: { resolveProvider: true }, - documentSymbolProvider: true, - foldingRangeProvider: true, - renameProvider: { prepareProvider: true, }, - selectionRangeProvider: true, - workspaceSymbolProvider: true, - workspace: { - workspaceFolders: { - supported: true, - changeNotifications: true, - }, - } - } - }; - }); - - - connection.onDocumentLinks(async (params, token): Promise => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.getDocumentLinks(document, token); - } - } catch (e) { - console.error(e.stack); - } - return []; - }); - - connection.onDocumentLinkResolve(async (link, token): Promise => { - try { - return await provider!.resolveDocumentLink(link, token); - } catch (e) { - console.error(e.stack); - } - return undefined; - }); - - connection.onDocumentSymbol(async (params, token): Promise => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.getDocumentSymbols(document, token); - } - } catch (e) { - console.error(e.stack); - } - return []; - }); - - connection.onFoldingRanges(async (params, token): Promise => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.getFoldingRanges(document, token); - } - } catch (e) { - console.error(e.stack); - } - return []; - }); - - connection.onSelectionRanges(async (params, token): Promise => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.getSelectionRanges(document, params.positions, token); - } - } catch (e) { - console.error(e.stack); - } - return []; - }); - - connection.onWorkspaceSymbol(async (params, token): Promise => { - try { - return await provider!.getWorkspaceSymbols(params.query, token); - } catch (e) { - console.error(e.stack); - } - return []; - }); - - connection.onReferences(async (params, token): Promise => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.getReferences(document, params.position, params.context, token); - } - } catch (e) { - console.error(e.stack); - } - return []; - }); - - connection.onDefinition(async (params, token): Promise => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.getDefinition(document, params.position, token); - } - } catch (e) { - console.error(e.stack); - } - return undefined; - }); - - connection.onPrepareRename(async (params, token) => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - return await provider!.prepareRename(document, params.position, token); - } - } catch (e) { - console.error(e.stack); - } - return undefined; - }); - - connection.onRenameRequest(async (params, token) => { - try { - const document = documents.get(params.textDocument.uri); - if (document) { - const edit = await provider!.getRenameEdit(document, params.position, params.newName, token); - console.log(JSON.stringify(edit)); - return edit; - } - } catch (e) { - console.error(e.stack); - } - return undefined; - }); - - connection.onRequest(protocol.getReferencesToFileInWorkspace, (async (params: { uri: string }, token: CancellationToken) => { - try { - return await provider!.getFileReferences(URI.parse(params.uri), token); - } catch (e) { - console.error(e.stack); - } - return undefined; - })); - - documents.listen(connection); - notebooks.listen(connection); - connection.listen(); -} - - -function registerCompletionsSupport( - connection: Connection, - documents: TextDocuments, - ls: md.IMdLanguageService, - config: ConfigurationManager, -): IDisposable { - // let registration: Promise | undefined; - function update() { - // TODO: client still makes the request in this case. Figure our how to properly unregister. - return; - // const settings = config.getSettings(); - // if (settings?.markdown.suggest.paths.enabled) { - // if (!registration) { - // registration = connection.client.register(CompletionRequest.type); - // } - // } else { - // registration?.then(x => x.dispose()); - // registration = undefined; - // } - } - - connection.onCompletion(async (params, token): Promise => { - try { - const settings = config.getSettings(); - if (!settings?.markdown.suggest.paths.enabled) { - return []; - } - - const document = documents.get(params.textDocument.uri); - if (document) { - return await ls.getCompletionItems(document, params.position, params.context!, token); - } - } catch (e) { - console.error(e.stack); - } - return []; - }); - - update(); - return config.onDidChangeConfiguration(() => update()); -} diff --git a/extensions/markdown-language-features/server/src/util/arrays.ts b/extensions/markdown-language-features/server/src/util/arrays.ts deleted file mode 100644 index c68857a1c8..0000000000 --- a/extensions/markdown-language-features/server/src/util/arrays.ts +++ /dev/null @@ -1,11 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * @returns New array with all falsy values removed. The original array IS NOT modified. - */ -export function coalesce(array: ReadonlyArray): T[] { - return array.filter(e => !!e); -} diff --git a/extensions/markdown-language-features/server/src/util/dispose.ts b/extensions/markdown-language-features/server/src/util/dispose.ts deleted file mode 100644 index 5b2ece486d..0000000000 --- a/extensions/markdown-language-features/server/src/util/dispose.ts +++ /dev/null @@ -1,80 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export class MultiDisposeError extends Error { - constructor( - public readonly errors: any[] - ) { - super(`Encountered errors while disposing of store. Errors: [${errors.join(', ')}]`); - } -} - -export function disposeAll(disposables: Iterable) { - const errors: any[] = []; - - for (const disposable of disposables) { - try { - disposable.dispose(); - } catch (e) { - errors.push(e); - } - } - - if (errors.length === 1) { - throw errors[0]; - } else if (errors.length > 1) { - throw new MultiDisposeError(errors); - } -} - -export interface IDisposable { - dispose(): void; -} - -export abstract class Disposable { - private _isDisposed = false; - - protected _disposables: IDisposable[] = []; - - public dispose(): any { - if (this._isDisposed) { - return; - } - this._isDisposed = true; - disposeAll(this._disposables); - } - - protected _register(value: T): T { - if (this._isDisposed) { - value.dispose(); - } else { - this._disposables.push(value); - } - return value; - } - - protected get isDisposed() { - return this._isDisposed; - } -} - -export class DisposableStore extends Disposable { - private readonly items = new Set(); - - public override dispose() { - super.dispose(); - disposeAll(this.items); - this.items.clear(); - } - - public add(item: T): T { - if (this.isDisposed) { - console.warn('Adding to disposed store. Item will be leaked'); - } - - this.items.add(item); - return item; - } -} diff --git a/extensions/markdown-language-features/server/src/util/file.ts b/extensions/markdown-language-features/server/src/util/file.ts deleted file mode 100644 index aa42c39470..0000000000 --- a/extensions/markdown-language-features/server/src/util/file.ts +++ /dev/null @@ -1,16 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { TextDocument } from 'vscode-languageserver-textdocument'; -import { URI, Utils } from 'vscode-uri'; -import { LsConfiguration } from '../config'; - -export function looksLikeMarkdownPath(config: LsConfiguration, resolvedHrefPath: URI) { - return config.markdownFileExtensions.includes(Utils.extname(URI.from(resolvedHrefPath)).toLowerCase().replace('.', '')); -} - -export function isMarkdownFile(document: TextDocument) { - return document.languageId === 'markdown'; -} diff --git a/extensions/markdown-language-features/server/src/util/limiter.ts b/extensions/markdown-language-features/server/src/util/limiter.ts deleted file mode 100644 index da9e4d8755..0000000000 --- a/extensions/markdown-language-features/server/src/util/limiter.ts +++ /dev/null @@ -1,67 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -interface ILimitedTaskFactory { - factory: ITask>; - c: (value: T | Promise) => void; - e: (error?: unknown) => void; -} - -interface ITask { - (): T; -} - -/** - * A helper to queue N promises and run them all with a max degree of parallelism. The helper - * ensures that at any time no more than M promises are running at the same time. - * - * Taken from 'src/vs/base/common/async.ts' - */ -export class Limiter { - - private _size = 0; - private runningPromises: number; - private readonly maxDegreeOfParalellism: number; - private readonly outstandingPromises: ILimitedTaskFactory[]; - - constructor(maxDegreeOfParalellism: number) { - this.maxDegreeOfParalellism = maxDegreeOfParalellism; - this.outstandingPromises = []; - this.runningPromises = 0; - } - - get size(): number { - return this._size; - } - - queue(factory: ITask>): Promise { - this._size++; - - return new Promise((c, e) => { - this.outstandingPromises.push({ factory, c, e }); - this.consume(); - }); - } - - private consume(): void { - while (this.outstandingPromises.length && this.runningPromises < this.maxDegreeOfParalellism) { - const iLimitedTask = this.outstandingPromises.shift()!; - this.runningPromises++; - - const promise = iLimitedTask.factory(); - promise.then(iLimitedTask.c, iLimitedTask.e); - promise.then(() => this.consumed(), () => this.consumed()); - } - } - - private consumed(): void { - this._size--; - this.runningPromises--; - - if (this.outstandingPromises.length > 0) { - this.consume(); - } - } -} diff --git a/extensions/markdown-language-features/server/src/util/resourceMap.ts b/extensions/markdown-language-features/server/src/util/resourceMap.ts deleted file mode 100644 index 7be102bbf3..0000000000 --- a/extensions/markdown-language-features/server/src/util/resourceMap.ts +++ /dev/null @@ -1,69 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { URI } from 'vscode-uri'; - - -type ResourceToKey = (uri: URI) => string; - -const defaultResourceToKey = (resource: URI): string => resource.toString(); - -export class ResourceMap { - - private readonly map = new Map(); - - private readonly toKey: ResourceToKey; - - constructor(toKey: ResourceToKey = defaultResourceToKey) { - this.toKey = toKey; - } - - public set(uri: URI, value: T): this { - this.map.set(this.toKey(uri), { uri, value }); - return this; - } - - public get(resource: URI): T | undefined { - return this.map.get(this.toKey(resource))?.value; - } - - public has(resource: URI): boolean { - return this.map.has(this.toKey(resource)); - } - - public get size(): number { - return this.map.size; - } - - public clear(): void { - this.map.clear(); - } - - public delete(resource: URI): boolean { - return this.map.delete(this.toKey(resource)); - } - - public *values(): IterableIterator { - for (const entry of this.map.values()) { - yield entry.value; - } - } - - public *keys(): IterableIterator { - for (const entry of this.map.values()) { - yield entry.uri; - } - } - - public *entries(): IterableIterator<[URI, T]> { - for (const entry of this.map.values()) { - yield [entry.uri, entry.value]; - } - } - - public [Symbol.iterator](): IterableIterator<[URI, T]> { - return this.entries(); - } -} diff --git a/extensions/markdown-language-features/server/src/util/schemes.ts b/extensions/markdown-language-features/server/src/util/schemes.ts deleted file mode 100644 index 806953ed5a..0000000000 --- a/extensions/markdown-language-features/server/src/util/schemes.ts +++ /dev/null @@ -1,8 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export const Schemes = Object.freeze({ - notebookCell: 'vscode-notebook-cell', -}); diff --git a/extensions/markdown-language-features/server/src/workspace.ts b/extensions/markdown-language-features/server/src/workspace.ts deleted file mode 100644 index 83fa402e48..0000000000 --- a/extensions/markdown-language-features/server/src/workspace.ts +++ /dev/null @@ -1,251 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Connection, Emitter, FileChangeType, NotebookDocuments, TextDocuments } from 'vscode-languageserver'; -import { TextDocument } from 'vscode-languageserver-textdocument'; -import * as md from 'vscode-markdown-languageservice'; -import { ContainingDocumentContext, FileWatcherOptions, IFileSystemWatcher } from 'vscode-markdown-languageservice/out/workspace'; -import { URI } from 'vscode-uri'; -import { LsConfiguration } from './config'; -import * as protocol from './protocol'; -import { coalesce } from './util/arrays'; -import { isMarkdownFile, looksLikeMarkdownPath } from './util/file'; -import { Limiter } from './util/limiter'; -import { ResourceMap } from './util/resourceMap'; -import { Schemes } from './util/schemes'; - -declare const TextDecoder: any; - -export class VsCodeClientWorkspace implements md.IWorkspaceWithWatching { - - private readonly _onDidCreateMarkdownDocument = new Emitter(); - public readonly onDidCreateMarkdownDocument = this._onDidCreateMarkdownDocument.event; - - private readonly _onDidChangeMarkdownDocument = new Emitter(); - public readonly onDidChangeMarkdownDocument = this._onDidChangeMarkdownDocument.event; - - private readonly _onDidDeleteMarkdownDocument = new Emitter(); - public readonly onDidDeleteMarkdownDocument = this._onDidDeleteMarkdownDocument.event; - - private readonly _documentCache = new ResourceMap(); - - private readonly _utf8Decoder = new TextDecoder('utf-8'); - - private _watcherPool = 0; - private readonly _watchers = new Map; - readonly onDidCreate: Emitter; - readonly onDidDelete: Emitter; - }>(); - - constructor( - private readonly connection: Connection, - private readonly config: LsConfiguration, - private readonly documents: TextDocuments, - private readonly notebooks: NotebookDocuments, - private readonly logger: md.ILogger, - ) { - documents.onDidOpen(e => { - this._documentCache.delete(URI.parse(e.document.uri)); - if (this.isRelevantMarkdownDocument(e.document)) { - this._onDidCreateMarkdownDocument.fire(e.document); - } - }); - - documents.onDidChangeContent(e => { - if (this.isRelevantMarkdownDocument(e.document)) { - this._onDidChangeMarkdownDocument.fire(e.document); - } - }); - - documents.onDidClose(e => { - this._documentCache.delete(URI.parse(e.document.uri)); - }); - - connection.onDidChangeWatchedFiles(async ({ changes }) => { - for (const change of changes) { - const resource = URI.parse(change.uri); - this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: onDidChangeWatchedFiles', `${change.type}: ${resource}`); - switch (change.type) { - case FileChangeType.Changed: { - this._documentCache.delete(resource); - const document = await this.openMarkdownDocument(resource); - if (document) { - this._onDidChangeMarkdownDocument.fire(document); - } - break; - } - case FileChangeType.Created: { - const document = await this.openMarkdownDocument(resource); - if (document) { - this._onDidCreateMarkdownDocument.fire(document); - } - break; - } - case FileChangeType.Deleted: { - this._documentCache.delete(resource); - this._onDidDeleteMarkdownDocument.fire(resource); - break; - } - } - } - }); - - connection.onRequest(protocol.fs_watcher_onChange, params => { - this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: fs_watcher_onChange', `${params.kind}: ${params.uri}`); - - const watcher = this._watchers.get(params.id); - if (!watcher) { - return; - } - - switch (params.kind) { - case 'create': watcher.onDidCreate.fire(URI.parse(params.uri)); return; - case 'change': watcher.onDidChange.fire(URI.parse(params.uri)); return; - case 'delete': watcher.onDidDelete.fire(URI.parse(params.uri)); return; - } - }); - } - - public listen() { - this.connection.workspace.onDidChangeWorkspaceFolders(async () => { - this.workspaceFolders = (await this.connection.workspace.getWorkspaceFolders() ?? []).map(x => URI.parse(x.uri)); - }); - } - - private _workspaceFolders: readonly URI[] = []; - - get workspaceFolders(): readonly URI[] { - return this._workspaceFolders; - } - - set workspaceFolders(value: readonly URI[]) { - this._workspaceFolders = value; - } - - async getAllMarkdownDocuments(): Promise> { - const maxConcurrent = 20; - - const foundFiles = new ResourceMap(); - const limiter = new Limiter(maxConcurrent); - - // Add files on disk - const resources = await this.connection.sendRequest(protocol.findMarkdownFilesInWorkspace, {}); - const onDiskResults = await Promise.all(resources.map(strResource => { - return limiter.queue(async () => { - const resource = URI.parse(strResource); - const doc = await this.openMarkdownDocument(resource); - if (doc) { - foundFiles.set(resource); - } - return doc; - }); - })); - - // Add opened files (such as untitled files) - const openTextDocumentResults = await Promise.all(this.documents.all() - .filter(doc => !foundFiles.has(URI.parse(doc.uri)) && this.isRelevantMarkdownDocument(doc))); - - return coalesce([...onDiskResults, ...openTextDocumentResults]); - } - - hasMarkdownDocument(resource: URI): boolean { - return !!this.documents.get(resource.toString()); - } - - async openMarkdownDocument(resource: URI): Promise { - const existing = this._documentCache.get(resource); - if (existing) { - return existing; - } - - const matchingDocument = this.documents.get(resource.toString()); - if (matchingDocument) { - this._documentCache.set(resource, matchingDocument); - return matchingDocument; - } - - if (!looksLikeMarkdownPath(this.config, resource)) { - return undefined; - } - - try { - const response = await this.connection.sendRequest(protocol.fs_readFile, { uri: resource.toString() }); - // TODO: LSP doesn't seem to handle Array buffers well - const bytes = new Uint8Array(response); - - // We assume that markdown is in UTF-8 - const text = this._utf8Decoder.decode(bytes); - const doc = TextDocument.create(resource.toString(), 'markdown', 0, text); - this._documentCache.set(resource, doc); - return doc; - } catch (e) { - return undefined; - } - } - - async stat(resource: URI): Promise { - this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: stat', `${resource}`); - if (this._documentCache.has(resource) || this.documents.get(resource.toString())) { - return { isDirectory: false }; - } - return this.connection.sendRequest(protocol.fs_stat, { uri: resource.toString() }); - } - - async readDirectory(resource: URI): Promise<[string, md.FileStat][]> { - this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: readDir', `${resource}`); - return this.connection.sendRequest(protocol.fs_readDirectory, { uri: resource.toString() }); - } - - getContainingDocument(resource: URI): ContainingDocumentContext | undefined { - if (resource.scheme === Schemes.notebookCell) { - const nb = this.notebooks.findNotebookDocumentForCell(resource.toString()); - if (nb) { - return { - uri: URI.parse(nb.uri), - children: nb.cells.map(cell => ({ uri: URI.parse(cell.document) })), - }; - } - } - return undefined; - } - - watchFile(resource: URI, options: FileWatcherOptions): IFileSystemWatcher { - const id = this._watcherPool++; - this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: watchFile', `(${id}) ${resource}`); - - const entry = { - resource, - options, - onDidCreate: new Emitter(), - onDidChange: new Emitter(), - onDidDelete: new Emitter(), - }; - this._watchers.set(id, entry); - - this.connection.sendRequest(protocol.fs_watcher_create, { - id, - uri: resource.toString(), - options, - }); - - return { - onDidCreate: entry.onDidCreate.event, - onDidChange: entry.onDidChange.event, - onDidDelete: entry.onDidDelete.event, - dispose: () => { - this.logger.log(md.LogLevel.Trace, 'VsCodeClientWorkspace: disposeWatcher', `(${id}) ${resource}`); - this.connection.sendRequest(protocol.fs_watcher_delete, { id }); - this._watchers.delete(id); - } - }; - } - - private isRelevantMarkdownDocument(doc: TextDocument) { - return isMarkdownFile(doc) && URI.parse(doc.uri).scheme !== 'vscode-bulkeditpreview'; - } -} diff --git a/extensions/markdown-language-features/server/tsconfig.json b/extensions/markdown-language-features/server/tsconfig.json deleted file mode 100644 index 8b4aedde27..0000000000 --- a/extensions/markdown-language-features/server/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./out" - }, - "include": [ - "src/**/*" - ] -} diff --git a/extensions/markdown-language-features/server/yarn.lock b/extensions/markdown-language-features/server/yarn.lock deleted file mode 100644 index d0d31f5998..0000000000 --- a/extensions/markdown-language-features/server/yarn.lock +++ /dev/null @@ -1,69 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@types/node@16.x": - version "16.11.43" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.43.tgz#555e5a743f76b6b897d47f945305b618525ddbe6" - integrity sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ== - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -vscode-jsonrpc@8.0.2-next.1: - version "8.0.2-next.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2-next.1.tgz#6bdc39fd194782032e34047eeefce562941259c6" - integrity sha512-sbbvGSWja7NVBLHPGawtgezc8DHYJaP4qfr/AaJiyDapWcSFtHyPtm18+LnYMLTmB7bhOUW/lf5PeeuLpP6bKA== - -vscode-languageserver-protocol@3.17.2-next.6: - version "3.17.2-next.6" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.6.tgz#8f1dc0fcb29366b85f623a3f9af726de433b5fcc" - integrity sha512-WtsebNOOkWyNn4oFYoAMPC8Q/ZDoJ/K7Ja53OzTixiitvrl/RpXZETrtzH79R8P5kqCyx6VFBPb6KQILJfkDkA== - dependencies: - vscode-jsonrpc "8.0.2-next.1" - vscode-languageserver-types "3.17.2-next.2" - -vscode-languageserver-textdocument@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz#838769940ece626176ec5d5a2aa2d0aa69f5095c" - integrity sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg== - -vscode-languageserver-types@3.17.2-next.2: - version "3.17.2-next.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2-next.2.tgz#af5d6978eee7682aab87c1419323f5b141ac6596" - integrity sha512-TiAkLABgqkVWdAlC3XlOfdhdjIAdVU4YntPUm9kKGbXr+MGwpVnKz2KZMNBcvG0CFx8Hi8qliL0iq+ndPB720w== - -vscode-languageserver-types@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16" - integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ== - -vscode-languageserver@^8.0.2-next.5`: - version "8.0.2-next.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.5.tgz#39a2dd4c504fb88042375e7ac706a714bdaab4e5" - integrity sha512-2ZDb7O/4atS9mJKufPPz637z+51kCyZfgnobFW5eSrUdS3c0UB/nMS4Ng1EavYTX84GVaVMKCrmP0f2ceLmR0A== - dependencies: - vscode-languageserver-protocol "3.17.2-next.6" - -vscode-markdown-languageservice@^0.0.0-alpha.12: - version "0.0.0-alpha.12" - resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.0.0-alpha.12.tgz#5a3c7559969c3cb455d508d48129c8e221589630" - integrity sha512-9dJ/GL6A9UUOcB1TpvgsbcwqsYjnxHx4jxDaqeZZEMWFSUySfp0PAn1ge2S2Qj00zypvsu0eCTGUNd56G1/BNQ== - dependencies: - picomatch "^2.3.1" - vscode-languageserver-textdocument "^1.0.5" - vscode-languageserver-types "^3.17.1" - vscode-nls "^5.0.1" - vscode-uri "^3.0.3" - -vscode-nls@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2" - integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== - -vscode-uri@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84" - integrity sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA== diff --git a/extensions/markdown-language-features/src/client.ts b/extensions/markdown-language-features/src/client.ts deleted file mode 100644 index 4d86fc36d9..0000000000 --- a/extensions/markdown-language-features/src/client.ts +++ /dev/null @@ -1,114 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { BaseLanguageClient, LanguageClientOptions, NotebookDocumentSyncRegistrationType } from 'vscode-languageclient'; -import * as nls from 'vscode-nls'; -import { IMdParser } from './markdownEngine'; -import * as proto from './protocol'; -import { looksLikeMarkdownPath, markdownFileExtensions } from './util/file'; -import { IMdWorkspace } from './workspace'; - -const localize = nls.loadMessageBundle(); - -export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient; - - -export async function startClient(factory: LanguageClientConstructor, workspace: IMdWorkspace, parser: IMdParser): Promise { - - const mdFileGlob = `**/*.{${markdownFileExtensions.join(',')}}`; - - const clientOptions: LanguageClientOptions = { - documentSelector: [{ language: 'markdown' }], - synchronize: { - configurationSection: ['markdown'], - fileEvents: vscode.workspace.createFileSystemWatcher(mdFileGlob), - }, - initializationOptions: { - markdownFileExtensions, - }, - diagnosticPullOptions: { - onChange: true, - onSave: true, - onTabs: true, - match(_documentSelector, resource) { - return looksLikeMarkdownPath(resource); - }, - }, - - }; - - const client = factory('markdown', localize('markdownServer.name', 'Markdown Language Server'), clientOptions); - - client.registerProposedFeatures(); - - const notebookFeature = client.getFeature(NotebookDocumentSyncRegistrationType.method); - if (notebookFeature !== undefined) { - notebookFeature.register({ - id: String(Date.now()), - registerOptions: { - notebookSelector: [{ - notebook: '*', - cells: [{ language: 'markdown' }] - }] - } - }); - } - - client.onRequest(proto.parse, async (e) => { - const uri = vscode.Uri.parse(e.uri); - const doc = await workspace.getOrLoadMarkdownDocument(uri); - if (doc) { - return parser.tokenize(doc); - } else { - return []; - } - }); - - client.onRequest(proto.fs_readFile, async (e): Promise => { - const uri = vscode.Uri.parse(e.uri); - return Array.from(await vscode.workspace.fs.readFile(uri)); - }); - - client.onRequest(proto.fs_stat, async (e): Promise<{ isDirectory: boolean } | undefined> => { - const uri = vscode.Uri.parse(e.uri); - try { - const stat = await vscode.workspace.fs.stat(uri); - return { isDirectory: stat.type === vscode.FileType.Directory }; - } catch { - return undefined; - } - }); - - client.onRequest(proto.fs_readDirectory, async (e): Promise<[string, { isDirectory: boolean }][]> => { - const uri = vscode.Uri.parse(e.uri); - const result = await vscode.workspace.fs.readDirectory(uri); - return result.map(([name, type]) => [name, { isDirectory: type === vscode.FileType.Directory }]); - }); - - client.onRequest(proto.findMarkdownFilesInWorkspace, async (): Promise => { - return (await vscode.workspace.findFiles(mdFileGlob, '**/node_modules/**')).map(x => x.toString()); - }); - - const watchers = new Map(); - - client.onRequest(proto.fs_watcher_create, async (params): Promise => { - const id = params.id; - const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(vscode.Uri.parse(params.uri), '*'), params.options.ignoreCreate, params.options.ignoreChange, params.options.ignoreDelete); - watchers.set(id, watcher); - watcher.onDidCreate(() => { client.sendRequest(proto.fs_watcher_onChange, { id, uri: params.uri, kind: 'create' }); }); - watcher.onDidChange(() => { client.sendRequest(proto.fs_watcher_onChange, { id, uri: params.uri, kind: 'change' }); }); - watcher.onDidDelete(() => { client.sendRequest(proto.fs_watcher_onChange, { id, uri: params.uri, kind: 'delete' }); }); - }); - - client.onRequest(proto.fs_watcher_delete, async (params): Promise => { - watchers.get(params.id)?.dispose(); - watchers.delete(params.id); - }); - - await client.start(); - - return client; -} diff --git a/extensions/markdown-language-features/src/commands/openDocumentLink.ts b/extensions/markdown-language-features/src/commands/openDocumentLink.ts index dff7b05fb0..9445fdbf43 100644 --- a/extensions/markdown-language-features/src/commands/openDocumentLink.ts +++ b/extensions/markdown-language-features/src/commands/openDocumentLink.ts @@ -5,9 +5,8 @@ import * as vscode from 'vscode'; import { Command } from '../commandManager'; -import { MdTableOfContentsProvider } from '../tableOfContents'; +import { MarkdownEngine } from '../markdownEngine'; import { openDocumentLink } from '../util/openDocumentLink'; -import { Schemes } from '../util/schemes'; type UriComponents = { readonly scheme?: string; @@ -49,18 +48,18 @@ export class OpenDocumentLinkCommand implements Command { } public constructor( - private readonly tocProvider: MdTableOfContentsProvider, + private readonly engine: MarkdownEngine ) { } public async execute(args: OpenDocumentLinkArgs) { const fromResource = vscode.Uri.parse('').with(args.fromResource); const targetResource = reviveUri(args.parts).with({ fragment: args.fragment }); - return openDocumentLink(this.tocProvider, targetResource, fromResource); + return openDocumentLink(this.engine, targetResource, fromResource); } } function reviveUri(parts: any) { - if (parts.scheme === Schemes.file) { + if (parts.scheme === 'file') { return vscode.Uri.file(parts.path); } return vscode.Uri.parse('').with(parts); diff --git a/extensions/markdown-language-features/src/commands/refreshPreview.ts b/extensions/markdown-language-features/src/commands/refreshPreview.ts index 1d983d2f55..331e5375e9 100644 --- a/extensions/markdown-language-features/src/commands/refreshPreview.ts +++ b/extensions/markdown-language-features/src/commands/refreshPreview.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Command } from '../commandManager'; -import { MarkdownItEngine } from '../markdownEngine'; +import { MarkdownEngine } from '../markdownEngine'; import { MarkdownPreviewManager } from '../preview/previewManager'; export class RefreshPreviewCommand implements Command { @@ -12,7 +12,7 @@ export class RefreshPreviewCommand implements Command { public constructor( private readonly webviewManager: MarkdownPreviewManager, - private readonly engine: MarkdownItEngine + private readonly engine: MarkdownEngine ) { } public execute() { diff --git a/extensions/markdown-language-features/src/commands/reloadPlugins.ts b/extensions/markdown-language-features/src/commands/reloadPlugins.ts index 826697d545..9d757277c2 100644 --- a/extensions/markdown-language-features/src/commands/reloadPlugins.ts +++ b/extensions/markdown-language-features/src/commands/reloadPlugins.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Command } from '../commandManager'; -import { MarkdownItEngine } from '../markdownEngine'; +import { MarkdownEngine } from '../markdownEngine'; import { MarkdownPreviewManager } from '../preview/previewManager'; export class ReloadPlugins implements Command { @@ -12,7 +12,7 @@ export class ReloadPlugins implements Command { public constructor( private readonly webviewManager: MarkdownPreviewManager, - private readonly engine: MarkdownItEngine, + private readonly engine: MarkdownEngine, ) { } public execute(): void { diff --git a/extensions/markdown-language-features/src/commands/renderDocument.ts b/extensions/markdown-language-features/src/commands/renderDocument.ts index 7da7e52d72..9400f130ce 100644 --- a/extensions/markdown-language-features/src/commands/renderDocument.ts +++ b/extensions/markdown-language-features/src/commands/renderDocument.ts @@ -4,17 +4,17 @@ *--------------------------------------------------------------------------------------------*/ import { Command } from '../commandManager'; -import { MarkdownItEngine } from '../markdownEngine'; -import { ITextDocument } from '../types/textDocument'; +import { MarkdownEngine } from '../markdownEngine'; +import { SkinnyTextDocument } from '../workspaceContents'; export class RenderDocument implements Command { public readonly id = 'markdown.api.render'; public constructor( - private readonly engine: MarkdownItEngine + private readonly engine: MarkdownEngine ) { } - public async execute(document: ITextDocument | string): Promise { + public async execute(document: SkinnyTextDocument | string): Promise { return (await (this.engine.render(document))).html; } } diff --git a/extensions/markdown-language-features/src/extension.browser.ts b/extensions/markdown-language-features/src/extension.browser.ts deleted file mode 100644 index 65d1ad6bbb..0000000000 --- a/extensions/markdown-language-features/src/extension.browser.ts +++ /dev/null @@ -1,42 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { BaseLanguageClient, LanguageClient, LanguageClientOptions } from 'vscode-languageclient/browser'; -import { startClient } from './client'; -import { activateShared } from './extension.shared'; -import { VsCodeOutputLogger } from './logging'; -import { IMdParser, MarkdownItEngine } from './markdownEngine'; -import { getMarkdownExtensionContributions } from './markdownExtensions'; -import { githubSlugifier } from './slugify'; -import { IMdWorkspace, VsCodeMdWorkspace } from './workspace'; - -export async function activate(context: vscode.ExtensionContext) { - const contributions = getMarkdownExtensionContributions(context); - context.subscriptions.push(contributions); - - const logger = new VsCodeOutputLogger(); - context.subscriptions.push(logger); - - const engine = new MarkdownItEngine(contributions, githubSlugifier, logger); - - const workspace = new VsCodeMdWorkspace(); - context.subscriptions.push(workspace); - - const client = await startServer(context, workspace, engine); - context.subscriptions.push({ - dispose: () => client.stop() - }); - activateShared(context, client, workspace, engine, logger, contributions); -} - -function startServer(context: vscode.ExtensionContext, workspace: IMdWorkspace, parser: IMdParser): Promise { - const serverMain = vscode.Uri.joinPath(context.extensionUri, 'server/dist/browser/main.js'); - const worker = new Worker(serverMain.toString()); - - return startClient((id: string, name: string, clientOptions: LanguageClientOptions) => { - return new LanguageClient(id, name, clientOptions, worker); - }, workspace, parser); -} diff --git a/extensions/markdown-language-features/src/extension.shared.ts b/extensions/markdown-language-features/src/extension.shared.ts deleted file mode 100644 index 6c5ee45e6d..0000000000 --- a/extensions/markdown-language-features/src/extension.shared.ts +++ /dev/null @@ -1,90 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { BaseLanguageClient } from 'vscode-languageclient'; -import { CommandManager } from './commandManager'; -import * as commands from './commands/index'; -import { registerPasteSupport } from './languageFeatures/copyPaste'; -import { registerDiagnosticSupport } from './languageFeatures/diagnostics'; -import { registerDropIntoEditorSupport } from './languageFeatures/dropIntoEditor'; -import { registerFindFileReferenceSupport } from './languageFeatures/fileReferences'; -import { ILogger } from './logging'; -import { MarkdownItEngine, MdParsingProvider } from './markdownEngine'; -import { MarkdownContributionProvider } from './markdownExtensions'; -import { MdDocumentRenderer } from './preview/documentRenderer'; -import { MarkdownPreviewManager } from './preview/previewManager'; -import { ContentSecurityPolicyArbiter, ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './preview/security'; -import { MdTableOfContentsProvider } from './tableOfContents'; -import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter'; -import { IMdWorkspace } from './workspace'; - -export function activateShared( - context: vscode.ExtensionContext, - client: BaseLanguageClient, - workspace: IMdWorkspace, - engine: MarkdownItEngine, - logger: ILogger, - contributions: MarkdownContributionProvider, -) { - const telemetryReporter = loadDefaultTelemetryReporter(); - context.subscriptions.push(telemetryReporter); - - const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState); - const commandManager = new CommandManager(); - - const parser = new MdParsingProvider(engine, workspace); - const tocProvider = new MdTableOfContentsProvider(parser, workspace, logger); - context.subscriptions.push(parser, tocProvider); - - const contentProvider = new MdDocumentRenderer(engine, context, cspArbiter, contributions, logger); - const previewManager = new MarkdownPreviewManager(contentProvider, workspace, logger, contributions, tocProvider); - context.subscriptions.push(previewManager); - - context.subscriptions.push(registerMarkdownLanguageFeatures(client, commandManager)); - context.subscriptions.push(registerMarkdownCommands(commandManager, previewManager, telemetryReporter, cspArbiter, engine, tocProvider)); - - context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => { - previewManager.updateConfiguration(); - })); -} - -function registerMarkdownLanguageFeatures( - client: BaseLanguageClient, - commandManager: CommandManager, -): vscode.Disposable { - const selector: vscode.DocumentSelector = { language: 'markdown', scheme: '*' }; - return vscode.Disposable.from( - // Language features - registerDiagnosticSupport(selector, commandManager), - registerDropIntoEditorSupport(selector), - registerFindFileReferenceSupport(commandManager, client), - registerPasteSupport(selector), - ); -} - -function registerMarkdownCommands( - commandManager: CommandManager, - previewManager: MarkdownPreviewManager, - telemetryReporter: TelemetryReporter, - cspArbiter: ContentSecurityPolicyArbiter, - engine: MarkdownItEngine, - tocProvider: MdTableOfContentsProvider, -): vscode.Disposable { - const previewSecuritySelector = new PreviewSecuritySelector(cspArbiter, previewManager); - - commandManager.register(new commands.ShowPreviewCommand(previewManager, telemetryReporter)); - commandManager.register(new commands.ShowPreviewToSideCommand(previewManager, telemetryReporter)); - commandManager.register(new commands.ShowLockedPreviewToSideCommand(previewManager, telemetryReporter)); - commandManager.register(new commands.ShowSourceCommand(previewManager)); - commandManager.register(new commands.RefreshPreviewCommand(previewManager, engine)); - commandManager.register(new commands.MoveCursorToPositionCommand()); - commandManager.register(new commands.ShowPreviewSecuritySelectorCommand(previewSecuritySelector, previewManager)); - commandManager.register(new commands.OpenDocumentLinkCommand(tocProvider)); - commandManager.register(new commands.ToggleLockCommand(previewManager)); - commandManager.register(new commands.RenderDocument(engine)); - commandManager.register(new commands.ReloadPlugins(previewManager, engine)); - return commandManager; -} diff --git a/extensions/markdown-language-features/src/extension.ts b/extensions/markdown-language-features/src/extension.ts index 797dfa620e..d4ff9e1ac0 100644 --- a/extensions/markdown-language-features/src/extension.ts +++ b/extensions/markdown-language-features/src/extension.ts @@ -4,50 +4,103 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { BaseLanguageClient, LanguageClient, ServerOptions, TransportKind } from 'vscode-languageclient/node'; -import { startClient } from './client'; -import { activateShared } from './extension.shared'; -import { VsCodeOutputLogger } from './logging'; -import { IMdParser, MarkdownItEngine } from './markdownEngine'; +import { CommandManager } from './commandManager'; +import * as commands from './commands/index'; +import { register as registerDiagnostics } from './languageFeatures/diagnostics'; +import { MdDefinitionProvider } from './languageFeatures/definitionProvider'; +import { MdLinkProvider } from './languageFeatures/documentLinkProvider'; +import { MdDocumentSymbolProvider } from './languageFeatures/documentSymbolProvider'; +import { registerDropIntoEditor } from './languageFeatures/dropIntoEditor'; +import { registerFindFileReferences } from './languageFeatures/fileReferences'; +import { MdFoldingProvider } from './languageFeatures/foldingProvider'; +import { MdPathCompletionProvider } from './languageFeatures/pathCompletions'; +import { MdReferencesProvider } from './languageFeatures/references'; +import { MdRenameProvider } from './languageFeatures/rename'; +import { MdSmartSelect } from './languageFeatures/smartSelect'; +import { MdWorkspaceSymbolProvider } from './languageFeatures/workspaceSymbolProvider'; +import { Logger } from './logger'; +import { MarkdownEngine } from './markdownEngine'; import { getMarkdownExtensionContributions } from './markdownExtensions'; +import { MarkdownContentProvider } from './preview/previewContentProvider'; +import { MarkdownPreviewManager } from './preview/previewManager'; +import { ContentSecurityPolicyArbiter, ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './preview/security'; import { githubSlugifier } from './slugify'; -import { IMdWorkspace, VsCodeMdWorkspace } from './workspace'; +import { loadDefaultTelemetryReporter, TelemetryReporter } from './telemetryReporter'; +import { VsCodeMdWorkspaceContents } from './workspaceContents'; + + +export function activate(context: vscode.ExtensionContext) { + const telemetryReporter = loadDefaultTelemetryReporter(); + context.subscriptions.push(telemetryReporter); -export async function activate(context: vscode.ExtensionContext) { const contributions = getMarkdownExtensionContributions(context); context.subscriptions.push(contributions); - const logger = new VsCodeOutputLogger(); - context.subscriptions.push(logger); + const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState); + const engine = new MarkdownEngine(contributions, githubSlugifier); + const logger = new Logger(); + const commandManager = new CommandManager(); - const engine = new MarkdownItEngine(contributions, githubSlugifier, logger); + const contentProvider = new MarkdownContentProvider(engine, context, cspArbiter, contributions, logger); + const symbolProvider = new MdDocumentSymbolProvider(engine); + const previewManager = new MarkdownPreviewManager(contentProvider, logger, contributions, engine); + context.subscriptions.push(previewManager); - const workspace = new VsCodeMdWorkspace(); - context.subscriptions.push(workspace); + context.subscriptions.push(registerMarkdownLanguageFeatures(commandManager, symbolProvider, engine)); + context.subscriptions.push(registerMarkdownCommands(commandManager, previewManager, telemetryReporter, cspArbiter, engine)); - const client = await startServer(context, workspace, engine); - context.subscriptions.push({ - dispose: () => client.stop() - }); - activateShared(context, client, workspace, engine, logger, contributions); + context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(() => { + logger.updateConfiguration(); + previewManager.updateConfiguration(); + })); } -function startServer(context: vscode.ExtensionContext, workspace: IMdWorkspace, parser: IMdParser): Promise { - const clientMain = vscode.extensions.getExtension('vscode.markdown-language-features')?.packageJSON?.main || ''; +function registerMarkdownLanguageFeatures( + commandManager: CommandManager, + symbolProvider: MdDocumentSymbolProvider, + engine: MarkdownEngine +): vscode.Disposable { + const selector: vscode.DocumentSelector = { language: 'markdown', scheme: '*' }; - const serverMain = `./server/${clientMain.indexOf('/dist/') !== -1 ? 'dist' : 'out'}/node/main`; - const serverModule = context.asAbsolutePath(serverMain); + const linkProvider = new MdLinkProvider(engine); + const workspaceContents = new VsCodeMdWorkspaceContents(); - // The debug options for the server - const debugOptions = { execArgv: ['--nolazy', '--inspect=' + (7000 + Math.round(Math.random() * 999))] }; - - // If the extension is launch in debug mode the debug server options are use - // Otherwise the run options are used - const serverOptions: ServerOptions = { - run: { module: serverModule, transport: TransportKind.ipc }, - debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions } - }; - return startClient((id, name, clientOptions) => { - return new LanguageClient(id, name, serverOptions, clientOptions); - }, workspace, parser); + const referencesProvider = new MdReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier); + return vscode.Disposable.from( + vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider), + vscode.languages.registerDocumentLinkProvider(selector, linkProvider), + vscode.languages.registerFoldingRangeProvider(selector, new MdFoldingProvider(engine)), + vscode.languages.registerSelectionRangeProvider(selector, new MdSmartSelect(engine)), + vscode.languages.registerWorkspaceSymbolProvider(new MdWorkspaceSymbolProvider(symbolProvider, workspaceContents)), + vscode.languages.registerReferenceProvider(selector, referencesProvider), + vscode.languages.registerRenameProvider(selector, new MdRenameProvider(referencesProvider, workspaceContents, githubSlugifier)), + vscode.languages.registerDefinitionProvider(selector, new MdDefinitionProvider(referencesProvider)), + MdPathCompletionProvider.register(selector, engine, linkProvider), + registerDiagnostics(engine, workspaceContents, linkProvider), + registerDropIntoEditor(selector), + registerFindFileReferences(commandManager, referencesProvider), + ); +} + +function registerMarkdownCommands( + commandManager: CommandManager, + previewManager: MarkdownPreviewManager, + telemetryReporter: TelemetryReporter, + cspArbiter: ContentSecurityPolicyArbiter, + engine: MarkdownEngine +): vscode.Disposable { + const previewSecuritySelector = new PreviewSecuritySelector(cspArbiter, previewManager); + + commandManager.register(new commands.ShowPreviewCommand(previewManager, telemetryReporter)); + commandManager.register(new commands.ShowPreviewToSideCommand(previewManager, telemetryReporter)); + commandManager.register(new commands.ShowLockedPreviewToSideCommand(previewManager, telemetryReporter)); + commandManager.register(new commands.ShowSourceCommand(previewManager)); + commandManager.register(new commands.RefreshPreviewCommand(previewManager, engine)); + commandManager.register(new commands.MoveCursorToPositionCommand()); + commandManager.register(new commands.ShowPreviewSecuritySelectorCommand(previewSecuritySelector, previewManager)); + commandManager.register(new commands.OpenDocumentLinkCommand(engine)); + commandManager.register(new commands.ToggleLockCommand(previewManager)); + commandManager.register(new commands.RenderDocument(engine)); + commandManager.register(new commands.ReloadPlugins(previewManager, engine)); + return commandManager; } diff --git a/extensions/markdown-language-features/src/languageFeatures/copyPaste.ts b/extensions/markdown-language-features/src/languageFeatures/copyPaste.ts deleted file mode 100644 index d392970339..0000000000 --- a/extensions/markdown-language-features/src/languageFeatures/copyPaste.ts +++ /dev/null @@ -1,29 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { tryGetUriListSnippet } from './dropIntoEditor'; - -export function registerPasteSupport(selector: vscode.DocumentSelector) { - return vscode.languages.registerDocumentPasteEditProvider(selector, new class implements vscode.DocumentPasteEditProvider { - - async provideDocumentPasteEdits( - document: vscode.TextDocument, - _ranges: readonly vscode.Range[], - dataTransfer: vscode.DataTransfer, - token: vscode.CancellationToken, - ): Promise { - const enabled = vscode.workspace.getConfiguration('markdown', document).get('experimental.editor.pasteLinks.enabled', true); - if (!enabled) { - return; - } - - const snippet = await tryGetUriListSnippet(document, dataTransfer, token); - return snippet ? new vscode.DocumentPasteEdit(snippet) : undefined; - } - }, { - pasteMimeTypes: ['text/uri-list'] - }); -} diff --git a/extensions/markdown-language-features/src/languageFeatures/definitionProvider.ts b/extensions/markdown-language-features/src/languageFeatures/definitionProvider.ts new file mode 100644 index 0000000000..599e604a34 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/definitionProvider.ts @@ -0,0 +1,21 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as vscode from 'vscode'; +import { Disposable } from '../util/dispose'; +import { SkinnyTextDocument } from '../workspaceContents'; +import { MdReferencesProvider } from './references'; + +export class MdDefinitionProvider extends Disposable implements vscode.DefinitionProvider { + + constructor(private readonly referencesProvider: MdReferencesProvider) { + super(); + } + + async provideDefinition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + const allRefs = await this.referencesProvider.getAllReferencesAtPosition(document, position, token); + + return allRefs.find(ref => ref.kind === 'link' && ref.isDefinition)?.location; + } +} diff --git a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts index 1e76b78f62..b397beaa54 100644 --- a/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts +++ b/extensions/markdown-language-features/src/languageFeatures/diagnostics.ts @@ -5,79 +5,294 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; -import { CommandManager } from '../commandManager'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContents } from '../tableOfContents'; +import { noopToken } from '../test/util'; +import { Delayer } from '../util/async'; +import { Disposable } from '../util/dispose'; +import { isMarkdownFile } from '../util/file'; +import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; +import { InternalHref, LinkDefinitionSet, MdLink, MdLinkProvider } from './documentLinkProvider'; +import { tryFindMdDocumentForLink } from './references'; const localize = nls.loadMessageBundle(); -// Copied from markdown language service -export enum DiagnosticCode { - link_noSuchReferences = 'link.no-such-reference', - link_noSuchHeaderInOwnFile = 'link.no-such-header-in-own-file', - link_noSuchFile = 'link.no-such-file', - link_noSuchHeaderInFile = 'link.no-such-header-in-file', +export interface DiagnosticConfiguration { + /** + * Fired when the configuration changes. + */ + readonly onDidChange: vscode.Event; + + getOptions(resource: vscode.Uri): DiagnosticOptions; } +export enum DiagnosticLevel { + ignore = 'ignore', + warning = 'warning', + error = 'error', +} -class AddToIgnoreLinksQuickFixProvider implements vscode.CodeActionProvider { +export interface DiagnosticOptions { + readonly enabled: boolean; + readonly validateReferences: DiagnosticLevel; + readonly validateOwnHeaders: DiagnosticLevel; + readonly validateFilePaths: DiagnosticLevel; +} - private static readonly _addToIgnoreLinksCommandId = '_markdown.addToIgnoreLinks'; +function toSeverity(level: DiagnosticLevel): vscode.DiagnosticSeverity | undefined { + switch (level) { + case DiagnosticLevel.error: return vscode.DiagnosticSeverity.Error; + case DiagnosticLevel.warning: return vscode.DiagnosticSeverity.Warning; + case DiagnosticLevel.ignore: return undefined; + } +} - private static readonly metadata: vscode.CodeActionProviderMetadata = { - providedCodeActionKinds: [ - vscode.CodeActionKind.QuickFix - ], - }; +class VSCodeDiagnosticConfiguration extends Disposable implements DiagnosticConfiguration { - public static register(selector: vscode.DocumentSelector, commandManager: CommandManager): vscode.Disposable { - const reg = vscode.languages.registerCodeActionsProvider(selector, new AddToIgnoreLinksQuickFixProvider(), AddToIgnoreLinksQuickFixProvider.metadata); - const commandReg = commandManager.register({ - id: AddToIgnoreLinksQuickFixProvider._addToIgnoreLinksCommandId, - execute(resource: vscode.Uri, path: string) { - const settingId = 'experimental.validate.ignoreLinks'; - const config = vscode.workspace.getConfiguration('markdown', resource); - const paths = new Set(config.get(settingId, [])); - paths.add(path); - config.update(settingId, [...paths], vscode.ConfigurationTarget.WorkspaceFolder); + private readonly _onDidChange = this._register(new vscode.EventEmitter()); + public readonly onDidChange = this._onDidChange.event; + + constructor() { + super(); + + this._register(vscode.workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('markdown.experimental.validate.enabled')) { + this._onDidChange.fire(); } - }); - return vscode.Disposable.from(reg, commandReg); + })); } - provideCodeActions(document: vscode.TextDocument, _range: vscode.Range | vscode.Selection, context: vscode.CodeActionContext, _token: vscode.CancellationToken): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> { - const fixes: vscode.CodeAction[] = []; + public getOptions(resource: vscode.Uri): DiagnosticOptions { + const config = vscode.workspace.getConfiguration('markdown', resource); + return { + enabled: config.get('experimental.validate.enabled', false), + validateReferences: config.get('experimental.validate.referenceLinks', DiagnosticLevel.ignore), + validateOwnHeaders: config.get('experimental.validate.headerLinks', DiagnosticLevel.ignore), + validateFilePaths: config.get('experimental.validate.fileLinks', DiagnosticLevel.ignore), + }; + } +} - for (const diagnostic of context.diagnostics) { - switch (diagnostic.code) { - case DiagnosticCode.link_noSuchReferences: - case DiagnosticCode.link_noSuchHeaderInOwnFile: - case DiagnosticCode.link_noSuchFile: - case DiagnosticCode.link_noSuchHeaderInFile: { - const hrefText = (diagnostic as any).data?.hrefText; - if (hrefText) { - const fix = new vscode.CodeAction( - localize('ignoreLinksQuickFix.title', "Exclude '{0}' from link validation.", hrefText), - vscode.CodeActionKind.QuickFix); +export class DiagnosticManager extends Disposable { - fix.command = { - command: AddToIgnoreLinksQuickFixProvider._addToIgnoreLinksCommandId, - title: '', - arguments: [document.uri, hrefText], - }; - fixes.push(fix); + private readonly collection: vscode.DiagnosticCollection; + + private readonly pendingDiagnostics = new Set(); + private readonly diagnosticDelayer: Delayer; + + constructor( + private readonly computer: DiagnosticComputer, + private readonly configuration: DiagnosticConfiguration, + ) { + super(); + + this.diagnosticDelayer = new Delayer(300); + + this.collection = this._register(vscode.languages.createDiagnosticCollection('markdown')); + + this._register(this.configuration.onDidChange(() => { + this.rebuild(); + })); + + const onDocUpdated = (doc: vscode.TextDocument) => { + if (isMarkdownFile(doc)) { + this.pendingDiagnostics.add(doc.uri); + this.diagnosticDelayer.trigger(() => this.recomputePendingDiagnostics()); + } + }; + + this._register(vscode.workspace.onDidOpenTextDocument(doc => { + onDocUpdated(doc); + })); + + this._register(vscode.workspace.onDidChangeTextDocument(e => { + onDocUpdated(e.document); + })); + + this._register(vscode.workspace.onDidCloseTextDocument(doc => { + this.pendingDiagnostics.delete(doc.uri); + this.collection.delete(doc.uri); + })); + + this.rebuild(); + } + + private recomputePendingDiagnostics(): void { + const pending = [...this.pendingDiagnostics]; + this.pendingDiagnostics.clear(); + + for (const resource of pending) { + const doc = vscode.workspace.textDocuments.find(doc => doc.uri.fsPath === resource.fsPath); + if (doc) { + this.update(doc); + } + } + } + + private async rebuild() { + this.collection.clear(); + + const allOpenedTabResources = this.getAllTabResources(); + await Promise.all( + vscode.workspace.textDocuments + .filter(doc => allOpenedTabResources.has(doc.uri.toString()) && isMarkdownFile(doc)) + .map(doc => this.update(doc))); + } + + private getAllTabResources() { + const openedTabDocs = new Map(); + for (const group of vscode.window.tabGroups.all) { + for (const tab of group.tabs) { + if (tab.input instanceof vscode.TabInputText) { + openedTabDocs.set(tab.input.uri.toString(), tab.input.uri); + } + } + } + return openedTabDocs; + } + + private async update(doc: vscode.TextDocument): Promise { + const diagnostics = await this.getDiagnostics(doc, noopToken); + this.collection.set(doc.uri, diagnostics); + } + + public async getDiagnostics(doc: SkinnyTextDocument, token: vscode.CancellationToken): Promise { + const config = this.configuration.getOptions(doc.uri); + if (!config.enabled) { + return []; + } + return this.computer.getDiagnostics(doc, config, token); + } +} + +export class DiagnosticComputer { + + constructor( + private readonly engine: MarkdownEngine, + private readonly workspaceContents: MdWorkspaceContents, + private readonly linkProvider: MdLinkProvider, + ) { } + + public async getDiagnostics(doc: SkinnyTextDocument, options: DiagnosticOptions, token: vscode.CancellationToken): Promise { + const links = await this.linkProvider.getAllLinks(doc, token); + if (token.isCancellationRequested) { + return []; + } + + return (await Promise.all([ + this.validateFileLinks(doc, options, links, token), + Array.from(this.validateReferenceLinks(options, links)), + this.validateOwnHeaderLinks(doc, options, links, token), + ])).flat(); + } + + private async validateOwnHeaderLinks(doc: SkinnyTextDocument, options: DiagnosticOptions, links: readonly MdLink[], token: vscode.CancellationToken): Promise { + const severity = toSeverity(options.validateOwnHeaders); + if (typeof severity === 'undefined') { + return []; + } + + const toc = await TableOfContents.create(this.engine, doc); + if (token.isCancellationRequested) { + return []; + } + + const diagnostics: vscode.Diagnostic[] = []; + for (const link of links) { + if (link.href.kind === 'internal' + && link.href.path.toString() === doc.uri.toString() + && link.href.fragment + && !toc.lookup(link.href.fragment) + ) { + diagnostics.push(new vscode.Diagnostic( + link.source.hrefRange, + localize('invalidHeaderLink', 'No header found: \'{0}\'', link.href.fragment), + severity)); + } + } + + return diagnostics; + } + + private *validateReferenceLinks(options: DiagnosticOptions, links: readonly MdLink[]): Iterable { + const severity = toSeverity(options.validateReferences); + if (typeof severity === 'undefined') { + return []; + } + + const definitionSet = new LinkDefinitionSet(links); + for (const link of links) { + if (link.href.kind === 'reference' && !definitionSet.lookup(link.href.ref)) { + yield new vscode.Diagnostic( + link.source.hrefRange, + localize('invalidReferenceLink', 'No link reference found: \'{0}\'', link.href.ref), + severity); + } + } + } + + private async validateFileLinks(doc: SkinnyTextDocument, options: DiagnosticOptions, links: readonly MdLink[], token: vscode.CancellationToken): Promise { + const severity = toSeverity(options.validateFilePaths); + if (typeof severity === 'undefined') { + return []; + } + + const tocs = new Map(); + + // TODO: cache links so we don't recompute duplicate hrefs + // TODO: parallelize + + const diagnostics: vscode.Diagnostic[] = []; + for (const link of links) { + if (token.isCancellationRequested) { + return []; + } + + if (link.href.kind !== 'internal') { + continue; + } + + const hrefDoc = await tryFindMdDocumentForLink(link.href, this.workspaceContents); + if (hrefDoc && hrefDoc.uri.toString() === doc.uri.toString()) { + continue; + } + + if (!hrefDoc && !await this.workspaceContents.pathExists(link.href.path)) { + diagnostics.push( + new vscode.Diagnostic( + link.source.hrefRange, + localize('invalidPathLink', 'File does not exist at path: {0}', (link.href as InternalHref).path.toString(true)), + severity)); + } else if (hrefDoc) { + if (link.href.fragment) { + // validate fragment looks valid + let hrefDocToc = tocs.get(link.href.path.toString()); + if (!hrefDocToc) { + hrefDocToc = await TableOfContents.create(this.engine, hrefDoc); + tocs.set(link.href.path.toString(), hrefDocToc); + } + + if (!hrefDocToc.lookup(link.href.fragment)) { + diagnostics.push( + new vscode.Diagnostic( + link.source.hrefRange, + localize('invalidLinkToHeaderInOtherFile', 'Header does not exist in file: {0}', (link.href as InternalHref).path.fragment), + severity)); } - break; } } } - return fixes; + return diagnostics; } } - -export function registerDiagnosticSupport( - selector: vscode.DocumentSelector, - commandManager: CommandManager, +export function register( + engine: MarkdownEngine, + workspaceContents: MdWorkspaceContents, + linkProvider: MdLinkProvider, ): vscode.Disposable { - return AddToIgnoreLinksQuickFixProvider.register(selector, commandManager); + const configuration = new VSCodeDiagnosticConfiguration(); + const manager = new DiagnosticManager(new DiagnosticComputer(engine, workspaceContents, linkProvider), configuration); + return vscode.Disposable.from(configuration, manager); } diff --git a/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts b/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts new file mode 100644 index 0000000000..89be468fac --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/documentLinkProvider.ts @@ -0,0 +1,421 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as nls from 'vscode-nls'; +import * as uri from 'vscode-uri'; +import { OpenDocumentLinkCommand } from '../commands/openDocumentLink'; +import { MarkdownEngine } from '../markdownEngine'; +import { coalesce } from '../util/arrays'; +import { getUriForLinkWithKnownExternalScheme, isOfScheme, Schemes } from '../util/schemes'; +import { SkinnyTextDocument } from '../workspaceContents'; + +const localize = nls.loadMessageBundle(); + +export interface ExternalHref { + readonly kind: 'external'; + readonly uri: vscode.Uri; +} + +export interface InternalHref { + readonly kind: 'internal'; + readonly path: vscode.Uri; + readonly fragment: string; +} + +export interface ReferenceHref { + readonly kind: 'reference'; + readonly ref: string; +} + +export type LinkHref = ExternalHref | InternalHref | ReferenceHref; + + +function parseLink( + document: SkinnyTextDocument, + link: string, +): ExternalHref | InternalHref | undefined { + const cleanLink = stripAngleBrackets(link); + const externalSchemeUri = getUriForLinkWithKnownExternalScheme(cleanLink); + if (externalSchemeUri) { + // Normalize VS Code links to target currently running version + if (isOfScheme(Schemes.vscode, link) || isOfScheme(Schemes['vscode-insiders'], link)) { + return { kind: 'external', uri: vscode.Uri.parse(link).with({ scheme: vscode.env.uriScheme }) }; + } + return { kind: 'external', uri: externalSchemeUri }; + } + + // Assume it must be an relative or absolute file path + // Use a fake scheme to avoid parse warnings + const tempUri = vscode.Uri.parse(`vscode-resource:${link}`); + + let resourceUri: vscode.Uri | undefined; + if (!tempUri.path) { + resourceUri = document.uri; + } else if (tempUri.path[0] === '/') { + const root = getWorkspaceFolder(document); + if (root) { + resourceUri = vscode.Uri.joinPath(root, tempUri.path); + } + } else { + if (document.uri.scheme === Schemes.untitled) { + const root = getWorkspaceFolder(document); + if (root) { + resourceUri = vscode.Uri.joinPath(root, tempUri.path); + } + } else { + const base = uri.Utils.dirname(document.uri); + resourceUri = vscode.Uri.joinPath(base, tempUri.path); + } + } + + if (!resourceUri) { + return undefined; + } + + return { + kind: 'internal', + path: resourceUri.with({ fragment: '' }), + fragment: tempUri.fragment, + }; +} + +function getWorkspaceFolder(document: SkinnyTextDocument) { + return vscode.workspace.getWorkspaceFolder(document.uri)?.uri + || vscode.workspace.workspaceFolders?.[0]?.uri; +} + +interface MdLinkSource { + readonly text: string; + readonly resource: vscode.Uri; + readonly hrefRange: vscode.Range; + readonly fragmentRange: vscode.Range | undefined; +} + +export interface MdInlineLink { + readonly kind: 'link'; + readonly source: MdLinkSource; + readonly href: LinkHref; +} + +export interface MdLinkDefinition { + readonly kind: 'definition'; + readonly source: MdLinkSource; + readonly ref: { + readonly range: vscode.Range; + readonly text: string; + }; + readonly href: ExternalHref | InternalHref; +} + +export type MdLink = MdInlineLink | MdLinkDefinition; + +function extractDocumentLink( + document: SkinnyTextDocument, + pre: number, + link: string, + matchIndex: number | undefined +): MdLink | undefined { + const offset = (matchIndex || 0) + pre; + const linkStart = document.positionAt(offset); + const linkEnd = document.positionAt(offset + link.length); + try { + const linkTarget = parseLink(document, link); + if (!linkTarget) { + return undefined; + } + return { + kind: 'link', + href: linkTarget, + source: { + text: link, + resource: document.uri, + hrefRange: new vscode.Range(linkStart, linkEnd), + fragmentRange: getFragmentRange(link, linkStart, linkEnd), + } + }; + } catch { + return undefined; + } +} + +function getFragmentRange(text: string, start: vscode.Position, end: vscode.Position): vscode.Range | undefined { + const index = text.indexOf('#'); + if (index < 0) { + return undefined; + } + return new vscode.Range(start.translate({ characterDelta: index + 1 }), end); +} + +const angleBracketLinkRe = /^<(.*)>$/; + +/** + * Used to strip brackets from the markdown link + * + * will be transformed to http://example.com +*/ +function stripAngleBrackets(link: string) { + return link.replace(angleBracketLinkRe, '$1'); +} + +/** + * Matches `[text](link)` + */ +const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*(".*?")?\)/g; + +/** + * Matches `[text][ref]` + */ +const referenceLinkPattern = /(?:(\[((?:\\\]|[^\]])+)\]\[\s*?)([^\s\]]*?)\]|\[\s*?([^\s\]]*?)\])(?![\:\(])/g; + +/** + * Matches `` + */ +const autoLinkPattern = /\<(\w+:[^\>\s]+)\>/g; + +/** + * Matches `[text]: link` + */ +const definitionPattern = /^([\t ]*\[(?!\^)((?:\\\]|[^\]])+)\]:\s*)([^<]\S*|<[^>]+>)/gm; + +const inlineCodePattern = /(?:^|[^`])(`+)(?:.+?|.*?(?:(?:\r?\n).+?)*?)(?:\r?\n)?\1(?:$|[^`])/gm; + +interface CodeInDocument { + /** + * code blocks and fences each represented by [line_start,line_end). + */ + readonly multiline: ReadonlyArray<[number, number]>; + + /** + * inline code spans each represented by {@link vscode.Range}. + */ + readonly inline: readonly vscode.Range[]; +} + +async function findCode(document: SkinnyTextDocument, engine: MarkdownEngine): Promise { + const tokens = await engine.parse(document); + const multiline = tokens.filter(t => (t.type === 'code_block' || t.type === 'fence') && !!t.map).map(t => t.map) as [number, number][]; + + const text = document.getText(); + const inline = [...text.matchAll(inlineCodePattern)].map(match => { + const start = match.index || 0; + return new vscode.Range(document.positionAt(start), document.positionAt(start + match[0].length)); + }); + + return { multiline, inline }; +} + +function isLinkInsideCode(code: CodeInDocument, linkHrefRange: vscode.Range) { + return code.multiline.some(interval => linkHrefRange.start.line >= interval[0] && linkHrefRange.start.line < interval[1]) || + code.inline.some(position => position.intersection(linkHrefRange)); +} + +export class MdLinkProvider implements vscode.DocumentLinkProvider { + + constructor( + private readonly engine: MarkdownEngine + ) { } + + public async provideDocumentLinks( + document: SkinnyTextDocument, + token: vscode.CancellationToken + ): Promise { + const allLinks = await this.getAllLinks(document, token); + if (token.isCancellationRequested) { + return []; + } + + const definitionSet = new LinkDefinitionSet(allLinks); + return coalesce(allLinks + .map(data => this.toValidDocumentLink(data, definitionSet))); + } + + private toValidDocumentLink(link: MdLink, definitionSet: LinkDefinitionSet): vscode.DocumentLink | undefined { + switch (link.href.kind) { + case 'external': { + return new vscode.DocumentLink(link.source.hrefRange, link.href.uri); + } + case 'internal': { + const uri = OpenDocumentLinkCommand.createCommandUri(link.source.resource, link.href.path, link.href.fragment); + const documentLink = new vscode.DocumentLink(link.source.hrefRange, uri); + documentLink.tooltip = localize('documentLink.tooltip', 'Follow link'); + return documentLink; + } + case 'reference': { + const def = definitionSet.lookup(link.href.ref); + if (def) { + return new vscode.DocumentLink( + link.source.hrefRange, + vscode.Uri.parse(`command:_markdown.moveCursorToPosition?${encodeURIComponent(JSON.stringify([def.source.hrefRange.start.line, def.source.hrefRange.start.character]))}`)); + } else { + return undefined; + } + } + } + } + + public async getAllLinks(document: SkinnyTextDocument, token: vscode.CancellationToken): Promise { + const codeInDocument = await findCode(document, this.engine); + if (token.isCancellationRequested) { + return []; + } + + return Array.from([ + ...this.getInlineLinks(document, codeInDocument), + ...this.getReferenceLinks(document, codeInDocument), + ...this.getLinkDefinitions2(document, codeInDocument), + ...this.getAutoLinks(document, codeInDocument), + ]); + } + + private *getInlineLinks(document: SkinnyTextDocument, codeInDocument: CodeInDocument): Iterable { + const text = document.getText(); + + for (const match of text.matchAll(linkPattern)) { + const matchImageData = match[4] && extractDocumentLink(document, match[3].length + 1, match[4], match.index); + if (matchImageData && !isLinkInsideCode(codeInDocument, matchImageData.source.hrefRange)) { + yield matchImageData; + } + const matchLinkData = extractDocumentLink(document, match[1].length, match[5], match.index); + if (matchLinkData && !isLinkInsideCode(codeInDocument, matchLinkData.source.hrefRange)) { + yield matchLinkData; + } + } + } + + private *getAutoLinks(document: SkinnyTextDocument, codeInDocument: CodeInDocument): Iterable { + const text = document.getText(); + + for (const match of text.matchAll(autoLinkPattern)) { + const link = match[1]; + const linkTarget = parseLink(document, link); + if (linkTarget) { + const offset = (match.index ?? 0) + 1; + const linkStart = document.positionAt(offset); + const linkEnd = document.positionAt(offset + link.length); + const hrefRange = new vscode.Range(linkStart, linkEnd); + if (isLinkInsideCode(codeInDocument, hrefRange)) { + continue; + } + yield { + kind: 'link', + href: linkTarget, + source: { + text: link, + resource: document.uri, + hrefRange: new vscode.Range(linkStart, linkEnd), + fragmentRange: getFragmentRange(link, linkStart, linkEnd), + } + }; + } + } + } + + private *getReferenceLinks(document: SkinnyTextDocument, codeInDocument: CodeInDocument): Iterable { + const text = document.getText(); + for (const match of text.matchAll(referenceLinkPattern)) { + let linkStart: vscode.Position; + let linkEnd: vscode.Position; + let reference = match[3]; + if (reference) { // [text][ref] + const pre = match[1]; + const offset = (match.index || 0) + pre.length; + linkStart = document.positionAt(offset); + linkEnd = document.positionAt(offset + reference.length); + } else if (match[4]) { // [ref][], [ref] + reference = match[4]; + const offset = (match.index || 0) + 1; + linkStart = document.positionAt(offset); + linkEnd = document.positionAt(offset + reference.length); + } else { + continue; + } + + const hrefRange = new vscode.Range(linkStart, linkEnd); + if (isLinkInsideCode(codeInDocument, hrefRange)) { + continue; + } + + yield { + kind: 'link', + source: { + text: reference, + resource: document.uri, + hrefRange, + fragmentRange: undefined, + }, + href: { + kind: 'reference', + ref: reference, + } + }; + } + } + + public async getLinkDefinitions(document: SkinnyTextDocument): Promise> { + const codeInDocument = await findCode(document, this.engine); + return this.getLinkDefinitions2(document, codeInDocument); + } + + private *getLinkDefinitions2(document: SkinnyTextDocument, codeInDocument: CodeInDocument): Iterable { + const text = document.getText(); + for (const match of text.matchAll(definitionPattern)) { + const pre = match[1]; + const reference = match[2]; + const link = match[3].trim(); + const offset = (match.index || 0) + pre.length; + + const refStart = document.positionAt((match.index ?? 0) + 1); + const refRange = new vscode.Range(refStart, refStart.translate({ characterDelta: reference.length })); + + let linkStart: vscode.Position; + let linkEnd: vscode.Position; + let text: string; + if (angleBracketLinkRe.test(link)) { + linkStart = document.positionAt(offset + 1); + linkEnd = document.positionAt(offset + link.length - 1); + text = link.substring(1, link.length - 1); + } else { + linkStart = document.positionAt(offset); + linkEnd = document.positionAt(offset + link.length); + text = link; + } + const hrefRange = new vscode.Range(linkStart, linkEnd); + if (isLinkInsideCode(codeInDocument, hrefRange)) { + continue; + } + const target = parseLink(document, text); + if (target) { + yield { + kind: 'definition', + source: { + text: link, + resource: document.uri, + hrefRange, + fragmentRange: getFragmentRange(link, linkStart, linkEnd), + }, + ref: { text: reference, range: refRange }, + href: target, + }; + } + } + } +} + +export class LinkDefinitionSet { + private readonly _map = new Map(); + + constructor(links: Iterable) { + for (const link of links) { + if (link.kind === 'definition') { + this._map.set(link.ref.text, link); + } + } + } + + public lookup(ref: string): MdLinkDefinition | undefined { + return this._map.get(ref); + } +} diff --git a/extensions/markdown-language-features/src/languageFeatures/documentSymbolProvider.ts b/extensions/markdown-language-features/src/languageFeatures/documentSymbolProvider.ts new file mode 100644 index 0000000000..6c73efd64a --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/documentSymbolProvider.ts @@ -0,0 +1,76 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContents, TocEntry } from '../tableOfContents'; +import { SkinnyTextDocument } from '../workspaceContents'; + +interface MarkdownSymbol { + readonly level: number; + readonly parent: MarkdownSymbol | undefined; + readonly children: vscode.DocumentSymbol[]; +} + +export class MdDocumentSymbolProvider implements vscode.DocumentSymbolProvider { + + constructor( + private readonly engine: MarkdownEngine + ) { } + + public async provideDocumentSymbolInformation(document: SkinnyTextDocument): Promise { + const toc = await TableOfContents.create(this.engine, document); + return toc.entries.map(entry => this.toSymbolInformation(entry)); + } + + public async provideDocumentSymbols(document: SkinnyTextDocument): Promise { + const toc = await TableOfContents.create(this.engine, document); + const root: MarkdownSymbol = { + level: -Infinity, + children: [], + parent: undefined + }; + this.buildTree(root, toc.entries); + return root.children; + } + + private buildTree(parent: MarkdownSymbol, entries: readonly TocEntry[]) { + if (!entries.length) { + return; + } + + const entry = entries[0]; + const symbol = this.toDocumentSymbol(entry); + symbol.children = []; + + while (parent && entry.level <= parent.level) { + parent = parent.parent!; + } + parent.children.push(symbol); + this.buildTree({ level: entry.level, children: symbol.children, parent }, entries.slice(1)); + } + + + private toSymbolInformation(entry: TocEntry): vscode.SymbolInformation { + return new vscode.SymbolInformation( + this.getSymbolName(entry), + vscode.SymbolKind.String, + '', + entry.sectionLocation); + } + + private toDocumentSymbol(entry: TocEntry) { + return new vscode.DocumentSymbol( + this.getSymbolName(entry), + '', + vscode.SymbolKind.String, + entry.sectionLocation.range, + entry.sectionLocation.range); + } + + private getSymbolName(entry: TocEntry): string { + return '#'.repeat(entry.level) + ' ' + entry.text; + } +} diff --git a/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts b/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts index 5c2e49e78b..40322feb75 100644 --- a/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts +++ b/extensions/markdown-language-features/src/languageFeatures/dropIntoEditor.ts @@ -23,54 +23,49 @@ const imageFileExtensions = new Set([ '.webp', ]); -export function registerDropIntoEditorSupport(selector: vscode.DocumentSelector) { - return vscode.languages.registerDocumentDropEditProvider(selector, new class implements vscode.DocumentDropEditProvider { - async provideDocumentDropEdits(document: vscode.TextDocument, _position: vscode.Position, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise { +export function registerDropIntoEditor(selector: vscode.DocumentSelector) { + return vscode.languages.registerDocumentOnDropProvider(selector, new class implements vscode.DocumentOnDropProvider { + async provideDocumentOnDropEdits(document: vscode.TextDocument, position: vscode.Position, dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise { const enabled = vscode.workspace.getConfiguration('markdown', document).get('editor.drop.enabled', true); if (!enabled) { + return; + } + + const urlList = await dataTransfer.get('text/uri-list')?.asString(); + if (!urlList) { return undefined; } - const snippet = await tryGetUriListSnippet(document, dataTransfer, token); - return snippet ? new vscode.DocumentDropEdit(snippet) : undefined; + const uris: vscode.Uri[] = []; + for (const resource of urlList.split('\n')) { + try { + uris.push(vscode.Uri.parse(resource)); + } catch { + // noop + } + } + + if (!uris.length) { + return; + } + + const snippet = new vscode.SnippetString(); + uris.forEach((uri, i) => { + const mdPath = document.uri.scheme === uri.scheme + ? encodeURI(path.relative(URI.Utils.dirname(document.uri).fsPath, uri.fsPath)) + : uri.toString(false); + + const ext = URI.Utils.extname(uri).toLowerCase(); + snippet.appendText(imageFileExtensions.has(ext) ? '![' : '['); + snippet.appendTabstop(); + snippet.appendText(`](${mdPath})`); + + if (i <= uris.length - 1 && uris.length > 1) { + snippet.appendText(' '); + } + }); + + return new vscode.SnippetTextEdit(new vscode.Range(position, position), snippet); } }); } - -export async function tryGetUriListSnippet(document: vscode.TextDocument, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise { - const urlList = await dataTransfer.get('text/uri-list')?.asString(); - if (!urlList || token.isCancellationRequested) { - return undefined; - } - - const uris: vscode.Uri[] = []; - for (const resource of urlList.split('\n')) { - try { - uris.push(vscode.Uri.parse(resource)); - } catch { - // noop - } - } - - if (!uris.length) { - return; - } - - const snippet = new vscode.SnippetString(); - uris.forEach((uri, i) => { - const mdPath = document.uri.scheme === uri.scheme - ? encodeURI(path.relative(URI.Utils.dirname(document.uri).fsPath, uri.fsPath).replace(/\\/g, '/')) - : uri.toString(false); - - const ext = URI.Utils.extname(uri).toLowerCase(); - snippet.appendText(imageFileExtensions.has(ext) ? '![' : '['); - snippet.appendTabstop(); - snippet.appendText(`](${mdPath})`); - - if (i <= uris.length - 1 && uris.length > 1) { - snippet.appendText(' '); - } - }); - - return snippet; -} diff --git a/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts b/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts index 6ca2e06180..eb5b1a0b6f 100644 --- a/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts +++ b/extensions/markdown-language-features/src/languageFeatures/fileReferences.ts @@ -4,10 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { BaseLanguageClient } from 'vscode-languageclient'; import * as nls from 'vscode-nls'; import { Command, CommandManager } from '../commandManager'; -import { getReferencesToFileInWorkspace } from '../protocol'; +import { MdReferencesProvider } from './references'; const localize = nls.loadMessageBundle(); @@ -17,7 +16,7 @@ export class FindFileReferencesCommand implements Command { public readonly id = 'markdown.findAllFileReferences'; constructor( - private readonly client: BaseLanguageClient, + private readonly referencesProvider: MdReferencesProvider, ) { } public async execute(resource?: vscode.Uri) { @@ -34,9 +33,8 @@ export class FindFileReferencesCommand implements Command { location: vscode.ProgressLocation.Window, title: localize('progress.title', "Finding file references") }, async (_progress, token) => { - const locations = (await this.client.sendRequest(getReferencesToFileInWorkspace, { uri: resource!.toString() }, token)).map(loc => { - return new vscode.Location(vscode.Uri.parse(loc.uri), new vscode.Range(loc.range.start.line, loc.range.start.character, loc.range.end.line, loc.range.end.character)); - }); + const references = await this.referencesProvider.getAllReferencesToFile(resource!, token); + const locations = references.map(ref => ref.location); const config = vscode.workspace.getConfiguration('references'); const existingSetting = config.inspect('preferredLocation'); @@ -51,9 +49,6 @@ export class FindFileReferencesCommand implements Command { } } -export function registerFindFileReferenceSupport( - commandManager: CommandManager, - client: BaseLanguageClient, -): vscode.Disposable { - return commandManager.register(new FindFileReferencesCommand(client)); +export function registerFindFileReferences(commandManager: CommandManager, referencesProvider: MdReferencesProvider): vscode.Disposable { + return commandManager.register(new FindFileReferencesCommand(referencesProvider)); } diff --git a/extensions/markdown-language-features/src/languageFeatures/foldingProvider.ts b/extensions/markdown-language-features/src/languageFeatures/foldingProvider.ts new file mode 100644 index 0000000000..61407e671b --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/foldingProvider.ts @@ -0,0 +1,113 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import Token = require('markdown-it/lib/token'); +import * as vscode from 'vscode'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContents } from '../tableOfContents'; +import { SkinnyTextDocument } from '../workspaceContents'; + +const rangeLimit = 5000; + +interface MarkdownItTokenWithMap extends Token { + map: [number, number]; +} + +export class MdFoldingProvider implements vscode.FoldingRangeProvider { + + constructor( + private readonly engine: MarkdownEngine + ) { } + + public async provideFoldingRanges( + document: SkinnyTextDocument, + _: vscode.FoldingContext, + _token: vscode.CancellationToken + ): Promise { + const foldables = await Promise.all([ + this.getRegions(document), + this.getHeaderFoldingRanges(document), + this.getBlockFoldingRanges(document) + ]); + return foldables.flat().slice(0, rangeLimit); + } + + private async getRegions(document: SkinnyTextDocument): Promise { + const tokens = await this.engine.parse(document); + const regionMarkers = tokens.filter(isRegionMarker) + .map(token => ({ line: token.map[0], isStart: isStartRegion(token.content) })); + + const nestingStack: { line: number; isStart: boolean }[] = []; + return regionMarkers + .map(marker => { + if (marker.isStart) { + nestingStack.push(marker); + } else if (nestingStack.length && nestingStack[nestingStack.length - 1].isStart) { + return new vscode.FoldingRange(nestingStack.pop()!.line, marker.line, vscode.FoldingRangeKind.Region); + } else { + // noop: invalid nesting (i.e. [end, start] or [start, end, end]) + } + return null; + }) + .filter((region: vscode.FoldingRange | null): region is vscode.FoldingRange => !!region); + } + + private async getHeaderFoldingRanges(document: SkinnyTextDocument) { + const toc = await TableOfContents.create(this.engine, document); + return toc.entries.map(entry => { + let endLine = entry.sectionLocation.range.end.line; + if (document.lineAt(endLine).isEmptyOrWhitespace && endLine >= entry.line + 1) { + endLine = endLine - 1; + } + return new vscode.FoldingRange(entry.line, endLine); + }); + } + + private async getBlockFoldingRanges(document: SkinnyTextDocument): Promise { + const tokens = await this.engine.parse(document); + const multiLineListItems = tokens.filter(isFoldableToken); + return multiLineListItems.map(listItem => { + const start = listItem.map[0]; + let end = listItem.map[1] - 1; + if (document.lineAt(end).isEmptyOrWhitespace && end >= start + 1) { + end = end - 1; + } + return new vscode.FoldingRange(start, end, this.getFoldingRangeKind(listItem)); + }); + } + + private getFoldingRangeKind(listItem: Token): vscode.FoldingRangeKind | undefined { + return listItem.type === 'html_block' && listItem.content.startsWith('/.test(t); +const isEndRegion = (t: string) => /^\s*/.test(t); + +const isRegionMarker = (token: Token): token is MarkdownItTokenWithMap => + !!token.map && token.type === 'html_block' && (isStartRegion(token.content) || isEndRegion(token.content)); + +const isFoldableToken = (token: Token): token is MarkdownItTokenWithMap => { + if (!token.map) { + return false; + } + + switch (token.type) { + case 'fence': + case 'list_item_open': + return token.map[1] > token.map[0]; + + case 'html_block': + if (isRegionMarker(token)) { + return false; + } + return token.map[1] > token.map[0] + 1; + + default: + return false; + } +}; diff --git a/extensions/markdown-language-features/src/languageFeatures/pathCompletions.ts b/extensions/markdown-language-features/src/languageFeatures/pathCompletions.ts new file mode 100644 index 0000000000..85c92b4c51 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/pathCompletions.ts @@ -0,0 +1,353 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { dirname, resolve } from 'path'; +import * as vscode from 'vscode'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContents } from '../tableOfContents'; +import { resolveUriToMarkdownFile } from '../util/openDocumentLink'; +import { SkinnyTextDocument } from '../workspaceContents'; +import { MdLinkProvider } from './documentLinkProvider'; + +enum CompletionContextKind { + /** `[...](|)` */ + Link, + + /** `[...][|]` */ + ReferenceLink, + + /** `[]: |` */ + LinkDefinition, +} + +interface AnchorContext { + /** + * Link text before the `#`. + * + * For `[text](xy#z|abc)` this is `xy`. + */ + readonly beforeAnchor: string; + + /** + * Text of the anchor before the current position. + * + * For `[text](xy#z|abc)` this is `z`. + */ + readonly anchorPrefix: string; +} + +interface CompletionContext { + readonly kind: CompletionContextKind; + + /** + * Text of the link before the current position + * + * For `[text](xy#z|abc)` this is `xy#z`. + */ + readonly linkPrefix: string; + + /** + * Position of the start of the link. + * + * For `[text](xy#z|abc)` this is the position before `xy`. + */ + readonly linkTextStartPosition: vscode.Position; + + /** + * Text of the link after the current position. + * + * For `[text](xy#z|abc)` this is `abc`. + */ + readonly linkSuffix: string; + + /** + * Info if the link looks like it is for an anchor: `[](#header)` + */ + readonly anchorInfo?: AnchorContext; +} + +function tryDecodeUriComponent(str: string): string { + try { + return decodeURIComponent(str); + } catch { + return str; + } +} + +export class MdPathCompletionProvider implements vscode.CompletionItemProvider { + + public static register( + selector: vscode.DocumentSelector, + engine: MarkdownEngine, + linkProvider: MdLinkProvider, + ): vscode.Disposable { + return vscode.languages.registerCompletionItemProvider(selector, new MdPathCompletionProvider(engine, linkProvider), '.', '/', '#'); + } + + constructor( + private readonly engine: MarkdownEngine, + private readonly linkProvider: MdLinkProvider, + ) { } + + public async provideCompletionItems(document: SkinnyTextDocument, position: vscode.Position, _token: vscode.CancellationToken, _context: vscode.CompletionContext): Promise { + if (!this.arePathSuggestionEnabled(document)) { + return []; + } + + const context = this.getPathCompletionContext(document, position); + if (!context) { + return []; + } + + switch (context.kind) { + case CompletionContextKind.ReferenceLink: { + const items: vscode.CompletionItem[] = []; + for await (const item of this.provideReferenceSuggestions(document, position, context)) { + items.push(item); + } + return items; + } + + case CompletionContextKind.LinkDefinition: + case CompletionContextKind.Link: { + const items: vscode.CompletionItem[] = []; + + const isAnchorInCurrentDoc = context.anchorInfo && context.anchorInfo.beforeAnchor.length === 0; + + // Add anchor #links in current doc + if (context.linkPrefix.length === 0 || isAnchorInCurrentDoc) { + const insertRange = new vscode.Range(context.linkTextStartPosition, position); + for await (const item of this.provideHeaderSuggestions(document, position, context, insertRange)) { + items.push(item); + } + } + + if (!isAnchorInCurrentDoc) { + if (context.anchorInfo) { // Anchor to a different document + const rawUri = this.resolveReference(document, context.anchorInfo.beforeAnchor); + if (rawUri) { + const otherDoc = await resolveUriToMarkdownFile(rawUri); + if (otherDoc) { + const anchorStartPosition = position.translate({ characterDelta: -(context.anchorInfo.anchorPrefix.length + 1) }); + const range = new vscode.Range(anchorStartPosition, position); + for await (const item of this.provideHeaderSuggestions(otherDoc, position, context, range)) { + items.push(item); + } + } + } + } else { // Normal path suggestions + for await (const item of this.providePathSuggestions(document, position, context)) { + items.push(item); + } + } + } + + return items; + } + } + } + + private arePathSuggestionEnabled(document: SkinnyTextDocument): boolean { + const config = vscode.workspace.getConfiguration('markdown', document.uri); + return config.get('suggest.paths.enabled', true); + } + + /// [...](...| + private readonly linkStartPattern = /\[([^\]]*?)\]\(\s*([^\s\(\)]*)$/; + + /// [...][...| + private readonly referenceLinkStartPattern = /\[([^\]]*?)\]\[\s*([^\s\(\)]*)$/; + + /// [id]: | + private readonly definitionPattern = /^\s*\[[\w\-]+\]:\s*([^\s]*)$/m; + + private getPathCompletionContext(document: SkinnyTextDocument, position: vscode.Position): CompletionContext | undefined { + const line = document.lineAt(position.line).text; + + const linePrefixText = line.slice(0, position.character); + const lineSuffixText = line.slice(position.character); + + const linkPrefixMatch = linePrefixText.match(this.linkStartPattern); + if (linkPrefixMatch) { + const prefix = linkPrefixMatch[2]; + if (this.refLooksLikeUrl(prefix)) { + return undefined; + } + + const suffix = lineSuffixText.match(/^[^\)\s]*/); + return { + kind: CompletionContextKind.Link, + linkPrefix: tryDecodeUriComponent(prefix), + linkTextStartPosition: position.translate({ characterDelta: -prefix.length }), + linkSuffix: suffix ? suffix[0] : '', + anchorInfo: this.getAnchorContext(prefix), + }; + } + + const definitionLinkPrefixMatch = linePrefixText.match(this.definitionPattern); + if (definitionLinkPrefixMatch) { + const prefix = definitionLinkPrefixMatch[1]; + if (this.refLooksLikeUrl(prefix)) { + return undefined; + } + + const suffix = lineSuffixText.match(/^[^\s]*/); + return { + kind: CompletionContextKind.LinkDefinition, + linkPrefix: tryDecodeUriComponent(prefix), + linkTextStartPosition: position.translate({ characterDelta: -prefix.length }), + linkSuffix: suffix ? suffix[0] : '', + anchorInfo: this.getAnchorContext(prefix), + }; + } + + const referenceLinkPrefixMatch = linePrefixText.match(this.referenceLinkStartPattern); + if (referenceLinkPrefixMatch) { + const prefix = referenceLinkPrefixMatch[2]; + const suffix = lineSuffixText.match(/^[^\]\s]*/); + return { + kind: CompletionContextKind.ReferenceLink, + linkPrefix: prefix, + linkTextStartPosition: position.translate({ characterDelta: -prefix.length }), + linkSuffix: suffix ? suffix[0] : '', + }; + } + + return undefined; + } + + /** + * Check if {@param ref} looks like a 'http:' style url. + */ + private refLooksLikeUrl(prefix: string): boolean { + return /^\s*[\w\d\-]+:/.test(prefix); + } + + private getAnchorContext(prefix: string): AnchorContext | undefined { + const anchorMatch = prefix.match(/^(.*)#([\w\d\-]*)$/); + if (!anchorMatch) { + return undefined; + } + return { + beforeAnchor: anchorMatch[1], + anchorPrefix: anchorMatch[2], + }; + } + + private async *provideReferenceSuggestions(document: SkinnyTextDocument, position: vscode.Position, context: CompletionContext): AsyncIterable { + const insertionRange = new vscode.Range(context.linkTextStartPosition, position); + const replacementRange = new vscode.Range(insertionRange.start, position.translate({ characterDelta: context.linkSuffix.length })); + + const definitions = await this.linkProvider.getLinkDefinitions(document); + for (const def of definitions) { + yield { + kind: vscode.CompletionItemKind.Reference, + label: def.ref.text, + range: { + inserting: insertionRange, + replacing: replacementRange, + }, + }; + } + } + + private async *provideHeaderSuggestions(document: SkinnyTextDocument, position: vscode.Position, context: CompletionContext, insertionRange: vscode.Range): AsyncIterable { + const toc = await TableOfContents.createForDocumentOrNotebook(this.engine, document); + for (const entry of toc.entries) { + const replacementRange = new vscode.Range(insertionRange.start, position.translate({ characterDelta: context.linkSuffix.length })); + yield { + kind: vscode.CompletionItemKind.Reference, + label: '#' + decodeURIComponent(entry.slug.value), + range: { + inserting: insertionRange, + replacing: replacementRange, + }, + }; + } + } + + private async *providePathSuggestions(document: SkinnyTextDocument, position: vscode.Position, context: CompletionContext): AsyncIterable { + const valueBeforeLastSlash = context.linkPrefix.substring(0, context.linkPrefix.lastIndexOf('/') + 1); // keep the last slash + + const parentDir = this.resolveReference(document, valueBeforeLastSlash || '.'); + if (!parentDir) { + return; + } + + const pathSegmentStart = position.translate({ characterDelta: valueBeforeLastSlash.length - context.linkPrefix.length }); + const insertRange = new vscode.Range(pathSegmentStart, position); + + const pathSegmentEnd = position.translate({ characterDelta: context.linkSuffix.length }); + const replacementRange = new vscode.Range(pathSegmentStart, pathSegmentEnd); + + let dirInfo: Array<[string, vscode.FileType]>; + try { + dirInfo = await vscode.workspace.fs.readDirectory(parentDir); + } catch { + return; + } + + for (const [name, type] of dirInfo) { + // Exclude paths that start with `.` + if (name.startsWith('.')) { + continue; + } + + const isDir = type === vscode.FileType.Directory; + yield { + label: isDir ? name + '/' : name, + insertText: isDir ? encodeURIComponent(name) + '/' : encodeURIComponent(name), + kind: isDir ? vscode.CompletionItemKind.Folder : vscode.CompletionItemKind.File, + range: { + inserting: insertRange, + replacing: replacementRange, + }, + command: isDir ? { command: 'editor.action.triggerSuggest', title: '' } : undefined, + }; + } + } + + private resolveReference(document: SkinnyTextDocument, ref: string): vscode.Uri | undefined { + const docUri = this.getFileUriOfTextDocument(document); + + if (ref.startsWith('/')) { + const workspaceFolder = vscode.workspace.getWorkspaceFolder(docUri); + if (workspaceFolder) { + return vscode.Uri.joinPath(workspaceFolder.uri, ref); + } else { + return this.resolvePath(docUri, ref.slice(1)); + } + } + + return this.resolvePath(docUri, ref); + } + + private resolvePath(root: vscode.Uri, ref: string): vscode.Uri | undefined { + try { + if (root.scheme === 'file') { + return vscode.Uri.file(resolve(dirname(root.fsPath), ref)); + } else { + return root.with({ + path: resolve(dirname(root.path), ref), + }); + } + } catch { + return undefined; + } + } + + private getFileUriOfTextDocument(document: SkinnyTextDocument) { + if (document.uri.scheme === 'vscode-notebook-cell') { + const notebook = vscode.workspace.notebookDocuments + .find(notebook => notebook.getCells().some(cell => cell.document === document)); + + if (notebook) { + return notebook.uri; + } + } + + return document.uri; + } +} diff --git a/extensions/markdown-language-features/src/languageFeatures/references.ts b/extensions/markdown-language-features/src/languageFeatures/references.ts new file mode 100644 index 0000000000..aa2e1f1ee9 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/references.ts @@ -0,0 +1,308 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as vscode from 'vscode'; +import * as uri from 'vscode-uri'; +import { MarkdownEngine } from '../markdownEngine'; +import { Slugifier } from '../slugify'; +import { TableOfContents, TocEntry } from '../tableOfContents'; +import { noopToken } from '../test/util'; +import { Disposable } from '../util/dispose'; +import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; +import { InternalHref, MdLink, MdLinkProvider } from './documentLinkProvider'; +import { MdWorkspaceCache } from './workspaceCache'; + + +/** + * A link in a markdown file. + */ +export interface MdLinkReference { + readonly kind: 'link'; + readonly isTriggerLocation: boolean; + readonly isDefinition: boolean; + readonly location: vscode.Location; + + readonly link: MdLink; +} + +/** + * A header in a markdown file. + */ +export interface MdHeaderReference { + readonly kind: 'header'; + + readonly isTriggerLocation: boolean; + readonly isDefinition: boolean; + + /** + * The range of the header. + * + * In `# a b c #` this would be the range of `# a b c #` + */ + readonly location: vscode.Location; + + /** + * The text of the header. + * + * In `# a b c #` this would be `a b c` + */ + readonly headerText: string; + + /** + * The range of the header text itself. + * + * In `# a b c #` this would be the range of `a b c` + */ + readonly headerTextLocation: vscode.Location; +} + +export type MdReference = MdLinkReference | MdHeaderReference; + +export class MdReferencesProvider extends Disposable implements vscode.ReferenceProvider { + + private readonly _linkCache: MdWorkspaceCache; + + public constructor( + private readonly linkProvider: MdLinkProvider, + private readonly workspaceContents: MdWorkspaceContents, + private readonly engine: MarkdownEngine, + private readonly slugifier: Slugifier, + ) { + super(); + + this._linkCache = this._register(new MdWorkspaceCache(workspaceContents, doc => linkProvider.getAllLinks(doc, noopToken))); + } + + async provideReferences(document: SkinnyTextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): Promise { + const allRefs = await this.getAllReferencesAtPosition(document, position, token); + + return allRefs + .filter(ref => context.includeDeclaration || !ref.isDefinition) + .map(ref => ref.location); + } + + public async getAllReferencesAtPosition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + const toc = await TableOfContents.create(this.engine, document); + if (token.isCancellationRequested) { + return []; + } + + const header = toc.entries.find(entry => entry.line === position.line); + if (header) { + return this.getReferencesToHeader(document, header); + } else { + return this.getReferencesToLinkAtPosition(document, position, token); + } + } + + private async getReferencesToHeader(document: SkinnyTextDocument, header: TocEntry): Promise { + const links = (await this._linkCache.getAll()).flat(); + + const references: MdReference[] = []; + + references.push({ + kind: 'header', + isTriggerLocation: true, + isDefinition: true, + location: header.headerLocation, + headerText: header.text, + headerTextLocation: header.headerTextLocation + }); + + for (const link of links) { + if (link.href.kind === 'internal' + && this.looksLikeLinkToDoc(link.href, document.uri) + && this.slugifier.fromHeading(link.href.fragment).value === header.slug.value + ) { + references.push({ + kind: 'link', + isTriggerLocation: false, + isDefinition: false, + link, + location: new vscode.Location(link.source.resource, link.source.hrefRange), + }); + } + } + + return references; + } + + private async getReferencesToLinkAtPosition(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + const docLinks = await this.linkProvider.getAllLinks(document, token); + + for (const link of docLinks) { + if (link.kind === 'definition') { + // We could be in either the ref name or the definition + if (link.ref.range.contains(position)) { + return Array.from(this.getReferencesToLinkReference(docLinks, link.ref.text, { resource: document.uri, range: link.ref.range })); + } else if (link.source.hrefRange.contains(position)) { + return this.getReferencesToLink(link, position, token); + } + } else { + if (link.source.hrefRange.contains(position)) { + return this.getReferencesToLink(link, position, token); + } + } + } + + return []; + } + + private async getReferencesToLink(sourceLink: MdLink, triggerPosition: vscode.Position, token: vscode.CancellationToken): Promise { + const allLinksInWorkspace = (await this._linkCache.getAll()).flat(); + if (token.isCancellationRequested) { + return []; + } + + if (sourceLink.href.kind === 'reference') { + return Array.from(this.getReferencesToLinkReference(allLinksInWorkspace, sourceLink.href.ref, { resource: sourceLink.source.resource, range: sourceLink.source.hrefRange })); + } + + if (sourceLink.href.kind === 'external') { + const references: MdReference[] = []; + + for (const link of allLinksInWorkspace) { + if (link.href.kind === 'external' && link.href.uri.toString() === sourceLink.href.uri.toString()) { + const isTriggerLocation = sourceLink.source.resource.fsPath === link.source.resource.fsPath && sourceLink.source.hrefRange.isEqual(link.source.hrefRange); + references.push({ + kind: 'link', + isTriggerLocation, + isDefinition: false, + link, + location: new vscode.Location(link.source.resource, link.source.hrefRange), + }); + } + } + return references; + } + + const targetDoc = await tryFindMdDocumentForLink(sourceLink.href, this.workspaceContents); + if (token.isCancellationRequested) { + return []; + } + + const references: MdReference[] = []; + + if (targetDoc && sourceLink.href.fragment && sourceLink.source.fragmentRange?.contains(triggerPosition)) { + const toc = await TableOfContents.create(this.engine, targetDoc); + const entry = toc.lookup(sourceLink.href.fragment); + if (entry) { + references.push({ + kind: 'header', + isTriggerLocation: false, + isDefinition: true, + location: entry.headerLocation, + headerText: entry.text, + headerTextLocation: entry.headerTextLocation + }); + } + + for (const link of allLinksInWorkspace) { + if (link.href.kind !== 'internal' || !this.looksLikeLinkToDoc(link.href, targetDoc.uri)) { + continue; + } + + if (this.slugifier.fromHeading(link.href.fragment).equals(this.slugifier.fromHeading(sourceLink.href.fragment))) { + const isTriggerLocation = sourceLink.source.resource.fsPath === link.source.resource.fsPath && sourceLink.source.hrefRange.isEqual(link.source.hrefRange); + references.push({ + kind: 'link', + isTriggerLocation, + isDefinition: false, + link, + location: new vscode.Location(link.source.resource, link.source.hrefRange), + }); + } + } + } else { // Triggered on a link without a fragment so we only require matching the file and ignore fragments + references.push(...this.findAllLinksToFile(targetDoc?.uri ?? sourceLink.href.path, allLinksInWorkspace, sourceLink)); + } + + return references; + } + + private looksLikeLinkToDoc(href: InternalHref, targetDoc: vscode.Uri) { + return href.path.fsPath === targetDoc.fsPath + || uri.Utils.extname(href.path) === '' && href.path.with({ path: href.path.path + '.md' }).fsPath === targetDoc.fsPath; + } + + public async getAllReferencesToFile(resource: vscode.Uri, _token: vscode.CancellationToken): Promise { + const allLinksInWorkspace = (await this._linkCache.getAll()).flat(); + return Array.from(this.findAllLinksToFile(resource, allLinksInWorkspace, undefined)); + } + + private * findAllLinksToFile(resource: vscode.Uri, allLinksInWorkspace: readonly MdLink[], sourceLink: MdLink | undefined): Iterable { + for (const link of allLinksInWorkspace) { + if (link.href.kind !== 'internal' || !this.looksLikeLinkToDoc(link.href, resource)) { + continue; + } + + // Exclude cases where the file is implicitly referencing itself + if (link.source.text.startsWith('#') && link.source.resource.fsPath === resource.fsPath) { + continue; + } + + const isTriggerLocation = !!sourceLink && sourceLink.source.resource.fsPath === link.source.resource.fsPath && sourceLink.source.hrefRange.isEqual(link.source.hrefRange); + const pathRange = this.getPathRange(link); + yield { + kind: 'link', + isTriggerLocation, + isDefinition: false, + link, + location: new vscode.Location(link.source.resource, pathRange), + }; + } + } + + private * getReferencesToLinkReference(allLinks: Iterable, refToFind: string, from: { resource: vscode.Uri; range: vscode.Range }): Iterable { + for (const link of allLinks) { + let ref: string; + if (link.kind === 'definition') { + ref = link.ref.text; + } else if (link.href.kind === 'reference') { + ref = link.href.ref; + } else { + continue; + } + + if (ref === refToFind && link.source.resource.fsPath === from.resource.fsPath) { + const isTriggerLocation = from.resource.fsPath === link.source.resource.fsPath && ( + (link.href.kind === 'reference' && from.range.isEqual(link.source.hrefRange)) || (link.kind === 'definition' && from.range.isEqual(link.ref.range))); + + const pathRange = this.getPathRange(link); + yield { + kind: 'link', + isTriggerLocation, + isDefinition: link.kind === 'definition', + link, + location: new vscode.Location(from.resource, pathRange), + }; + } + } + } + + /** + * Get just the range of the file path, dropping the fragment + */ + private getPathRange(link: MdLink): vscode.Range { + return link.source.fragmentRange + ? link.source.hrefRange.with(undefined, link.source.fragmentRange.start.translate(0, -1)) + : link.source.hrefRange; + } +} + +export async function tryFindMdDocumentForLink(href: InternalHref, workspaceContents: MdWorkspaceContents): Promise { + const targetDoc = await workspaceContents.getMarkdownDocument(href.path); + if (targetDoc) { + return targetDoc; + } + + // We don't think the file exists. If it doesn't already have an extension, try tacking on a `.md` and using that instead + if (uri.Utils.extname(href.path) === '') { + const dotMdResource = href.path.with({ path: href.path.path + '.md' }); + return workspaceContents.getMarkdownDocument(dotMdResource); + } + + return undefined; +} + diff --git a/extensions/markdown-language-features/src/languageFeatures/rename.ts b/extensions/markdown-language-features/src/languageFeatures/rename.ts new file mode 100644 index 0000000000..398ef6486b --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/rename.ts @@ -0,0 +1,272 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import * as path from 'path'; +import * as vscode from 'vscode'; +import * as nls from 'vscode-nls'; +import * as URI from 'vscode-uri'; +import { Slugifier } from '../slugify'; +import { Disposable } from '../util/dispose'; +import { resolveDocumentLink } from '../util/openDocumentLink'; +import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; +import { InternalHref } from './documentLinkProvider'; +import { MdHeaderReference, MdLinkReference, MdReference, MdReferencesProvider, tryFindMdDocumentForLink } from './references'; + +const localize = nls.loadMessageBundle(); + + +export interface MdReferencesResponse { + references: MdReference[]; + triggerRef: MdReference; +} + +interface MdFileRenameEdit { + readonly from: vscode.Uri; + readonly to: vscode.Uri; +} + +/** + * Type with additional metadata about the edits for testing + * + * This is needed since `vscode.WorkspaceEdit` does not expose info on file renames. + */ +export interface MdWorkspaceEdit { + readonly edit: vscode.WorkspaceEdit; + + readonly fileRenames?: ReadonlyArray; +} + +function tryDecodeUri(str: string): string { + try { + return decodeURI(str); + } catch { + return str; + } +} + +export class MdRenameProvider extends Disposable implements vscode.RenameProvider { + + private cachedRefs?: { + readonly resource: vscode.Uri; + readonly version: number; + readonly position: vscode.Position; + readonly triggerRef: MdReference; + readonly references: MdReference[]; + } | undefined; + + private readonly renameNotSupportedText = localize('invalidRenameLocation', "Rename not supported at location"); + + public constructor( + private readonly referencesProvider: MdReferencesProvider, + private readonly workspaceContents: MdWorkspaceContents, + private readonly slugifier: Slugifier, + ) { + super(); + } + + public async prepareRename(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + const allRefsInfo = await this.getAllReferences(document, position, token); + if (token.isCancellationRequested) { + return undefined; + } + + if (!allRefsInfo || !allRefsInfo.references.length) { + throw new Error(this.renameNotSupportedText); + } + + const triggerRef = allRefsInfo.triggerRef; + switch (triggerRef.kind) { + case 'header': { + return { range: triggerRef.headerTextLocation.range, placeholder: triggerRef.headerText }; + } + case 'link': { + if (triggerRef.link.kind === 'definition') { + // We may have been triggered on the ref or the definition itself + if (triggerRef.link.ref.range.contains(position)) { + return { range: triggerRef.link.ref.range, placeholder: triggerRef.link.ref.text }; + } + } + + if (triggerRef.link.href.kind === 'external') { + return { range: triggerRef.link.source.hrefRange, placeholder: document.getText(triggerRef.link.source.hrefRange) }; + } + + // See if we are renaming the fragment or the path + const { fragmentRange } = triggerRef.link.source; + if (fragmentRange?.contains(position)) { + const declaration = this.findHeaderDeclaration(allRefsInfo.references); + if (declaration) { + return { range: fragmentRange, placeholder: declaration.headerText }; + } + return { range: fragmentRange, placeholder: document.getText(fragmentRange) }; + } + + const range = this.getFilePathRange(triggerRef); + if (!range) { + throw new Error(this.renameNotSupportedText); + } + return { range, placeholder: tryDecodeUri(document.getText(range)) }; + } + } + } + + private getFilePathRange(ref: MdLinkReference): vscode.Range { + if (ref.link.source.fragmentRange) { + return ref.link.source.hrefRange.with(undefined, ref.link.source.fragmentRange.start.translate(0, -1)); + } + return ref.link.source.hrefRange; + } + + private findHeaderDeclaration(references: readonly MdReference[]): MdHeaderReference | undefined { + return references.find(ref => ref.isDefinition && ref.kind === 'header') as MdHeaderReference | undefined; + } + + public async provideRenameEdits(document: SkinnyTextDocument, position: vscode.Position, newName: string, token: vscode.CancellationToken): Promise { + return (await this.provideRenameEditsImpl(document, position, newName, token))?.edit; + } + + public async provideRenameEditsImpl(document: SkinnyTextDocument, position: vscode.Position, newName: string, token: vscode.CancellationToken): Promise { + const allRefsInfo = await this.getAllReferences(document, position, token); + if (token.isCancellationRequested || !allRefsInfo || !allRefsInfo.references.length) { + return undefined; + } + + const triggerRef = allRefsInfo.triggerRef; + + if (triggerRef.kind === 'link' && ( + (triggerRef.link.kind === 'definition' && triggerRef.link.ref.range.contains(position)) || triggerRef.link.href.kind === 'reference' + )) { + return this.renameReferenceLinks(allRefsInfo, newName); + } else if (triggerRef.kind === 'link' && triggerRef.link.href.kind === 'external') { + return this.renameExternalLink(allRefsInfo, newName); + } else if (triggerRef.kind === 'header' || (triggerRef.kind === 'link' && triggerRef.link.source.fragmentRange?.contains(position) && (triggerRef.link.kind === 'definition' || triggerRef.link.kind === 'link' && triggerRef.link.href.kind === 'internal'))) { + return this.renameFragment(allRefsInfo, newName); + } else if (triggerRef.kind === 'link' && !triggerRef.link.source.fragmentRange?.contains(position) && triggerRef.link.kind === 'link' && triggerRef.link.href.kind === 'internal') { + return this.renameFilePath(triggerRef.link.source.resource, triggerRef.link.href, allRefsInfo, newName); + } + + return undefined; + } + + private async renameFilePath(triggerDocument: vscode.Uri, triggerHref: InternalHref, allRefsInfo: MdReferencesResponse, newName: string): Promise { + const edit = new vscode.WorkspaceEdit(); + const fileRenames: MdFileRenameEdit[] = []; + + const targetDoc = await tryFindMdDocumentForLink(triggerHref, this.workspaceContents); + const targetUri = targetDoc?.uri ?? triggerHref.path; + + const rawNewFilePath = resolveDocumentLink(newName, triggerDocument); + let resolvedNewFilePath = rawNewFilePath; + if (!URI.Utils.extname(resolvedNewFilePath)) { + // If the newly entered path doesn't have a file extension but the original file did + // tack on a .md file extension + if (URI.Utils.extname(targetUri)) { + resolvedNewFilePath = resolvedNewFilePath.with({ + path: resolvedNewFilePath.path + '.md' + }); + } + } + + // First rename the file + if (await this.workspaceContents.pathExists(targetUri)) { + fileRenames.push({ from: targetUri, to: resolvedNewFilePath }); + edit.renameFile(targetUri, resolvedNewFilePath); + } + + // Then update all refs to it + for (const ref of allRefsInfo.references) { + if (ref.kind === 'link') { + // Try to preserve style of existing links + let newPath: string; + if (ref.link.source.text.startsWith('/')) { + const root = resolveDocumentLink('/', ref.link.source.resource); + newPath = '/' + path.relative(root.toString(true), rawNewFilePath.toString(true)); + } else { + const rootDir = URI.Utils.dirname(ref.link.source.resource); + if (rootDir.scheme === rawNewFilePath.scheme && rootDir.scheme !== 'untitled') { + newPath = path.relative(rootDir.toString(true), rawNewFilePath.toString(true)); + if (newName.startsWith('./') && !newPath.startsWith('../') || newName.startsWith('.\\') && !newPath.startsWith('..\\')) { + newPath = './' + newPath; + } + } else { + newPath = newName; + } + } + edit.replace(ref.link.source.resource, this.getFilePathRange(ref), encodeURI(newPath.replace(/\\/g, '/'))); + } + } + + return { edit, fileRenames }; + } + + private renameFragment(allRefsInfo: MdReferencesResponse, newName: string): MdWorkspaceEdit { + const slug = this.slugifier.fromHeading(newName).value; + + const edit = new vscode.WorkspaceEdit(); + for (const ref of allRefsInfo.references) { + switch (ref.kind) { + case 'header': + edit.replace(ref.location.uri, ref.headerTextLocation.range, newName); + break; + + case 'link': + edit.replace(ref.link.source.resource, ref.link.source.fragmentRange ?? ref.location.range, !ref.link.source.fragmentRange || ref.link.href.kind === 'external' ? newName : slug); + break; + } + } + return { edit }; + } + + private renameExternalLink(allRefsInfo: MdReferencesResponse, newName: string): MdWorkspaceEdit { + const edit = new vscode.WorkspaceEdit(); + for (const ref of allRefsInfo.references) { + if (ref.kind === 'link') { + edit.replace(ref.link.source.resource, ref.location.range, newName); + } + } + return { edit }; + } + + private renameReferenceLinks(allRefsInfo: MdReferencesResponse, newName: string): MdWorkspaceEdit { + const edit = new vscode.WorkspaceEdit(); + for (const ref of allRefsInfo.references) { + if (ref.kind === 'link') { + if (ref.link.kind === 'definition') { + edit.replace(ref.link.source.resource, ref.link.ref.range, newName); + } else { + edit.replace(ref.link.source.resource, ref.link.source.fragmentRange ?? ref.location.range, newName); + } + } + } + return { edit }; + } + + private async getAllReferences(document: SkinnyTextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + const version = document.version; + + if (this.cachedRefs + && this.cachedRefs.resource.fsPath === document.uri.fsPath + && this.cachedRefs.version === document.version + && this.cachedRefs.position.isEqual(position) + ) { + return this.cachedRefs; + } + + const references = await this.referencesProvider.getAllReferencesAtPosition(document, position, token); + const triggerRef = references.find(ref => ref.isTriggerLocation); + if (!triggerRef) { + return undefined; + } + + this.cachedRefs = { + resource: document.uri, + version, + position, + references, + triggerRef + }; + return this.cachedRefs; + } +} + diff --git a/extensions/markdown-language-features/src/languageFeatures/smartSelect.ts b/extensions/markdown-language-features/src/languageFeatures/smartSelect.ts new file mode 100644 index 0000000000..275677f769 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/smartSelect.ts @@ -0,0 +1,251 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import Token = require('markdown-it/lib/token'); +import * as vscode from 'vscode'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContents, TocEntry } from '../tableOfContents'; +import { SkinnyTextDocument } from '../workspaceContents'; + +interface MarkdownItTokenWithMap extends Token { + map: [number, number]; +} + +export class MdSmartSelect implements vscode.SelectionRangeProvider { + + constructor( + private readonly engine: MarkdownEngine + ) { } + + public async provideSelectionRanges(document: SkinnyTextDocument, positions: vscode.Position[], _token: vscode.CancellationToken): Promise { + const promises = await Promise.all(positions.map((position) => { + return this.provideSelectionRange(document, position, _token); + })); + return promises.filter(item => item !== undefined) as vscode.SelectionRange[]; + } + + private async provideSelectionRange(document: SkinnyTextDocument, position: vscode.Position, _token: vscode.CancellationToken): Promise { + const headerRange = await this.getHeaderSelectionRange(document, position); + const blockRange = await this.getBlockSelectionRange(document, position, headerRange); + const inlineRange = await this.getInlineSelectionRange(document, position, blockRange); + return inlineRange || blockRange || headerRange; + } + private async getInlineSelectionRange(document: SkinnyTextDocument, position: vscode.Position, blockRange?: vscode.SelectionRange): Promise { + return createInlineRange(document, position, blockRange); + } + + private async getBlockSelectionRange(document: SkinnyTextDocument, position: vscode.Position, headerRange?: vscode.SelectionRange): Promise { + + const tokens = await this.engine.parse(document); + + const blockTokens = getBlockTokensForPosition(tokens, position, headerRange); + + if (blockTokens.length === 0) { + return undefined; + } + + let currentRange: vscode.SelectionRange | undefined = headerRange ? headerRange : createBlockRange(blockTokens.shift()!, document, position.line); + + for (let i = 0; i < blockTokens.length; i++) { + currentRange = createBlockRange(blockTokens[i], document, position.line, currentRange); + } + return currentRange; + } + + private async getHeaderSelectionRange(document: SkinnyTextDocument, position: vscode.Position): Promise { + const toc = await TableOfContents.create(this.engine, document); + + const headerInfo = getHeadersForPosition(toc.entries, position); + + const headers = headerInfo.headers; + + let currentRange: vscode.SelectionRange | undefined; + + for (let i = 0; i < headers.length; i++) { + currentRange = createHeaderRange(headers[i], i === headers.length - 1, headerInfo.headerOnThisLine, currentRange, getFirstChildHeader(document, headers[i], toc.entries)); + } + return currentRange; + } +} + +function getHeadersForPosition(toc: readonly TocEntry[], position: vscode.Position): { headers: TocEntry[]; headerOnThisLine: boolean } { + const enclosingHeaders = toc.filter(header => header.sectionLocation.range.start.line <= position.line && header.sectionLocation.range.end.line >= position.line); + const sortedHeaders = enclosingHeaders.sort((header1, header2) => (header1.line - position.line) - (header2.line - position.line)); + const onThisLine = toc.find(header => header.line === position.line) !== undefined; + return { + headers: sortedHeaders, + headerOnThisLine: onThisLine + }; +} + +function createHeaderRange(header: TocEntry, isClosestHeaderToPosition: boolean, onHeaderLine: boolean, parent?: vscode.SelectionRange, startOfChildRange?: vscode.Position): vscode.SelectionRange | undefined { + const range = header.sectionLocation.range; + const contentRange = new vscode.Range(range.start.translate(1), range.end); + if (onHeaderLine && isClosestHeaderToPosition && startOfChildRange) { + // selection was made on this header line, so select header and its content until the start of its first child + // then all of its content + return new vscode.SelectionRange(range.with(undefined, startOfChildRange), new vscode.SelectionRange(range, parent)); + } else if (onHeaderLine && isClosestHeaderToPosition) { + // selection was made on this header line and no children so expand to all of its content + return new vscode.SelectionRange(range, parent); + } else if (isClosestHeaderToPosition && startOfChildRange) { + // selection was made within content and has child so select content + // of this header then all content then header + return new vscode.SelectionRange(contentRange.with(undefined, startOfChildRange), new vscode.SelectionRange(contentRange, (new vscode.SelectionRange(range, parent)))); + } else { + // not on this header line so select content then header + return new vscode.SelectionRange(contentRange, new vscode.SelectionRange(range, parent)); + } +} + +function getBlockTokensForPosition(tokens: Token[], position: vscode.Position, parent?: vscode.SelectionRange): MarkdownItTokenWithMap[] { + const enclosingTokens = tokens.filter((token): token is MarkdownItTokenWithMap => !!token.map && (token.map[0] <= position.line && token.map[1] > position.line) && (!parent || (token.map[0] >= parent.range.start.line && token.map[1] <= parent.range.end.line + 1)) && isBlockElement(token)); + if (enclosingTokens.length === 0) { + return []; + } + const sortedTokens = enclosingTokens.sort((token1, token2) => (token2.map[1] - token2.map[0]) - (token1.map[1] - token1.map[0])); + return sortedTokens; +} + +function createBlockRange(block: MarkdownItTokenWithMap, document: SkinnyTextDocument, cursorLine: number, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { + if (block.type === 'fence') { + return createFencedRange(block, cursorLine, document, parent); + } else { + let startLine = document.lineAt(block.map[0]).isEmptyOrWhitespace ? block.map[0] + 1 : block.map[0]; + let endLine = startLine === block.map[1] ? block.map[1] : block.map[1] - 1; + if (block.type === 'paragraph_open' && block.map[1] - block.map[0] === 2) { + startLine = endLine = cursorLine; + } else if (isList(block) && document.lineAt(endLine).isEmptyOrWhitespace) { + endLine = endLine - 1; + } + const range = new vscode.Range(startLine, 0, endLine, document.lineAt(endLine).text?.length ?? 0); + if (parent?.range.contains(range) && !parent.range.isEqual(range)) { + return new vscode.SelectionRange(range, parent); + } else if (parent?.range.isEqual(range)) { + return parent; + } else { + return new vscode.SelectionRange(range); + } + } +} + +function createInlineRange(document: SkinnyTextDocument, cursorPosition: vscode.Position, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { + const lineText = document.lineAt(cursorPosition.line).text; + const boldSelection = createBoldRange(lineText, cursorPosition.character, cursorPosition.line, parent); + const italicSelection = createOtherInlineRange(lineText, cursorPosition.character, cursorPosition.line, true, parent); + let comboSelection: vscode.SelectionRange | undefined; + if (boldSelection && italicSelection && !boldSelection.range.isEqual(italicSelection.range)) { + if (boldSelection.range.contains(italicSelection.range)) { + comboSelection = createOtherInlineRange(lineText, cursorPosition.character, cursorPosition.line, true, boldSelection); + } else if (italicSelection.range.contains(boldSelection.range)) { + comboSelection = createBoldRange(lineText, cursorPosition.character, cursorPosition.line, italicSelection); + } + } + const linkSelection = createLinkRange(lineText, cursorPosition.character, cursorPosition.line, comboSelection || boldSelection || italicSelection || parent); + const inlineCodeBlockSelection = createOtherInlineRange(lineText, cursorPosition.character, cursorPosition.line, false, linkSelection || parent); + return inlineCodeBlockSelection || linkSelection || comboSelection || boldSelection || italicSelection; +} + +function createFencedRange(token: MarkdownItTokenWithMap, cursorLine: number, document: SkinnyTextDocument, parent?: vscode.SelectionRange): vscode.SelectionRange { + const startLine = token.map[0]; + const endLine = token.map[1] - 1; + const onFenceLine = cursorLine === startLine || cursorLine === endLine; + const fenceRange = new vscode.Range(startLine, 0, endLine, document.lineAt(endLine).text.length); + const contentRange = endLine - startLine > 2 && !onFenceLine ? new vscode.Range(startLine + 1, 0, endLine - 1, document.lineAt(endLine - 1).text.length) : undefined; + if (contentRange) { + return new vscode.SelectionRange(contentRange, new vscode.SelectionRange(fenceRange, parent)); + } else { + if (parent?.range.isEqual(fenceRange)) { + return parent; + } else { + return new vscode.SelectionRange(fenceRange, parent); + } + } +} + +function createBoldRange(lineText: string, cursorChar: number, cursorLine: number, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { + const regex = /\*\*([^*]+\*?[^*]+\*?[^*]+)\*\*/gim; + const matches = [...lineText.matchAll(regex)].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length >= cursorChar); + if (matches.length) { + // should only be one match, so select first and index 0 contains the entire match + const bold = matches[0][0]; + const startIndex = lineText.indexOf(bold); + const cursorOnStars = cursorChar === startIndex || cursorChar === startIndex + 1 || cursorChar === startIndex + bold.length || cursorChar === startIndex + bold.length - 1; + const contentAndStars = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex, cursorLine, startIndex + bold.length), parent); + const content = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex + 2, cursorLine, startIndex + bold.length - 2), contentAndStars); + return cursorOnStars ? contentAndStars : content; + } + return undefined; +} + +function createOtherInlineRange(lineText: string, cursorChar: number, cursorLine: number, isItalic: boolean, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { + const italicRegexes = [/(?:[^*]+)(\*([^*]+)(?:\*\*[^*]*\*\*)*([^*]+)\*)(?:[^*]+)/g, /^(?:[^*]*)(\*([^*]+)(?:\*\*[^*]*\*\*)*([^*]+)\*)(?:[^*]*)$/g]; + let matches = []; + if (isItalic) { + matches = [...lineText.matchAll(italicRegexes[0])].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length >= cursorChar); + if (!matches.length) { + matches = [...lineText.matchAll(italicRegexes[1])].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length >= cursorChar); + } + } else { + matches = [...lineText.matchAll(/\`[^\`]*\`/g)].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length >= cursorChar); + } + if (matches.length) { + // should only be one match, so select first and select group 1 for italics because that contains just the italic section + // doesn't include the leading and trailing characters which are guaranteed to not be * so as not to be confused with bold + const match = isItalic ? matches[0][1] : matches[0][0]; + const startIndex = lineText.indexOf(match); + const cursorOnType = cursorChar === startIndex || cursorChar === startIndex + match.length; + const contentAndType = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex, cursorLine, startIndex + match.length), parent); + const content = new vscode.SelectionRange(new vscode.Range(cursorLine, startIndex + 1, cursorLine, startIndex + match.length - 1), contentAndType); + return cursorOnType ? contentAndType : content; + } + return undefined; +} + +function createLinkRange(lineText: string, cursorChar: number, cursorLine: number, parent?: vscode.SelectionRange): vscode.SelectionRange | undefined { + const regex = /(\[[^\(\)]*\])(\([^\[\]]*\))/g; + const matches = [...lineText.matchAll(regex)].filter(match => lineText.indexOf(match[0]) <= cursorChar && lineText.indexOf(match[0]) + match[0].length > cursorChar); + + if (matches.length) { + // should only be one match, so select first and index 0 contains the entire match, so match = [text](url) + const link = matches[0][0]; + const linkRange = new vscode.SelectionRange(new vscode.Range(cursorLine, lineText.indexOf(link), cursorLine, lineText.indexOf(link) + link.length), parent); + + const linkText = matches[0][1]; + const url = matches[0][2]; + + // determine if cursor is within [text] or (url) in order to know which should be selected + const nearestType = cursorChar >= lineText.indexOf(linkText) && cursorChar < lineText.indexOf(linkText) + linkText.length ? linkText : url; + + const indexOfType = lineText.indexOf(nearestType); + // determine if cursor is on a bracket or paren and if so, return the [content] or (content), skipping over the content range + const cursorOnType = cursorChar === indexOfType || cursorChar === indexOfType + nearestType.length; + + const contentAndNearestType = new vscode.SelectionRange(new vscode.Range(cursorLine, indexOfType, cursorLine, indexOfType + nearestType.length), linkRange); + const content = new vscode.SelectionRange(new vscode.Range(cursorLine, indexOfType + 1, cursorLine, indexOfType + nearestType.length - 1), contentAndNearestType); + return cursorOnType ? contentAndNearestType : content; + } + return undefined; +} + +function isList(token: Token): boolean { + return token.type ? ['ordered_list_open', 'list_item_open', 'bullet_list_open'].includes(token.type) : false; +} + +function isBlockElement(token: Token): boolean { + return !['list_item_close', 'paragraph_close', 'bullet_list_close', 'inline', 'heading_close', 'heading_open'].includes(token.type); +} + +function getFirstChildHeader(document: SkinnyTextDocument, header?: TocEntry, toc?: readonly TocEntry[]): vscode.Position | undefined { + let childRange: vscode.Position | undefined; + if (header && toc) { + let children = toc.filter(t => header.sectionLocation.range.contains(t.sectionLocation.range) && t.sectionLocation.range.start.line > header.sectionLocation.range.start.line).sort((t1, t2) => t1.line - t2.line); + if (children.length > 0) { + childRange = children[0].sectionLocation.range.start; + const lineText = document.lineAt(childRange.line - 1).text; + return childRange ? childRange.translate(-1, lineText.length) : undefined; + } + } + return undefined; +} diff --git a/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts b/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts new file mode 100644 index 0000000000..63ac22ee40 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/workspaceCache.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { Disposable } from '../util/dispose'; +import { Lazy, lazy } from '../util/lazy'; +import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; + +/** + * Cache of information for markdown files in the workspace. + */ +export class MdWorkspaceCache extends Disposable { + + private readonly _cache = new Map>>(); + private _hasPopulatedCache = false; + + public constructor( + private readonly workspaceContents: MdWorkspaceContents, + private readonly getValue: (document: SkinnyTextDocument) => Promise, + ) { + super(); + } + + public async getAll(): Promise { + if (!this._hasPopulatedCache) { + await this.populateCache(); + this._hasPopulatedCache = true; + + this.workspaceContents.onDidChangeMarkdownDocument(this.onDidChangeDocument, this, this._disposables); + this.workspaceContents.onDidCreateMarkdownDocument(this.onDidChangeDocument, this, this._disposables); + this.workspaceContents.onDidDeleteMarkdownDocument(this.onDidDeleteDocument, this, this._disposables); + } + + return Promise.all(Array.from(this._cache.values(), x => x.value)); + } + + private async populateCache(): Promise { + const markdownDocumentUris = await this.workspaceContents.getAllMarkdownDocuments(); + for (const document of markdownDocumentUris) { + this.update(document); + } + } + + private key(resource: vscode.Uri): string { + return resource.toString(); + } + + private update(document: SkinnyTextDocument): void { + this._cache.set(this.key(document.uri), lazy(() => this.getValue(document))); + } + + private onDidChangeDocument(document: SkinnyTextDocument) { + this.update(document); + } + + private onDidDeleteDocument(resource: vscode.Uri) { + this._cache.delete(this.key(resource)); + } +} diff --git a/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts b/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts new file mode 100644 index 0000000000..3bd582dfc7 --- /dev/null +++ b/extensions/markdown-language-features/src/languageFeatures/workspaceSymbolProvider.ts @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import { Disposable } from '../util/dispose'; +import { MdWorkspaceContents } from '../workspaceContents'; +import { MdDocumentSymbolProvider } from './documentSymbolProvider'; +import { MdWorkspaceCache } from './workspaceCache'; + +export class MdWorkspaceSymbolProvider extends Disposable implements vscode.WorkspaceSymbolProvider { + + private readonly _cache: MdWorkspaceCache; + + public constructor( + symbolProvider: MdDocumentSymbolProvider, + workspaceContents: MdWorkspaceContents, + ) { + super(); + + this._cache = this._register(new MdWorkspaceCache(workspaceContents, doc => symbolProvider.provideDocumentSymbolInformation(doc))); + } + + public async provideWorkspaceSymbols(query: string): Promise { + const allSymbols = (await this._cache.getAll()).flat(); + return allSymbols.filter(symbolInformation => symbolInformation.name.toLowerCase().indexOf(query.toLowerCase()) !== -1); + } +} diff --git a/extensions/markdown-language-features/src/logging.ts b/extensions/markdown-language-features/src/logger.ts similarity index 59% rename from extensions/markdown-language-features/src/logging.ts rename to extensions/markdown-language-features/src/logger.ts index 4273b4bba6..4f1bddb09f 100644 --- a/extensions/markdown-language-features/src/logging.ts +++ b/extensions/markdown-language-features/src/logger.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { Disposable } from './util/dispose'; import { lazy } from './util/lazy'; enum Trace { @@ -26,61 +25,57 @@ namespace Trace { } } -export interface ILogger { - verbose(title: string, message: string, data?: any): void; + +function isString(value: any): value is string { + return Object.prototype.toString.call(value) === '[object String]'; } -export class VsCodeOutputLogger extends Disposable implements ILogger { +export class Logger { private trace?: Trace; - private readonly outputChannel = lazy(() => this._register(vscode.window.createOutputChannel('Markdown'))); + private readonly outputChannel = lazy(() => vscode.window.createOutputChannel('Markdown')); constructor() { - super(); - - this._register(vscode.workspace.onDidChangeConfiguration(() => { - this.updateConfiguration(); - })); - this.updateConfiguration(); } - public verbose(title: string, message: string, data?: any): void { + public log(message: string, data?: any): void { if (this.trace === Trace.Verbose) { - this.appendLine(`[Verbose ${this.now()}] ${title}: ${message}`); + this.appendLine(`[Log - ${this.now()}] ${message}`); if (data) { - this.appendLine(VsCodeOutputLogger.data2String(data)); + this.appendLine(Logger.data2String(data)); } } } + private now(): string { const now = new Date(); return String(now.getUTCHours()).padStart(2, '0') + ':' + String(now.getMinutes()).padStart(2, '0') - + ':' + String(now.getUTCSeconds()).padStart(2, '0') + '.' + String(now.getMilliseconds()).padStart(3, '0'); + + ':' + String(now.getUTCSeconds()).padStart(2, '0') + '.' + now.getMilliseconds(); } - private updateConfiguration(): void { + public updateConfiguration() { this.trace = this.readTrace(); } - private appendLine(value: string): void { - this.outputChannel.value.appendLine(value); + private appendLine(value: string) { + return this.outputChannel.value.appendLine(value); } private readTrace(): Trace { - return Trace.fromString(vscode.workspace.getConfiguration().get('markdown.trace.extension', 'off')); + return Trace.fromString(vscode.workspace.getConfiguration().get('markdown.trace', 'off')); } private static data2String(data: any): string { if (data instanceof Error) { - if (typeof data.stack === 'string') { + if (isString(data.stack)) { return data.stack; } - return data.message; + return (data as Error).message; } - if (typeof data === 'string') { + if (isString(data)) { return data; } return JSON.stringify(data, undefined, 2); diff --git a/extensions/markdown-language-features/src/markdownEngine.ts b/extensions/markdown-language-features/src/markdownEngine.ts index 0a521d5046..3e3f5d660a 100644 --- a/extensions/markdown-language-features/src/markdownEngine.ts +++ b/extensions/markdown-language-features/src/markdownEngine.ts @@ -3,19 +3,15 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import type MarkdownIt = require('markdown-it'); -import type Token = require('markdown-it/lib/token'); +import MarkdownIt = require('markdown-it'); +import Token = require('markdown-it/lib/token'); import * as vscode from 'vscode'; -import { ILogger } from './logging'; import { MarkdownContributionProvider } from './markdownExtensions'; import { Slugifier } from './slugify'; -import { ITextDocument } from './types/textDocument'; -import { Disposable } from './util/dispose'; import { stringHash } from './util/hash'; import { WebviewResourceProvider } from './util/resources'; import { isOfScheme, Schemes } from './util/schemes'; -import { MdDocumentInfoCache } from './util/workspaceCache'; -import { IMdWorkspace } from './workspace'; +import { SkinnyTextDocument } from './workspaceContents'; const UNICODE_NEWLINE_REGEX = /\u2028|\u2029/g; @@ -57,7 +53,7 @@ class TokenCache { }; private tokens?: Token[]; - public tryGetCached(document: ITextDocument, config: MarkdownItConfig): Token[] | undefined { + public tryGetCached(document: SkinnyTextDocument, config: MarkdownItConfig): Token[] | undefined { if (this.cachedDocument && this.cachedDocument.uri.toString() === document.uri.toString() && this.cachedDocument.version === document.version @@ -69,7 +65,7 @@ class TokenCache { return undefined; } - public update(document: ITextDocument, config: MarkdownItConfig, tokens: Token[]) { + public update(document: SkinnyTextDocument, config: MarkdownItConfig, tokens: Token[]) { this.cachedDocument = { uri: document.uri, version: document.version, @@ -95,28 +91,17 @@ interface RenderEnv { resourceProvider: WebviewResourceProvider | undefined; } -export interface IMdParser { - readonly slugifier: Slugifier; - - tokenize(document: ITextDocument): Promise; -} - -export class MarkdownItEngine implements IMdParser { +export class MarkdownEngine { private md?: Promise; private _slugCount = new Map(); private _tokenCache = new TokenCache(); - public readonly slugifier: Slugifier; - public constructor( private readonly contributionProvider: MarkdownContributionProvider, - slugifier: Slugifier, - private readonly logger: ILogger, + private readonly slugifier: Slugifier, ) { - this.slugifier = slugifier; - contributionProvider.onContributionsChanged(() => { // Markdown plugin contributions may have changed this.md = undefined; @@ -174,7 +159,7 @@ export class MarkdownItEngine implements IMdParser { } private tokenizeDocument( - document: ITextDocument, + document: SkinnyTextDocument, config: MarkdownItConfig, engine: MarkdownIt ): Token[] { @@ -184,7 +169,6 @@ export class MarkdownItEngine implements IMdParser { return cached; } - this.logger.verbose('MarkdownItEngine', `tokenizeDocument - ${document.uri}`); const tokens = this.tokenizeString(document.getText(), engine); this._tokenCache.update(document, config, tokens); return tokens; @@ -200,7 +184,7 @@ export class MarkdownItEngine implements IMdParser { this._slugCount = new Map(); } - public async render(input: ITextDocument | string, resourceProvider?: WebviewResourceProvider): Promise { + public async render(input: SkinnyTextDocument | string, resourceProvider?: WebviewResourceProvider): Promise { const config = this.getConfig(typeof input === 'string' ? undefined : input.uri); const engine = await this.getEngine(config); @@ -225,7 +209,7 @@ export class MarkdownItEngine implements IMdParser { }; } - public async tokenize(document: ITextDocument): Promise { + public async parse(document: SkinnyTextDocument): Promise { const config = this.getConfig(document.uri); const engine = await this.getEngine(config); return this.tokenizeDocument(document, config, engine); @@ -439,27 +423,3 @@ function normalizeHighlightLang(lang: string | undefined) { return lang; } } - -export class MdParsingProvider extends Disposable implements IMdParser { - - private readonly _cache: MdDocumentInfoCache; - - public readonly slugifier: Slugifier; - - constructor( - engine: MarkdownItEngine, - workspace: IMdWorkspace, - ) { - super(); - - this.slugifier = engine.slugifier; - - this._cache = this._register(new MdDocumentInfoCache(workspace, doc => { - return engine.tokenize(doc); - })); - } - - public tokenize(document: ITextDocument): Promise { - return this._cache.getForDocument(document); - } -} diff --git a/extensions/markdown-language-features/src/preview/preview.ts b/extensions/markdown-language-features/src/preview/preview.ts index ff7c4138bd..665cb3d73b 100644 --- a/extensions/markdown-language-features/src/preview/preview.ts +++ b/extensions/markdown-language-features/src/preview/preview.ts @@ -6,17 +6,16 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import * as uri from 'vscode-uri'; -import { ILogger } from '../logging'; +import { Logger } from '../logger'; +import { MarkdownEngine } from '../markdownEngine'; import { MarkdownContributionProvider } from '../markdownExtensions'; -import { MdTableOfContentsProvider } from '../tableOfContents'; import { Disposable } from '../util/dispose'; import { isMarkdownFile } from '../util/file'; import { openDocumentLink, resolveDocumentLink, resolveUriToMarkdownFile } from '../util/openDocumentLink'; import { WebviewResourceProvider } from '../util/resources'; import { urlToUri } from '../util/url'; -import { IMdWorkspace } from '../workspace'; -import { MdDocumentRenderer } from './documentRenderer'; import { MarkdownPreviewConfigurationManager } from './previewConfig'; +import { MarkdownContentProvider } from './previewContentProvider'; import { scrollEditorToLine, StartingScrollFragment, StartingScrollLine, StartingScrollLocation } from './scrolling'; import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from './topmostLineMonitor'; @@ -110,19 +109,16 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { private readonly _onScrollEmitter = this._register(new vscode.EventEmitter()); public readonly onScroll = this._onScrollEmitter.event; - private readonly _disposeCts = this._register(new vscode.CancellationTokenSource()); - constructor( webview: vscode.WebviewPanel, resource: vscode.Uri, startingScroll: StartingScrollLocation | undefined, private readonly delegate: MarkdownPreviewDelegate, - private readonly _contentProvider: MdDocumentRenderer, + private readonly engine: MarkdownEngine, + private readonly _contentProvider: MarkdownContentProvider, private readonly _previewConfigurations: MarkdownPreviewConfigurationManager, - private readonly _workspace: IMdWorkspace, - private readonly _logger: ILogger, + private readonly _logger: Logger, private readonly _contributionProvider: MarkdownContributionProvider, - private readonly _tocProvider: MdTableOfContentsProvider, ) { super(); @@ -206,8 +202,6 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { } override dispose() { - this._disposeCts.cancel(); - super.dispose(); this._disposed = true; @@ -271,7 +265,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { return; } - this._logger.verbose('MarkdownPreview', 'updateForView', { markdownFile: this._resource }); + this._logger.log('updateForView', { markdownFile: this._resource }); this.line = topLine; this.postMessage({ type: 'updateView', @@ -292,9 +286,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { try { document = await vscode.workspace.openTextDocument(this._resource); } catch { - if (!this._disposed) { - await this.showFileNotFoundError(); - } + await this.showFileNotFoundError(); return; } @@ -314,8 +306,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { this.currentVersion = pendingVersion; const content = await (shouldReloadPage - ? this._contentProvider.renderDocument(document, this, this._previewConfigurations, this.line, this.state, this._disposeCts.token) - : this._contentProvider.renderBody(document, this)); + ? this._contentProvider.provideTextDocumentContent(document, this, this._previewConfigurations, this.line, this.state) + : this._contentProvider.markdownBody(document, this)); // Another call to `doUpdate` may have happened. // Make sure we are still updating for the correct document @@ -372,7 +364,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { } private async showFileNotFoundError() { - this._webviewPanel.webview.html = this._contentProvider.renderFileNotFoundDocument(this._resource); + this._webviewPanel.webview.html = this._contentProvider.provideFileNotFoundContent(this._resource); } private updateWebviewContent(html: string, reloadPage: boolean): void { @@ -451,14 +443,14 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { const config = vscode.workspace.getConfiguration('markdown', this.resource); const openLinks = config.get('preview.openMarkdownLinks', 'inPreview'); if (openLinks === 'inPreview') { - const linkedDoc = await resolveUriToMarkdownFile(this._workspace, targetResource); + const linkedDoc = await resolveUriToMarkdownFile(targetResource); if (linkedDoc) { this.delegate.openPreviewLinkToMarkdownFile(linkedDoc.uri, targetResource.fragment); return; } } - return openDocumentLink(this._tocProvider, targetResource, this.resource); + return openDocumentLink(this.engine, targetResource, this.resource); } //#region WebviewResourceProvider @@ -474,7 +466,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { //#endregion } -export interface IManagedMarkdownPreview { +export interface ManagedMarkdownPreview { readonly resource: vscode.Uri; readonly resourceColumn: vscode.ViewColumn; @@ -494,23 +486,22 @@ export interface IManagedMarkdownPreview { ): boolean; } -export class StaticMarkdownPreview extends Disposable implements IManagedMarkdownPreview { +export class StaticMarkdownPreview extends Disposable implements ManagedMarkdownPreview { public static readonly customEditorViewType = 'vscode.markdown.preview.editor'; public static revive( resource: vscode.Uri, webview: vscode.WebviewPanel, - contentProvider: MdDocumentRenderer, + contentProvider: MarkdownContentProvider, previewConfigurations: MarkdownPreviewConfigurationManager, topmostLineMonitor: TopmostLineMonitor, - workspace: IMdWorkspace, - logger: ILogger, + logger: Logger, contributionProvider: MarkdownContributionProvider, - tocProvider: MdTableOfContentsProvider, + engine: MarkdownEngine, scrollLine?: number, ): StaticMarkdownPreview { - return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, topmostLineMonitor, workspace, logger, contributionProvider, tocProvider, scrollLine); + return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, topmostLineMonitor, logger, contributionProvider, engine, scrollLine); } private readonly preview: MarkdownPreview; @@ -518,13 +509,12 @@ export class StaticMarkdownPreview extends Disposable implements IManagedMarkdow private constructor( private readonly _webviewPanel: vscode.WebviewPanel, resource: vscode.Uri, - contentProvider: MdDocumentRenderer, + contentProvider: MarkdownContentProvider, private readonly _previewConfigurations: MarkdownPreviewConfigurationManager, topmostLineMonitor: TopmostLineMonitor, - workspace: IMdWorkspace, - logger: ILogger, + logger: Logger, contributionProvider: MarkdownContributionProvider, - tocProvider: MdTableOfContentsProvider, + engine: MarkdownEngine, scrollLine?: number, ) { super(); @@ -536,7 +526,7 @@ export class StaticMarkdownPreview extends Disposable implements IManagedMarkdow fragment }), StaticMarkdownPreview.customEditorViewType, this._webviewPanel.viewColumn); } - }, contentProvider, _previewConfigurations, workspace, logger, contributionProvider, tocProvider)); + }, engine, contentProvider, _previewConfigurations, logger, contributionProvider)); this._register(this._webviewPanel.onDidDispose(() => { this.dispose(); @@ -602,7 +592,7 @@ interface DynamicPreviewInput { readonly line?: number; } -export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdownPreview { +export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdownPreview { public static readonly viewType = 'markdown.preview'; @@ -615,30 +605,28 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo public static revive( input: DynamicPreviewInput, webview: vscode.WebviewPanel, - contentProvider: MdDocumentRenderer, + contentProvider: MarkdownContentProvider, previewConfigurations: MarkdownPreviewConfigurationManager, - workspace: IMdWorkspace, - logger: ILogger, + logger: Logger, topmostLineMonitor: TopmostLineMonitor, contributionProvider: MarkdownContributionProvider, - tocProvider: MdTableOfContentsProvider, + engine: MarkdownEngine, ): DynamicMarkdownPreview { webview.iconPath = contentProvider.iconPath; return new DynamicMarkdownPreview(webview, input, - contentProvider, previewConfigurations, workspace, logger, topmostLineMonitor, contributionProvider, tocProvider); + contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine); } public static create( input: DynamicPreviewInput, previewColumn: vscode.ViewColumn, - contentProvider: MdDocumentRenderer, + contentProvider: MarkdownContentProvider, previewConfigurations: MarkdownPreviewConfigurationManager, - workspace: IMdWorkspace, - logger: ILogger, + logger: Logger, topmostLineMonitor: TopmostLineMonitor, contributionProvider: MarkdownContributionProvider, - tocProvider: MdTableOfContentsProvider, + engine: MarkdownEngine, ): DynamicMarkdownPreview { const webview = vscode.window.createWebviewPanel( DynamicMarkdownPreview.viewType, @@ -648,19 +636,18 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo webview.iconPath = contentProvider.iconPath; return new DynamicMarkdownPreview(webview, input, - contentProvider, previewConfigurations, workspace, logger, topmostLineMonitor, contributionProvider, tocProvider); + contentProvider, previewConfigurations, logger, topmostLineMonitor, contributionProvider, engine); } private constructor( webview: vscode.WebviewPanel, input: DynamicPreviewInput, - private readonly _contentProvider: MdDocumentRenderer, + private readonly _contentProvider: MarkdownContentProvider, private readonly _previewConfigurations: MarkdownPreviewConfigurationManager, - private readonly _workspace: IMdWorkspace, - private readonly _logger: ILogger, + private readonly _logger: Logger, private readonly _topmostLineMonitor: TopmostLineMonitor, private readonly _contributionProvider: MarkdownContributionProvider, - private readonly _tocProvider: MdTableOfContentsProvider, + private readonly _engine: MarkdownEngine, ) { super(); @@ -812,11 +799,10 @@ export class DynamicMarkdownPreview extends Disposable implements IManagedMarkdo this.update(link, fragment ? new StartingScrollFragment(fragment) : undefined); } }, + this._engine, this._contentProvider, this._previewConfigurations, - this._workspace, this._logger, - this._contributionProvider, - this._tocProvider); + this._contributionProvider); } } diff --git a/extensions/markdown-language-features/src/preview/documentRenderer.ts b/extensions/markdown-language-features/src/preview/previewContentProvider.ts similarity index 91% rename from extensions/markdown-language-features/src/preview/documentRenderer.ts rename to extensions/markdown-language-features/src/preview/previewContentProvider.ts index 3c8ca0afdf..74621d404a 100644 --- a/extensions/markdown-language-features/src/preview/documentRenderer.ts +++ b/extensions/markdown-language-features/src/preview/previewContentProvider.ts @@ -6,10 +6,9 @@ import * as vscode from 'vscode'; import * as nls from 'vscode-nls'; import * as uri from 'vscode-uri'; -import { ILogger } from '../logging'; -import { MarkdownItEngine } from '../markdownEngine'; +import { Logger } from '../logger'; +import { MarkdownEngine } from '../markdownEngine'; import { MarkdownContributionProvider } from '../markdownExtensions'; -import { escapeAttribute, getNonce } from '../util/dom'; import { WebviewResourceProvider } from '../util/resources'; import { MarkdownPreviewConfiguration, MarkdownPreviewConfigurationManager } from './previewConfig'; import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from './security'; @@ -36,19 +35,23 @@ const previewStrings = { 'Content Disabled Security Warning') }; +function escapeAttribute(value: string | vscode.Uri): string { + return value.toString().replace(/"/g, '"'); +} + export interface MarkdownContentProviderOutput { html: string; containingImages: { src: string }[]; } -export class MdDocumentRenderer { +export class MarkdownContentProvider { constructor( - private readonly engine: MarkdownItEngine, + private readonly engine: MarkdownEngine, private readonly context: vscode.ExtensionContext, private readonly cspArbiter: ContentSecurityPolicyArbiter, private readonly contributionProvider: MarkdownContributionProvider, - private readonly logger: ILogger + private readonly logger: Logger ) { this.iconPath = { dark: vscode.Uri.joinPath(this.context.extensionUri, 'media', 'preview-dark.svg'), @@ -58,13 +61,12 @@ export class MdDocumentRenderer { public readonly iconPath: { light: vscode.Uri; dark: vscode.Uri }; - public async renderDocument( + public async provideTextDocumentContent( markdownDocument: vscode.TextDocument, resourceProvider: WebviewResourceProvider, previewConfigurations: MarkdownPreviewConfigurationManager, initialLine: number | undefined = undefined, - state: any | undefined, - token: vscode.CancellationToken + state?: any ): Promise { const sourceUri = markdownDocument.uri; const config = previewConfigurations.loadAndCacheConfiguration(sourceUri); @@ -80,17 +82,13 @@ export class MdDocumentRenderer { webviewResourceRoot: resourceProvider.asWebviewUri(markdownDocument.uri).toString(), }; - this.logger.verbose('DocumentRenderer', `provideTextDocumentContent - ${markdownDocument.uri}`, initialData); + this.logger.log('provideTextDocumentContent', initialData); // Content Security Policy const nonce = getNonce(); const csp = this.getCsp(resourceProvider, sourceUri, nonce); - const body = await this.renderBody(markdownDocument, resourceProvider); - if (token.isCancellationRequested) { - return { html: '', containingImages: [] }; - } - + const body = await this.markdownBody(markdownDocument, resourceProvider); const html = ` @@ -115,7 +113,7 @@ export class MdDocumentRenderer { }; } - public async renderBody( + public async markdownBody( markdownDocument: vscode.TextDocument, resourceProvider: WebviewResourceProvider, ): Promise { @@ -127,7 +125,9 @@ export class MdDocumentRenderer { }; } - public renderFileNotFoundDocument(resource: vscode.Uri): string { + public provideFileNotFoundContent( + resource: vscode.Uri, + ): string { const resourcePath = uri.Utils.basename(resource); const body = localize('preview.notFound', '{0} cannot be found', resourcePath); return ` @@ -246,3 +246,12 @@ export class MdDocumentRenderer { } } } + +function getNonce() { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 64; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; +} diff --git a/extensions/markdown-language-features/src/preview/previewManager.ts b/extensions/markdown-language-features/src/preview/previewManager.ts index 89a78d12bb..a30379fc6f 100644 --- a/extensions/markdown-language-features/src/preview/previewManager.ts +++ b/extensions/markdown-language-features/src/preview/previewManager.ts @@ -4,15 +4,14 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { ILogger } from '../logging'; +import { Logger } from '../logger'; +import { MarkdownEngine } from '../markdownEngine'; import { MarkdownContributionProvider } from '../markdownExtensions'; -import { MdTableOfContentsProvider } from '../tableOfContents'; import { Disposable, disposeAll } from '../util/dispose'; import { isMarkdownFile } from '../util/file'; -import { IMdWorkspace } from '../workspace'; -import { MdDocumentRenderer } from './documentRenderer'; -import { DynamicMarkdownPreview, IManagedMarkdownPreview, StaticMarkdownPreview } from './preview'; +import { DynamicMarkdownPreview, ManagedMarkdownPreview, StaticMarkdownPreview } from './preview'; import { MarkdownPreviewConfigurationManager } from './previewConfig'; +import { MarkdownContentProvider } from './previewContentProvider'; import { scrollEditorToLine, StartingScrollFragment } from './scrolling'; import { TopmostLineMonitor } from './topmostLineMonitor'; @@ -22,7 +21,7 @@ export interface DynamicPreviewSettings { readonly locked: boolean; } -class PreviewStore extends Disposable { +class PreviewStore extends Disposable { private readonly _previews = new Set(); @@ -66,14 +65,13 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview private readonly _dynamicPreviews = this._register(new PreviewStore()); private readonly _staticPreviews = this._register(new PreviewStore()); - private _activePreview: IManagedMarkdownPreview | undefined = undefined; + private _activePreview: ManagedMarkdownPreview | undefined = undefined; public constructor( - private readonly _contentProvider: MdDocumentRenderer, - private readonly _workspace: IMdWorkspace, - private readonly _logger: ILogger, + private readonly _contentProvider: MarkdownContentProvider, + private readonly _logger: Logger, private readonly _contributions: MarkdownContributionProvider, - private readonly _tocProvider: MdTableOfContentsProvider, + private readonly _engine: MarkdownEngine, ) { super(); @@ -165,11 +163,10 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview webview, this._contentProvider, this._previewConfigurations, - this._workspace, this._logger, this._topmostLineMonitor, this._contributions, - this._tocProvider); + this._engine); this.registerDynamicPreview(preview); } @@ -185,10 +182,9 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview this._contentProvider, this._previewConfigurations, this._topmostLineMonitor, - this._workspace, this._logger, this._contributions, - this._tocProvider, + this._engine, lineNumber ); this.registerStaticPreview(preview); @@ -210,11 +206,10 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview previewSettings.previewColumn, this._contentProvider, this._previewConfigurations, - this._workspace, this._logger, this._topmostLineMonitor, this._contributions, - this._tocProvider); + this._engine); this.setPreviewActiveContext(true); this._activePreview = preview; @@ -248,7 +243,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview return preview; } - private trackActive(preview: IManagedMarkdownPreview): void { + private trackActive(preview: ManagedMarkdownPreview): void { preview.onDidChangeViewState(({ webviewPanel }) => { this.setPreviewActiveContext(webviewPanel.active); this._activePreview = webviewPanel.active ? preview : undefined; diff --git a/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts b/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts index bc5b0614bf..2a8d50aef6 100644 --- a/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts +++ b/extensions/markdown-language-features/src/preview/topmostLineMonitor.ts @@ -6,7 +6,6 @@ import * as vscode from 'vscode'; import { Disposable } from '../util/dispose'; import { isMarkdownFile } from '../util/file'; -import { ResourceMap } from '../util/resourceMap'; export interface LastScrollLocation { readonly line: number; @@ -15,10 +14,10 @@ export interface LastScrollLocation { export class TopmostLineMonitor extends Disposable { - private readonly pendingUpdates = new ResourceMap(); + private readonly pendingUpdates = new Map(); private readonly throttle = 50; - private previousTextEditorInfo = new ResourceMap(); - private previousStaticEditorInfo = new ResourceMap(); + private previousTextEditorInfo = new Map(); + private previousStaticEditorInfo = new Map(); constructor() { super(); @@ -43,28 +42,28 @@ export class TopmostLineMonitor extends Disposable { public readonly onDidChanged = this._onChanged.event; public setPreviousStaticEditorLine(scrollLocation: LastScrollLocation): void { - this.previousStaticEditorInfo.set(scrollLocation.uri, scrollLocation); + this.previousStaticEditorInfo.set(scrollLocation.uri.toString(), scrollLocation); } public getPreviousStaticEditorLineByUri(resource: vscode.Uri): number | undefined { - const scrollLoc = this.previousStaticEditorInfo.get(resource); - this.previousStaticEditorInfo.delete(resource); + const scrollLoc = this.previousStaticEditorInfo.get(resource.toString()); + this.previousStaticEditorInfo.delete(resource.toString()); return scrollLoc?.line; } public setPreviousTextEditorLine(scrollLocation: LastScrollLocation): void { - this.previousTextEditorInfo.set(scrollLocation.uri, scrollLocation); + this.previousTextEditorInfo.set(scrollLocation.uri.toString(), scrollLocation); } public getPreviousTextEditorLineByUri(resource: vscode.Uri): number | undefined { - const scrollLoc = this.previousTextEditorInfo.get(resource); - this.previousTextEditorInfo.delete(resource); + const scrollLoc = this.previousTextEditorInfo.get(resource.toString()); + this.previousTextEditorInfo.delete(resource.toString()); return scrollLoc?.line; } public getPreviousStaticTextEditorLineByUri(resource: vscode.Uri): number | undefined { - const state = this.previousStaticEditorInfo.get(resource); + const state = this.previousStaticEditorInfo.get(resource.toString()); return state?.line; } @@ -72,20 +71,21 @@ export class TopmostLineMonitor extends Disposable { resource: vscode.Uri, line: number ) { - if (!this.pendingUpdates.has(resource)) { + const key = resource.toString(); + if (!this.pendingUpdates.has(key)) { // schedule update setTimeout(() => { - if (this.pendingUpdates.has(resource)) { + if (this.pendingUpdates.has(key)) { this._onChanged.fire({ resource, - line: this.pendingUpdates.get(resource) as number + line: this.pendingUpdates.get(key) as number }); - this.pendingUpdates.delete(resource); + this.pendingUpdates.delete(key); } }, this.throttle); } - this.pendingUpdates.set(resource, line); + this.pendingUpdates.set(key, line); } } diff --git a/extensions/markdown-language-features/src/protocol.ts b/extensions/markdown-language-features/src/protocol.ts deleted file mode 100644 index 0eec124bd5..0000000000 --- a/extensions/markdown-language-features/src/protocol.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import Token = require('markdown-it/lib/token'); -import { RequestType } from 'vscode-languageclient'; -import type * as lsp from 'vscode-languageserver-types'; -import type * as md from 'vscode-markdown-languageservice'; - -//#region From server -export const parse = new RequestType<{ uri: string }, Token[], any>('markdown/parse'); - -export const fs_readFile = new RequestType<{ uri: string }, number[], any>('markdown/fs/readFile'); -export const fs_readDirectory = new RequestType<{ uri: string }, [string, { isDirectory: boolean }][], any>('markdown/fs/readDirectory'); -export const fs_stat = new RequestType<{ uri: string }, { isDirectory: boolean } | undefined, any>('markdown/fs/stat'); - -export const fs_watcher_create = new RequestType<{ id: number; uri: string; options: md.FileWatcherOptions }, void, any>('markdown/fs/watcher/create'); -export const fs_watcher_delete = new RequestType<{ id: number }, void, any>('markdown/fs/watcher/delete'); - -export const findMarkdownFilesInWorkspace = new RequestType<{}, string[], any>('markdown/findMarkdownFilesInWorkspace'); -//#endregion - -//#region To server -export const getReferencesToFileInWorkspace = new RequestType<{ uri: string }, lsp.Location[], any>('markdown/getReferencesToFileInWorkspace'); - -export const fs_watcher_onChange = new RequestType<{ id: number; uri: string; kind: 'create' | 'change' | 'delete' }, void, any>('markdown/fs/watcher/onChange'); -//#endregion diff --git a/extensions/markdown-language-features/src/slugify.ts b/extensions/markdown-language-features/src/slugify.ts index f157861278..c5faf9a388 100644 --- a/extensions/markdown-language-features/src/slugify.ts +++ b/extensions/markdown-language-features/src/slugify.ts @@ -24,7 +24,7 @@ export const githubSlugifier: Slugifier = new class implements Slugifier { .toLowerCase() .replace(/\s+/g, '-') // Replace whitespace with - // allow-any-unicode-next-line - .replace(/[\]\[\!\/\'\"\#\$\%\&\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`。,、;:?!…—·ˉ¨‘’“”々~‖∶"'`|〃〔〕〈〉《》「」『』.〖〗【】()[]{}]/g, '') // Remove known punctuators + .replace(/[\]\[\!\'\#\$\%\&\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\_\{\|\}\~\`。,、;:?!…—·ˉ¨‘’“”々~‖∶"'`|〃〔〕〈〉《》「」『』.〖〗【】()[]{}]/g, '') // Remove known punctuators .replace(/^\-+/, '') // Remove leading - .replace(/\-+$/, '') // Remove trailing - ); diff --git a/extensions/markdown-language-features/src/tableOfContents.ts b/extensions/markdown-language-features/src/tableOfContents.ts index 12e84b9c3e..3cabcce034 100644 --- a/extensions/markdown-language-features/src/tableOfContents.ts +++ b/extensions/markdown-language-features/src/tableOfContents.ts @@ -4,15 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { ILogger } from './logging'; -import { IMdParser } from './markdownEngine'; -import { githubSlugifier, Slug, Slugifier } from './slugify'; -import { getLine, ITextDocument } from './types/textDocument'; -import { Disposable } from './util/dispose'; +import { MarkdownEngine } from './markdownEngine'; +import { githubSlugifier, Slug } from './slugify'; import { isMarkdownFile } from './util/file'; -import { Schemes } from './util/schemes'; -import { MdDocumentInfoCache } from './util/workspaceCache'; -import { IMdWorkspace } from './workspace'; +import { SkinnyTextDocument } from './workspaceContents'; export interface TocEntry { readonly slug: Slug; @@ -66,39 +61,35 @@ export interface TocEntry { export class TableOfContents { - public static async create(parser: IMdParser, document: ITextDocument,): Promise { - const entries = await this.buildToc(parser, document); - return new TableOfContents(entries, parser.slugifier); + public static async create(engine: MarkdownEngine, document: SkinnyTextDocument,): Promise { + const entries = await this.buildToc(engine, document); + return new TableOfContents(entries); } - public static async createForDocumentOrNotebook(parser: IMdParser, document: ITextDocument): Promise { - if (document.uri.scheme === Schemes.notebookCell) { + public static async createForDocumentOrNotebook(engine: MarkdownEngine, document: SkinnyTextDocument): Promise { + if (document.uri.scheme === 'vscode-notebook-cell') { const notebook = vscode.workspace.notebookDocuments .find(notebook => notebook.getCells().some(cell => cell.document === document)); if (notebook) { - return TableOfContents.createForNotebook(parser, notebook); + const entries: TocEntry[] = []; + + for (const cell of notebook.getCells()) { + if (cell.kind === vscode.NotebookCellKind.Markup && isMarkdownFile(cell.document)) { + entries.push(...(await this.buildToc(engine, cell.document))); + } + } + + return new TableOfContents(entries); } } - return this.create(parser, document); + return this.create(engine, document); } - public static async createForNotebook(parser: IMdParser, notebook: vscode.NotebookDocument): Promise { - const entries: TocEntry[] = []; - - for (const cell of notebook.getCells()) { - if (cell.kind === vscode.NotebookCellKind.Markup && isMarkdownFile(cell.document)) { - entries.push(...(await this.buildToc(parser, cell.document))); - } - } - - return new TableOfContents(entries, parser.slugifier); - } - - private static async buildToc(parser: IMdParser, document: ITextDocument): Promise { + private static async buildToc(engine: MarkdownEngine, document: SkinnyTextDocument): Promise { const toc: TocEntry[] = []; - const tokens = await parser.tokenize(document); + const tokens = await engine.parse(document); const existingSlugEntries = new Map(); @@ -108,26 +99,26 @@ export class TableOfContents { } const lineNumber = heading.map[0]; - const line = getLine(document, lineNumber); + const line = document.lineAt(lineNumber); - let slug = parser.slugifier.fromHeading(line); + let slug = githubSlugifier.fromHeading(line.text); const existingSlugEntry = existingSlugEntries.get(slug.value); if (existingSlugEntry) { ++existingSlugEntry.count; - slug = parser.slugifier.fromHeading(slug.value + '-' + existingSlugEntry.count); + slug = githubSlugifier.fromHeading(slug.value + '-' + existingSlugEntry.count); } else { existingSlugEntries.set(slug.value, { count: 0 }); } const headerLocation = new vscode.Location(document.uri, - new vscode.Range(lineNumber, 0, lineNumber, line.length)); + new vscode.Range(lineNumber, 0, lineNumber, line.text.length)); const headerTextLocation = new vscode.Location(document.uri, - new vscode.Range(lineNumber, line.match(/^#+\s*/)?.[0].length ?? 0, lineNumber, line.length - (line.match(/\s*#*$/)?.[0].length ?? 0))); + new vscode.Range(lineNumber, line.text.match(/^#+\s*/)?.[0].length ?? 0, lineNumber, line.text.length - (line.text.match(/\s*#*$/)?.[0].length ?? 0))); toc.push({ slug, - text: TableOfContents.getHeaderText(line), + text: TableOfContents.getHeaderText(line.text), level: TableOfContents.getHeaderLevel(heading.markup), line: lineNumber, sectionLocation: headerLocation, // Populated in next steps @@ -151,7 +142,7 @@ export class TableOfContents { sectionLocation: new vscode.Location(document.uri, new vscode.Range( entry.sectionLocation.range.start, - new vscode.Position(endLine, getLine(document, endLine).length))) + new vscode.Position(endLine, document.lineAt(endLine).text.length))) }; }); } @@ -170,44 +161,12 @@ export class TableOfContents { return header.replace(/^\s*#+\s*(.*?)(\s+#+)?$/, (_, word) => word.trim()); } - public static readonly empty = new TableOfContents([], githubSlugifier); - private constructor( public readonly entries: readonly TocEntry[], - private readonly slugifier: Slugifier, ) { } public lookup(fragment: string): TocEntry | undefined { - const slug = this.slugifier.fromHeading(fragment); + const slug = githubSlugifier.fromHeading(fragment); return this.entries.find(entry => entry.slug.equals(slug)); } } - -export class MdTableOfContentsProvider extends Disposable { - - private readonly _cache: MdDocumentInfoCache; - - constructor( - private readonly parser: IMdParser, - workspace: IMdWorkspace, - private readonly logger: ILogger, - ) { - super(); - this._cache = this._register(new MdDocumentInfoCache(workspace, doc => { - this.logger.verbose('TableOfContentsProvider', `create - ${doc.uri}`); - return TableOfContents.create(parser, doc); - })); - } - - public async get(resource: vscode.Uri): Promise { - return await this._cache.get(resource) ?? TableOfContents.empty; - } - - public getForDocument(doc: ITextDocument): Promise { - return this._cache.getForDocument(doc); - } - - public createForNotebook(notebook: vscode.NotebookDocument): Promise { - return TableOfContents.createForNotebook(this.parser, notebook); - } -} diff --git a/extensions/markdown-language-features/src/test/definitionProvider.test.ts b/extensions/markdown-language-features/src/test/definitionProvider.test.ts new file mode 100644 index 0000000000..a254f81a63 --- /dev/null +++ b/extensions/markdown-language-features/src/test/definitionProvider.test.ts @@ -0,0 +1,137 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdDefinitionProvider } from '../languageFeatures/definitionProvider'; +import { MdLinkProvider } from '../languageFeatures/documentLinkProvider'; +import { MdReferencesProvider } from '../languageFeatures/references'; +import { githubSlugifier } from '../slugify'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { MdWorkspaceContents } from '../workspaceContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; +import { joinLines, noopToken, workspacePath } from './util'; + + +function getDefinition(doc: InMemoryDocument, pos: vscode.Position, workspaceContents: MdWorkspaceContents) { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const referencesProvider = new MdReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier); + const provider = new MdDefinitionProvider(referencesProvider); + return provider.provideDefinition(doc, pos, noopToken); +} + +function assertDefinitionsEqual(actualDef: vscode.Definition, ...expectedDefs: { uri: vscode.Uri; line: number; startCharacter?: number; endCharacter?: number }[]) { + const actualDefsArr = Array.isArray(actualDef) ? actualDef : [actualDef]; + + assert.strictEqual(actualDefsArr.length, expectedDefs.length, `Definition counts should match`); + + for (let i = 0; i < actualDefsArr.length; ++i) { + const actual = actualDefsArr[i]; + const expected = expectedDefs[i]; + assert.strictEqual(actual.uri.toString(), expected.uri.toString(), `Definition '${i}' has expected document`); + assert.strictEqual(actual.range.start.line, expected.line, `Definition '${i}' has expected start line`); + assert.strictEqual(actual.range.end.line, expected.line, `Definition '${i}' has expected end line`); + if (typeof expected.startCharacter !== 'undefined') { + assert.strictEqual(actual.range.start.character, expected.startCharacter, `Definition '${i}' has expected start character`); + } + if (typeof expected.endCharacter !== 'undefined') { + assert.strictEqual(actual.range.end.character, expected.endCharacter, `Definition '${i}' has expected end character`); + } + } +} + +suite('markdown: Go to definition', () => { + test('Should not return definition when on link text', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `[ref](#abc)`, + `[ref]: http://example.com`, + )); + + const defs = await getDefinition(doc, new vscode.Position(0, 1), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(defs, undefined); + }); + + test('Should find definition links within file from link', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[link 1][abc]`, // trigger here + ``, + `[abc]: https://example.com`, + )); + + const defs = await getDefinition(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertDefinitionsEqual(defs!, + { uri: docUri, line: 2 }, + ); + }); + + test('Should find definition links using shorthand', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[ref]`, // trigger 1 + ``, + `[yes][ref]`, // trigger 2 + ``, + `[ref]: /Hello.md` // trigger 3 + )); + + { + const defs = await getDefinition(doc, new vscode.Position(0, 2), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertDefinitionsEqual(defs!, + { uri: docUri, line: 4 }, + ); + } + { + const defs = await getDefinition(doc, new vscode.Position(2, 7), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertDefinitionsEqual(defs!, + { uri: docUri, line: 4 }, + ); + } + { + const defs = await getDefinition(doc, new vscode.Position(4, 2), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertDefinitionsEqual(defs!, + { uri: docUri, line: 4 }, + ); + } + }); + + test('Should find definition links within file from definition', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[link 1][abc]`, + ``, + `[abc]: https://example.com`, // trigger here + )); + + const defs = await getDefinition(doc, new vscode.Position(2, 3), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertDefinitionsEqual(defs!, + { uri: docUri, line: 2 }, + ); + }); + + test('Should not find definition links across files', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[link 1][abc]`, + ``, + `[abc]: https://example.com`, + )); + + const defs = await getDefinition(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(workspacePath('other.md'), joinLines( + `[link 1][abc]`, + ``, + `[abc]: https://example.com?bad`, + )) + ])); + assertDefinitionsEqual(defs!, + { uri: docUri, line: 2 }, + ); + }); +}); diff --git a/extensions/markdown-language-features/src/test/diagnostic.test.ts b/extensions/markdown-language-features/src/test/diagnostic.test.ts new file mode 100644 index 0000000000..34def0a3df --- /dev/null +++ b/extensions/markdown-language-features/src/test/diagnostic.test.ts @@ -0,0 +1,160 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import 'mocha'; +import { DiagnosticComputer, DiagnosticConfiguration, DiagnosticLevel, DiagnosticManager, DiagnosticOptions } from '../languageFeatures/diagnostics'; +import { MdLinkProvider } from '../languageFeatures/documentLinkProvider'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { MdWorkspaceContents } from '../workspaceContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; +import { assertRangeEqual, joinLines, noopToken, workspacePath } from './util'; + + +function getComputedDiagnostics(doc: InMemoryDocument, workspaceContents: MdWorkspaceContents) { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const computer = new DiagnosticComputer(engine, workspaceContents, linkProvider); + return computer.getDiagnostics(doc, { + enabled: true, + validateFilePaths: DiagnosticLevel.warning, + validateOwnHeaders: DiagnosticLevel.warning, + validateReferences: DiagnosticLevel.warning, + }, noopToken); +} + +function createDiagnosticsManager(workspaceContents: MdWorkspaceContents, configuration = new MemoryDiagnosticConfiguration()) { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + return new DiagnosticManager(new DiagnosticComputer(engine, workspaceContents, linkProvider), configuration); +} + +class MemoryDiagnosticConfiguration implements DiagnosticConfiguration { + + private readonly _onDidChange = new vscode.EventEmitter(); + public readonly onDidChange = this._onDidChange.event; + + constructor( + private readonly enabled: boolean = true, + ) { } + + getOptions(_resource: vscode.Uri): DiagnosticOptions { + if (!this.enabled) { + return { + enabled: false, + validateFilePaths: DiagnosticLevel.ignore, + validateOwnHeaders: DiagnosticLevel.ignore, + validateReferences: DiagnosticLevel.ignore, + }; + } + return { + enabled: true, + validateFilePaths: DiagnosticLevel.warning, + validateOwnHeaders: DiagnosticLevel.warning, + validateReferences: DiagnosticLevel.warning, + }; + } +} + + +suite('markdown: Diagnostics', () => { + test('Should not return any diagnostics for empty document', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `text`, + )); + + const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(diagnostics, []); + }); + + test('Should generate diagnostic for link to file that does not exist', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `[bad](/no/such/file.md)`, + `[good](/doc.md)`, + `[good-ref]: /doc.md`, + `[bad-ref]: /no/such/file.md`, + )); + + const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(diagnostics.length, 2); + assertRangeEqual(new vscode.Range(0, 6, 0, 22), diagnostics[0].range); + assertRangeEqual(new vscode.Range(3, 11, 3, 27), diagnostics[1].range); + }); + + test('Should generate diagnostics for links to header that does not exist in current file', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `[good](#good-header)`, + `# Good Header`, + `[bad](#no-such-header)`, + `[good](#good-header)`, + `[good-ref]: #good-header`, + `[bad-ref]: #no-such-header`, + )); + + const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(diagnostics.length, 2); + assertRangeEqual(new vscode.Range(2, 6, 2, 21), diagnostics[0].range); + assertRangeEqual(new vscode.Range(5, 11, 5, 26), diagnostics[1].range); + }); + + test('Should generate diagnostics for links to non-existent headers in other files', async () => { + const doc1 = new InMemoryDocument(workspacePath('doc1.md'), joinLines( + `# My header`, + `[good](#my-header)`, + `[good](/doc1.md#my-header)`, + `[good](doc1.md#my-header)`, + `[good](/doc2.md#other-header)`, + `[bad](/doc2.md#no-such-other-header)`, + )); + + const doc2 = new InMemoryDocument(workspacePath('doc2.md'), joinLines( + `# Other header`, + )); + + const diagnostics = await getComputedDiagnostics(doc1, new InMemoryWorkspaceMarkdownDocuments([doc1, doc2])); + assert.deepStrictEqual(diagnostics.length, 1); + assertRangeEqual(new vscode.Range(5, 6, 5, 35), diagnostics[0].range); + }); + + test('Should support links both with and without .md file extension', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `# My header`, + `[good](#my-header)`, + `[good](/doc.md#my-header)`, + `[good](doc.md#my-header)`, + `[good](/doc#my-header)`, + `[good](doc#my-header)`, + )); + + const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(diagnostics.length, 0); + }); + + test('Should generate diagnostics for non-existent link reference', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `[good link][good]`, + `[bad link][no-such]`, + ``, + `[good]: http://example.com`, + )); + + const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(diagnostics.length, 1); + assertRangeEqual(new vscode.Range(1, 11, 1, 18), diagnostics[0].range); + }); + + test('Should not generate diagnostics when validate is disabled', async () => { + const doc1 = new InMemoryDocument(workspacePath('doc1.md'), joinLines( + `[text](#no-such-header)`, + `[text][no-such-ref]`, + )); + + const manager = createDiagnosticsManager(new InMemoryWorkspaceMarkdownDocuments([doc1]), new MemoryDiagnosticConfiguration(false)); + const diagnostics = await manager.getDiagnostics(doc1, noopToken); + assert.deepStrictEqual(diagnostics.length, 0); + }); +}); diff --git a/extensions/markdown-language-features/src/test/documentLink.test.ts b/extensions/markdown-language-features/src/test/documentLink.test.ts index 480c896b1b..1f4a7aa7b9 100644 --- a/extensions/markdown-language-features/src/test/documentLink.test.ts +++ b/extensions/markdown-language-features/src/test/documentLink.test.ts @@ -24,7 +24,7 @@ function workspaceFile(...segments: string[]) { async function getLinksForFile(file: vscode.Uri): Promise { debugLog('getting links', file.toString(), Date.now()); - const r = (await vscode.commands.executeCommand('vscode.executeLinkProvider', file, /*linkResolveCount*/ 100))!; + const r = (await vscode.commands.executeCommand('vscode.executeLinkProvider', file))!; debugLog('got links', file.toString(), Date.now()); return r; } @@ -134,7 +134,7 @@ async function getLinksForFile(file: vscode.Uri): Promise } }); - test('Should navigate to fragment within current untitled file', async () => { // TODO: skip for now for ls migration + test('Should navigate to fragment within current untitled file', async () => { const testFile = workspaceFile('x.md').with({ scheme: 'untitled' }); await withFileContents(testFile, joinLines( '[](#second)', @@ -171,7 +171,7 @@ async function withFileContents(file: vscode.Uri, contents: string): Promise { + test('Should not return anything for empty document', async () => { + const links = await getLinksForFile(''); + assert.strictEqual(links.length, 0); + }); + + test('Should not return anything for simple document without links', async () => { + const links = await getLinksForFile('# a\nfdasfdfsafsa'); + assert.strictEqual(links.length, 0); + }); + + test('Should detect basic http links', async () => { + const links = await getLinksForFile('a [b](https://example.com) c'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25)); + }); + + test('Should detect basic workspace links', async () => { + { + const links = await getLinksForFile('a [b](./file) c'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 12)); + } + { + const links = await getLinksForFile('a [b](file.png) c'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 14)); + } + }); + + test('Should detect links with title', async () => { + const links = await getLinksForFile('a [b](https://example.com "abc") c'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 25)); + }); + + // #35245 + test('Should handle links with escaped characters in name', async () => { + const links = await getLinksForFile('a [b\\]](./file)'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 8, 0, 14)); + }); + + + test('Should handle links with balanced parens', async () => { + { + const links = await getLinksForFile('a [b](https://example.com/a()c) c'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 30)); + } + { + const links = await getLinksForFile('a [b](https://example.com/a(b)c) c'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 6, 0, 31)); + + } + { + // #49011 + const links = await getLinksForFile('[A link](http://ThisUrlhasParens/A_link(in_parens))'); + assert.strictEqual(links.length, 1); + const [link] = links; + assertRangeEqual(link.range, new vscode.Range(0, 9, 0, 50)); + } + }); + + test('Should handle two links without space', async () => { + const links = await getLinksForFile('a ([test](test)[test2](test2)) c'); + assert.strictEqual(links.length, 2); + const [link1, link2] = links; + assertRangeEqual(link1.range, new vscode.Range(0, 10, 0, 14)); + assertRangeEqual(link2.range, new vscode.Range(0, 23, 0, 28)); + }); + + // #49238 + test('should handle hyperlinked images', async () => { + { + const links = await getLinksForFile('[![alt text](image.jpg)](https://example.com)'); + assert.strictEqual(links.length, 2); + const [link1, link2] = links; + assertRangeEqual(link1.range, new vscode.Range(0, 13, 0, 22)); + assertRangeEqual(link2.range, new vscode.Range(0, 25, 0, 44)); + } + { + const links = await getLinksForFile('[![a]( whitespace.jpg )]( https://whitespace.com )'); + assert.strictEqual(links.length, 2); + const [link1, link2] = links; + assertRangeEqual(link1.range, new vscode.Range(0, 7, 0, 21)); + assertRangeEqual(link2.range, new vscode.Range(0, 26, 0, 48)); + } + { + const links = await getLinksForFile('[![a](img1.jpg)](file1.txt) text [![a](img2.jpg)](file2.txt)'); + assert.strictEqual(links.length, 4); + const [link1, link2, link3, link4] = links; + assertRangeEqual(link1.range, new vscode.Range(0, 6, 0, 14)); + assertRangeEqual(link2.range, new vscode.Range(0, 17, 0, 26)); + assertRangeEqual(link3.range, new vscode.Range(0, 39, 0, 47)); + assertRangeEqual(link4.range, new vscode.Range(0, 50, 0, 59)); + } + }); + + test('Should not consider link references starting with ^ character valid (#107471)', async () => { + const links = await getLinksForFile('[^reference]: https://example.com'); + assert.strictEqual(links.length, 0); + }); + + test('Should find definitions links with spaces in angle brackets (#136073)', async () => { + const links = await getLinksForFile([ + '[a]: ', + '[b]: ', + ].join('\n')); + assert.strictEqual(links.length, 2); + + const [link1, link2] = links; + assertRangeEqual(link1.range, new vscode.Range(0, 6, 0, 9)); + assertRangeEqual(link2.range, new vscode.Range(1, 6, 1, 8)); + }); + + test('Should only find one link for reference sources [a]: source (#141285)', async () => { + const links = await getLinksForFile([ + '[Works]: https://microsoft.com', + ].join('\n')); + + assert.strictEqual(links.length, 1); + }); + + test('Should find links for referees with only one [] (#141285)', async () => { + let links = await getLinksForFile([ + '[ref]', + '[ref]: https://microsoft.com', + ].join('\n')); + assert.strictEqual(links.length, 2); + + links = await getLinksForFile([ + '[Does Not Work]', + '[def]: https://microsoft.com', + ].join('\n')); + assert.strictEqual(links.length, 1); + }); + + test('Should not find link for reference using one [] when source does not exist (#141285)', async () => { + const links = await getLinksForFile('[Works]'); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links in code fenced with backticks', async () => { + const text = joinLines( + '```', + '[b](https://example.com)', + '```'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links in code fenced with tilda', async () => { + const text = joinLines( + '~~~', + '[b](https://example.com)', + '~~~'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links in indented code', async () => { + const links = await getLinksForFile(' [b](https://example.com)'); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links in inline code span', async () => { + const links = await getLinksForFile('`[b](https://example.com)`'); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links with code span inside', async () => { + const links = await getLinksForFile('[li`nk](https://example.com`)'); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links in multiline inline code span', async () => { + const text = joinLines( + '`` ', + '[b](https://example.com)', + '``'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider link references in code fenced with backticks (#146714)', async () => { + const text = joinLines( + '```', + '[a] [bb]', + '```'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider reference sources in code fenced with backticks (#146714)', async () => { + const text = joinLines( + '```', + '[a]: http://example.com;', + '[b]: ;', + '[c]: (http://example.com);', + '```'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 0); + }); + + test('Should not consider links in multiline inline code span between between text', async () => { + const text = joinLines( + '[b](https://1.com) `[b](https://2.com)', + '` [b](https://3.com)'); + const links = await getLinksForFile(text); + assert.deepStrictEqual(links.map(l => l.target?.authority), ['1.com', '3.com']); + }); + + test('Should not consider links in multiline inline code span with new line after the first backtick', async () => { + const text = joinLines( + '`', + '[b](https://example.com)`'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 0); + }); + + test('Should not miss links in invalid multiline inline code span', async () => { + const text = joinLines( + '`` ', + '', + '[b](https://example.com)', + '', + '``'); + const links = await getLinksForFile(text); + assert.strictEqual(links.length, 1); + }); + + test('Should find autolinks', async () => { + const links = await getLinksForFile('pre post'); + assert.strictEqual(links.length, 1); + + const link = links[0]; + assertRangeEqual(link.range, new vscode.Range(0, 5, 0, 23)); + }); +}); diff --git a/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts b/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts new file mode 100644 index 0000000000..5dcad7ee65 --- /dev/null +++ b/extensions/markdown-language-features/src/test/documentSymbolProvider.test.ts @@ -0,0 +1,97 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdDocumentSymbolProvider } from '../languageFeatures/documentSymbolProvider'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryDocument } from '../util/inMemoryDocument'; + + +const testFileName = vscode.Uri.file('test.md'); + + +function getSymbolsForFile(fileContents: string) { + const doc = new InMemoryDocument(testFileName, fileContents); + const provider = new MdDocumentSymbolProvider(createNewMarkdownEngine()); + return provider.provideDocumentSymbols(doc); +} + + +suite('markdown.DocumentSymbolProvider', () => { + test('Should not return anything for empty document', async () => { + const symbols = await getSymbolsForFile(''); + assert.strictEqual(symbols.length, 0); + }); + + test('Should not return anything for document with no headers', async () => { + const symbols = await getSymbolsForFile('a\na'); + assert.strictEqual(symbols.length, 0); + }); + + test('Should not return anything for document with # but no real headers', async () => { + const symbols = await getSymbolsForFile('a#a\na#'); + assert.strictEqual(symbols.length, 0); + }); + + test('Should return single symbol for single header', async () => { + const symbols = await getSymbolsForFile('# h'); + assert.strictEqual(symbols.length, 1); + assert.strictEqual(symbols[0].name, '# h'); + }); + + test('Should not care about symbol level for single header', async () => { + const symbols = await getSymbolsForFile('### h'); + assert.strictEqual(symbols.length, 1); + assert.strictEqual(symbols[0].name, '### h'); + }); + + test('Should put symbols of same level in flat list', async () => { + const symbols = await getSymbolsForFile('## h\n## h2'); + assert.strictEqual(symbols.length, 2); + assert.strictEqual(symbols[0].name, '## h'); + assert.strictEqual(symbols[1].name, '## h2'); + }); + + test('Should nest symbol of level - 1 under parent', async () => { + + const symbols = await getSymbolsForFile('# h\n## h2\n## h3'); + assert.strictEqual(symbols.length, 1); + assert.strictEqual(symbols[0].name, '# h'); + assert.strictEqual(symbols[0].children.length, 2); + assert.strictEqual(symbols[0].children[0].name, '## h2'); + assert.strictEqual(symbols[0].children[1].name, '## h3'); + }); + + test('Should nest symbol of level - n under parent', async () => { + const symbols = await getSymbolsForFile('# h\n#### h2'); + assert.strictEqual(symbols.length, 1); + assert.strictEqual(symbols[0].name, '# h'); + assert.strictEqual(symbols[0].children.length, 1); + assert.strictEqual(symbols[0].children[0].name, '#### h2'); + }); + + test('Should flatten children where lower level occurs first', async () => { + const symbols = await getSymbolsForFile('# h\n### h2\n## h3'); + assert.strictEqual(symbols.length, 1); + assert.strictEqual(symbols[0].name, '# h'); + assert.strictEqual(symbols[0].children.length, 2); + assert.strictEqual(symbols[0].children[0].name, '### h2'); + assert.strictEqual(symbols[0].children[1].name, '## h3'); + }); + + test('Should handle line separator in file. Issue #63749', async () => { + const symbols = await getSymbolsForFile(`# A +- foo + +# B +- bar`); + assert.strictEqual(symbols.length, 2); + assert.strictEqual(symbols[0].name, '# A'); + assert.strictEqual(symbols[1].name, '# B'); + }); +}); + diff --git a/extensions/markdown-language-features/src/test/engine.test.ts b/extensions/markdown-language-features/src/test/engine.test.ts index 0f0e0ed89f..63a9ea92c1 100644 --- a/extensions/markdown-language-features/src/test/engine.test.ts +++ b/extensions/markdown-language-features/src/test/engine.test.ts @@ -6,8 +6,8 @@ import * as assert from 'assert'; import 'mocha'; import * as vscode from 'vscode'; -import { InMemoryDocument } from '../util/inMemoryDocument'; import { createNewMarkdownEngine } from './engine'; +import { InMemoryDocument } from '../util/inMemoryDocument'; const testFileName = vscode.Uri.file('test.md'); diff --git a/extensions/markdown-language-features/src/test/engine.ts b/extensions/markdown-language-features/src/test/engine.ts index 422c2272cb..7e05cf41fb 100644 --- a/extensions/markdown-language-features/src/test/engine.ts +++ b/extensions/markdown-language-features/src/test/engine.ts @@ -4,11 +4,10 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { MarkdownItEngine } from '../markdownEngine'; +import { MarkdownEngine } from '../markdownEngine'; import { MarkdownContributionProvider, MarkdownContributions } from '../markdownExtensions'; import { githubSlugifier } from '../slugify'; import { Disposable } from '../util/dispose'; -import { nulLogger } from './nulLogging'; const emptyContributions = new class extends Disposable implements MarkdownContributionProvider { readonly extensionUri = vscode.Uri.file('/'); @@ -16,6 +15,6 @@ const emptyContributions = new class extends Disposable implements MarkdownContr readonly onContributionsChanged = this._register(new vscode.EventEmitter()).event; }; -export function createNewMarkdownEngine(): MarkdownItEngine { - return new MarkdownItEngine(emptyContributions, githubSlugifier, nulLogger); +export function createNewMarkdownEngine(): MarkdownEngine { + return new MarkdownEngine(emptyContributions, githubSlugifier); } diff --git a/extensions/markdown-language-features/src/test/fileReferences.test.ts b/extensions/markdown-language-features/src/test/fileReferences.test.ts new file mode 100644 index 0000000000..36d60cfb70 --- /dev/null +++ b/extensions/markdown-language-features/src/test/fileReferences.test.ts @@ -0,0 +1,118 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdLinkProvider } from '../languageFeatures/documentLinkProvider'; +import { MdReference, MdReferencesProvider } from '../languageFeatures/references'; +import { githubSlugifier } from '../slugify'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { MdWorkspaceContents } from '../workspaceContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; +import { joinLines, noopToken, workspacePath } from './util'; + + +function getFileReferences(resource: vscode.Uri, workspaceContents: MdWorkspaceContents) { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const provider = new MdReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier); + return provider.getAllReferencesToFile(resource, noopToken); +} + +function assertReferencesEqual(actualRefs: readonly MdReference[], ...expectedRefs: { uri: vscode.Uri; line: number }[]) { + assert.strictEqual(actualRefs.length, expectedRefs.length, `Reference counts should match`); + + for (let i = 0; i < actualRefs.length; ++i) { + const actual = actualRefs[i].location; + const expected = expectedRefs[i]; + assert.strictEqual(actual.uri.toString(), expected.uri.toString(), `Ref '${i}' has expected document`); + assert.strictEqual(actual.range.start.line, expected.line, `Ref '${i}' has expected start line`); + assert.strictEqual(actual.range.end.line, expected.line, `Ref '${i}' has expected end line`); + } +} + +suite('markdown: find file references', () => { + + test('Should find basic references', async () => { + const docUri = workspacePath('doc.md'); + const otherUri = workspacePath('other.md'); + + const refs = await getFileReferences(otherUri, new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(docUri, joinLines( + `# header`, + `[link 1](./other.md)`, + `[link 2](./other.md)`, + )), + new InMemoryDocument(otherUri, joinLines( + `# header`, + `pre`, + `[link 3](./other.md)`, + `post`, + )), + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 1 }, + { uri: docUri, line: 2 }, + { uri: otherUri, line: 2 }, + ); + }); + + test('Should find references with and without file extensions', async () => { + const docUri = workspacePath('doc.md'); + const otherUri = workspacePath('other.md'); + + const refs = await getFileReferences(otherUri, new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(docUri, joinLines( + `# header`, + `[link 1](./other.md)`, + `[link 2](./other)`, + )), + new InMemoryDocument(otherUri, joinLines( + `# header`, + `pre`, + `[link 3](./other.md)`, + `[link 4](./other)`, + `post`, + )), + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 1 }, + { uri: docUri, line: 2 }, + { uri: otherUri, line: 2 }, + { uri: otherUri, line: 3 }, + ); + }); + + test('Should find references with headers on links', async () => { + const docUri = workspacePath('doc.md'); + const otherUri = workspacePath('other.md'); + + const refs = await getFileReferences(otherUri, new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(docUri, joinLines( + `# header`, + `[link 1](./other.md#sub-bla)`, + `[link 2](./other#sub-bla)`, + )), + new InMemoryDocument(otherUri, joinLines( + `# header`, + `pre`, + `[link 3](./other.md#sub-bla)`, + `[link 4](./other#sub-bla)`, + `post`, + )), + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 1 }, + { uri: docUri, line: 2 }, + { uri: otherUri, line: 2 }, + { uri: otherUri, line: 3 }, + ); + }); +}); diff --git a/extensions/markdown-language-features/src/test/foldingProvider.test.ts b/extensions/markdown-language-features/src/test/foldingProvider.test.ts new file mode 100644 index 0000000000..7e13d732e3 --- /dev/null +++ b/extensions/markdown-language-features/src/test/foldingProvider.test.ts @@ -0,0 +1,223 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdFoldingProvider } from '../languageFeatures/foldingProvider'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { createNewMarkdownEngine } from './engine'; +import { joinLines } from './util'; + +const testFileName = vscode.Uri.file('test.md'); + +suite('markdown.FoldingProvider', () => { + test('Should not return anything for empty document', async () => { + const folds = await getFoldsForDocument(``); + assert.strictEqual(folds.length, 0); + }); + + test('Should not return anything for document without headers', async () => { + const folds = await getFoldsForDocument(joinLines( + `a`, + `**b** afas`, + `a#b`, + `a`, + )); + assert.strictEqual(folds.length, 0); + }); + + test('Should fold from header to end of document', async () => { + const folds = await getFoldsForDocument(joinLines( + `a`, + `# b`, + `c`, + `d`, + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 3); + }); + + test('Should leave single newline before next header', async () => { + const folds = await getFoldsForDocument(joinLines( + ``, + `# a`, + `x`, + ``, + `# b`, + `y`, + )); + assert.strictEqual(folds.length, 2); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 2); + }); + + test('Should collapse multiple newlines to single newline before next header', async () => { + const folds = await getFoldsForDocument(joinLines( + ``, + `# a`, + `x`, + ``, + ``, + ``, + `# b`, + `y` + )); + assert.strictEqual(folds.length, 2); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 4); + }); + + test('Should not collapse if there is no newline before next header', async () => { + const folds = await getFoldsForDocument(joinLines( + ``, + `# a`, + `x`, + `# b`, + `y`, + )); + assert.strictEqual(folds.length, 2); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 2); + }); + + test('Should fold nested markers', async () => { + const folds = await getFoldsForDocument(joinLines( + `a`, + ``, + `b`, + ``, + `b.a`, + ``, + `b`, + ``, + `b.b`, + ``, + `b`, + ``, + `a`, + )); + assert.strictEqual(folds.length, 3); + const [outer, first, second] = folds.sort((a, b) => a.start - b.start); + + assert.strictEqual(outer.start, 1); + assert.strictEqual(outer.end, 11); + assert.strictEqual(first.start, 3); + assert.strictEqual(first.end, 5); + assert.strictEqual(second.start, 7); + assert.strictEqual(second.end, 9); + }); + + test('Should fold from list to end of document', async () => { + const folds = await getFoldsForDocument(joinLines( + `a`, + `- b`, + `c`, + `d`, + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 3); + }); + + test('lists folds should span multiple lines of content', async () => { + const folds = await getFoldsForDocument(joinLines( + `a`, + `- This list item\n spans multiple\n lines.`, + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 3); + }); + + test('List should leave single blankline before new element', async () => { + const folds = await getFoldsForDocument(joinLines( + `- a`, + `a`, + ``, + ``, + `b` + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 0); + assert.strictEqual(firstFold.end, 2); + }); + + test('Should fold fenced code blocks', async () => { + const folds = await getFoldsForDocument(joinLines( + `~~~ts`, + `a`, + `~~~`, + `b`, + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 0); + assert.strictEqual(firstFold.end, 2); + }); + + test('Should fold fenced code blocks with yaml front matter', async () => { + const folds = await getFoldsForDocument(joinLines( + `---`, + `title: bla`, + `---`, + ``, + `~~~ts`, + `a`, + `~~~`, + ``, + `a`, + `a`, + `b`, + `a`, + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 4); + assert.strictEqual(firstFold.end, 6); + }); + + test('Should fold html blocks', async () => { + const folds = await getFoldsForDocument(joinLines( + `x`, + `
`, + ` fa`, + `
`, + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 3); + }); + + test('Should fold html block comments', async () => { + const folds = await getFoldsForDocument(joinLines( + `x`, + `` + )); + assert.strictEqual(folds.length, 1); + const firstFold = folds[0]; + assert.strictEqual(firstFold.start, 1); + assert.strictEqual(firstFold.end, 3); + assert.strictEqual(firstFold.kind, vscode.FoldingRangeKind.Comment); + }); +}); + + +async function getFoldsForDocument(contents: string) { + const doc = new InMemoryDocument(testFileName, contents); + const provider = new MdFoldingProvider(createNewMarkdownEngine()); + return await provider.provideFoldingRanges(doc, {}, new vscode.CancellationTokenSource().token); +} diff --git a/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts b/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts index b3c20dc0f5..8f1e4a05fb 100644 --- a/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts +++ b/extensions/markdown-language-features/src/test/inMemoryWorkspace.ts @@ -4,80 +4,58 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import * as path from 'path'; import * as vscode from 'vscode'; -import { ITextDocument } from '../types/textDocument'; -import { Disposable } from '../util/dispose'; -import { ResourceMap } from '../util/resourceMap'; -import { IMdWorkspace } from '../workspace'; +import { MdWorkspaceContents, SkinnyTextDocument } from '../workspaceContents'; -export class InMemoryMdWorkspace extends Disposable implements IMdWorkspace { - private readonly _documents = new ResourceMap(uri => uri.fsPath); +export class InMemoryWorkspaceMarkdownDocuments implements MdWorkspaceContents { + private readonly _documents = new Map(); - constructor(documents: ITextDocument[]) { - super(); + constructor(documents: SkinnyTextDocument[]) { for (const doc of documents) { - this._documents.set(doc.uri, doc); + this._documents.set(this.getKey(doc.uri), doc); } } - public values() { - return Array.from(this._documents.values()); - } - public async getAllMarkdownDocuments() { - return this.values(); + return Array.from(this._documents.values()); } - public async getOrLoadMarkdownDocument(resource: vscode.Uri): Promise { - return this._documents.get(resource); - } - - public hasMarkdownDocument(resolvedHrefPath: vscode.Uri): boolean { - return this._documents.has(resolvedHrefPath); + public async getMarkdownDocument(resource: vscode.Uri): Promise { + return this._documents.get(this.getKey(resource)); } public async pathExists(resource: vscode.Uri): Promise { - return this._documents.has(resource); + return this._documents.has(this.getKey(resource)); } - public async readDirectory(resource: vscode.Uri): Promise<[string, vscode.FileType][]> { - const files = new Map(); - const pathPrefix = resource.fsPath + (resource.fsPath.endsWith('/') || resource.fsPath.endsWith('\\') ? '' : path.sep); - for (const doc of this._documents.values()) { - const path = doc.uri.fsPath; - if (path.startsWith(pathPrefix)) { - const parts = path.slice(pathPrefix.length).split(/\/|\\/g); - files.set(parts[0], parts.length > 1 ? vscode.FileType.Directory : vscode.FileType.File); - } - } - return Array.from(files.entries()); - } - - private readonly _onDidChangeMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); + private readonly _onDidChangeMarkdownDocumentEmitter = new vscode.EventEmitter(); public onDidChangeMarkdownDocument = this._onDidChangeMarkdownDocumentEmitter.event; - private readonly _onDidCreateMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); + private readonly _onDidCreateMarkdownDocumentEmitter = new vscode.EventEmitter(); public onDidCreateMarkdownDocument = this._onDidCreateMarkdownDocumentEmitter.event; - private readonly _onDidDeleteMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); + private readonly _onDidDeleteMarkdownDocumentEmitter = new vscode.EventEmitter(); public onDidDeleteMarkdownDocument = this._onDidDeleteMarkdownDocumentEmitter.event; - public updateDocument(document: ITextDocument) { - this._documents.set(document.uri, document); + public updateDocument(document: SkinnyTextDocument) { + this._documents.set(this.getKey(document.uri), document); this._onDidChangeMarkdownDocumentEmitter.fire(document); } - public createDocument(document: ITextDocument) { - assert.ok(!this._documents.has(document.uri)); + public createDocument(document: SkinnyTextDocument) { + assert.ok(!this._documents.has(this.getKey(document.uri))); - this._documents.set(document.uri, document); + this._documents.set(this.getKey(document.uri), document); this._onDidCreateMarkdownDocumentEmitter.fire(document); } public deleteDocument(resource: vscode.Uri) { - this._documents.delete(resource); + this._documents.delete(this.getKey(resource)); this._onDidDeleteMarkdownDocumentEmitter.fire(resource); } + + private getKey(resource: vscode.Uri): string { + return resource.fsPath; + } } diff --git a/extensions/markdown-language-features/src/test/nulLogging.ts b/extensions/markdown-language-features/src/test/nulLogging.ts deleted file mode 100644 index d0db040fc1..0000000000 --- a/extensions/markdown-language-features/src/test/nulLogging.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { ILogger } from '../logging'; - -export const nulLogger = new class implements ILogger { - verbose(): void { - // noop - } -}; diff --git a/extensions/markdown-language-features/src/test/pathCompletion.test.ts b/extensions/markdown-language-features/src/test/pathCompletion.test.ts new file mode 100644 index 0000000000..c6c0710ea6 --- /dev/null +++ b/extensions/markdown-language-features/src/test/pathCompletion.test.ts @@ -0,0 +1,169 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdLinkProvider } from '../languageFeatures/documentLinkProvider'; +import { MdPathCompletionProvider } from '../languageFeatures/pathCompletions'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { createNewMarkdownEngine } from './engine'; +import { CURSOR, getCursorPositions, joinLines, noopToken, workspacePath } from './util'; + + +function getCompletionsAtCursor(resource: vscode.Uri, fileContents: string) { + const doc = new InMemoryDocument(resource, fileContents); + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const provider = new MdPathCompletionProvider(engine, linkProvider); + const cursorPositions = getCursorPositions(fileContents, doc); + return provider.provideCompletionItems(doc, cursorPositions[0], noopToken, { + triggerCharacter: undefined, + triggerKind: vscode.CompletionTriggerKind.Invoke, + }); +} + +suite('Markdown path completion provider', () => { + + setup(async () => { + // These tests assume that the markdown completion provider is already registered + await vscode.extensions.getExtension('vscode.markdown-language-features')!.activate(); + }); + + test('Should not return anything when triggered in empty doc', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), `${CURSOR}`); + assert.strictEqual(completions.length, 0); + }); + + test('Should return anchor completions', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[](#${CURSOR}`, + ``, + `# A b C`, + `# x y Z`, + )); + + assert.strictEqual(completions.length, 2); + assert.ok(completions.some(x => x.label === '#a-b-c'), 'Has a-b-c anchor completion'); + assert.ok(completions.some(x => x.label === '#x-y-z'), 'Has x-y-z anchor completion'); + }); + + test('Should not return suggestions for http links', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[](http:${CURSOR}`, + ``, + `# http`, + `# http:`, + `# https:`, + )); + + assert.strictEqual(completions.length, 0); + }); + + test('Should return relative path suggestions', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[](${CURSOR}`, + ``, + `# A b C`, + )); + + assert.ok(completions.some(x => x.label === 'a.md'), 'Has a.md file completion'); + assert.ok(completions.some(x => x.label === 'b.md'), 'Has b.md file completion'); + assert.ok(completions.some(x => x.label === 'sub/'), 'Has sub folder completion'); + }); + + test('Should return relative path suggestions using ./', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[](./${CURSOR}`, + ``, + `# A b C`, + )); + + assert.ok(completions.some(x => x.label === 'a.md'), 'Has a.md file completion'); + assert.ok(completions.some(x => x.label === 'b.md'), 'Has b.md file completion'); + assert.ok(completions.some(x => x.label === 'sub/'), 'Has sub folder completion'); + }); + + test('Should return absolute path suggestions using /', async () => { + const completions = await getCompletionsAtCursor(workspacePath('sub', 'new.md'), joinLines( + `[](/${CURSOR}`, + ``, + `# A b C`, + )); + + assert.ok(completions.some(x => x.label === 'a.md'), 'Has a.md file completion'); + assert.ok(completions.some(x => x.label === 'b.md'), 'Has b.md file completion'); + assert.ok(completions.some(x => x.label === 'sub/'), 'Has sub folder completion'); + assert.ok(!completions.some(x => x.label === 'c.md'), 'Should not have c.md from sub folder'); + }); + + test('Should return anchor suggestions in other file', async () => { + const completions = await getCompletionsAtCursor(workspacePath('sub', 'new.md'), joinLines( + `[](/b.md#${CURSOR}`, + )); + + assert.ok(completions.some(x => x.label === '#b'), 'Has #b header completion'); + assert.ok(completions.some(x => x.label === '#header1'), 'Has #header1 header completion'); + }); + + test('Should reference links for current file', async () => { + const completions = await getCompletionsAtCursor(workspacePath('sub', 'new.md'), joinLines( + `[][${CURSOR}`, + ``, + `[ref-1]: bla`, + `[ref-2]: bla`, + )); + + assert.strictEqual(completions.length, 2); + assert.ok(completions.some(x => x.label === 'ref-1'), 'Has ref-1 reference completion'); + assert.ok(completions.some(x => x.label === 'ref-2'), 'Has ref-2 reference completion'); + }); + + test('Should complete headers in link definitions', async () => { + const completions = await getCompletionsAtCursor(workspacePath('sub', 'new.md'), joinLines( + `# a B c`, + `# x y Z`, + `[ref-1]: ${CURSOR}`, + )); + + assert.ok(completions.some(x => x.label === '#a-b-c'), 'Has #a-b-c header completion'); + assert.ok(completions.some(x => x.label === '#x-y-z'), 'Has #x-y-z header completion'); + }); + + test('Should complete relative paths in link definitions', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `# a B c`, + `[ref-1]: ${CURSOR}`, + )); + + assert.ok(completions.some(x => x.label === 'a.md'), 'Has a.md file completion'); + assert.ok(completions.some(x => x.label === 'b.md'), 'Has b.md file completion'); + assert.ok(completions.some(x => x.label === 'sub/'), 'Has sub folder completion'); + }); + + test('Should escape spaces in path names', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[](./sub/${CURSOR})` + )); + + assert.ok(completions.some(x => x.insertText === 'file%20with%20space.md'), 'Has encoded path completion'); + }); + + test('Should complete paths for path with encoded spaces', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[](./sub%20with%20space/${CURSOR})` + )); + + assert.ok(completions.some(x => x.insertText === 'file.md'), 'Has file from space'); + }); + + test('Should complete definition path for path with encoded spaces', async () => { + const completions = await getCompletionsAtCursor(workspacePath('new.md'), joinLines( + `[def]: ./sub%20with%20space/${CURSOR}` + )); + + assert.ok(completions.some(x => x.insertText === 'file.md'), 'Has file from space'); + }); +}); diff --git a/extensions/markdown-language-features/src/test/references.test.ts b/extensions/markdown-language-features/src/test/references.test.ts new file mode 100644 index 0000000000..d86c028c2c --- /dev/null +++ b/extensions/markdown-language-features/src/test/references.test.ts @@ -0,0 +1,580 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdLinkProvider } from '../languageFeatures/documentLinkProvider'; +import { MdReferencesProvider } from '../languageFeatures/references'; +import { githubSlugifier } from '../slugify'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { MdWorkspaceContents } from '../workspaceContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; +import { joinLines, noopToken, workspacePath } from './util'; + + +function getReferences(doc: InMemoryDocument, pos: vscode.Position, workspaceContents: MdWorkspaceContents) { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const provider = new MdReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier); + return provider.provideReferences(doc, pos, { includeDeclaration: true }, noopToken); +} + +function assertReferencesEqual(actualRefs: readonly vscode.Location[], ...expectedRefs: { uri: vscode.Uri; line: number; startCharacter?: number; endCharacter?: number }[]) { + assert.strictEqual(actualRefs.length, expectedRefs.length, `Reference counts should match`); + + for (let i = 0; i < actualRefs.length; ++i) { + const actual = actualRefs[i]; + const expected = expectedRefs[i]; + assert.strictEqual(actual.uri.toString(), expected.uri.toString(), `Ref '${i}' has expected document`); + assert.strictEqual(actual.range.start.line, expected.line, `Ref '${i}' has expected start line`); + assert.strictEqual(actual.range.end.line, expected.line, `Ref '${i}' has expected end line`); + if (typeof expected.startCharacter !== 'undefined') { + assert.strictEqual(actual.range.start.character, expected.startCharacter, `Ref '${i}' has expected start character`); + } + if (typeof expected.endCharacter !== 'undefined') { + assert.strictEqual(actual.range.end.character, expected.endCharacter, `Ref '${i}' has expected end character`); + } + } +} + +suite('markdown: find all references', () => { + test('Should not return references when not on header or link', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `# abc`, + ``, + `[link 1](#abc)`, + `text`, + )); + + { + const refs = await getReferences(doc, new vscode.Position(1, 0), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs, []); + } + { + const refs = await getReferences(doc, new vscode.Position(3, 2), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs, []); + } + }); + + test('Should find references from header within same file', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# abc`, + ``, + `[link 1](#abc)`, + `[not link](#noabc)`, + `[link 2](#abc)`, + )); + const refs = await getReferences(doc, new vscode.Position(0, 3), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, + { uri, line: 2 }, + { uri, line: 4 }, + ); + }); + + test('Should not return references when on link text', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `[ref](#abc)`, + `[ref]: http://example.com`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 1), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs, []); + }); + + test('Should find references using normalized slug', async () => { + const doc = new InMemoryDocument(workspacePath('doc.md'), joinLines( + `# a B c`, + `[simple](#a-b-c)`, + `[start underscore](#_a-b-c)`, + `[different case](#a-B-C)`, + )); + + { + // Trigger header + const refs = await getReferences(doc, new vscode.Position(0, 0), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs!.length, 4); + } + { + // Trigger on line 1 + const refs = await getReferences(doc, new vscode.Position(1, 12), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs!.length, 4); + } + { + // Trigger on line 2 + const refs = await getReferences(doc, new vscode.Position(2, 24), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs!.length, 4); + } + { + // Trigger on line 3 + const refs = await getReferences(doc, new vscode.Position(3, 20), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.deepStrictEqual(refs!.length, 4); + } + }); + + test('Should find references from header across files', async () => { + const docUri = workspacePath('doc.md'); + const other1Uri = workspacePath('sub', 'other.md'); + const other2Uri = workspacePath('other2.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `# abc`, + ``, + `[link 1](#abc)`, + )); + const refs = await getReferences(doc, new vscode.Position(0, 3), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(other1Uri, joinLines( + `[not link](#abc)`, + `[not link](/doc.md#abz)`, + `[link](/doc.md#abc)`, + )), + new InMemoryDocument(other2Uri, joinLines( + `[not link](#abc)`, + `[not link](./doc.md#abz)`, + `[link](./doc.md#abc)`, + )) + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, // Header definition + { uri: docUri, line: 2 }, + { uri: other1Uri, line: 2 }, + { uri: other2Uri, line: 2 }, + ); + }); + + test('Should find references from header to link definitions ', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# abc`, + ``, + `[bla]: #abc` + )); + + const refs = await getReferences(doc, new vscode.Position(0, 3), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, // Header definition + { uri, line: 2 }, + ); + }); + + test('Should find header references from link definition', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# A b C`, + `[text][bla]`, + `[bla]: #a-b-c`, // trigger here + )); + + const refs = await getReferences(doc, new vscode.Position(2, 9), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, // Header definition + { uri, line: 2 }, + ); + }); + + test('Should find references from link within same file', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# abc`, + ``, + `[link 1](#abc)`, + `[not link](#noabc)`, + `[link 2](#abc)`, + )); + + const refs = await getReferences(doc, new vscode.Position(2, 10), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, // Header definition + { uri, line: 2 }, + { uri, line: 4 }, + ); + }); + + test('Should find references from link across files', async () => { + const docUri = workspacePath('doc.md'); + const other1Uri = workspacePath('sub', 'other.md'); + const other2Uri = workspacePath('other2.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `# abc`, + ``, + `[link 1](#abc)`, + )); + const refs = await getReferences(doc, new vscode.Position(2, 10), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(other1Uri, joinLines( + `[not link](#abc)`, + `[not link](/doc.md#abz)`, + `[with ext](/doc.md#abc)`, + `[without ext](/doc#abc)`, + )), + new InMemoryDocument(other2Uri, joinLines( + `[not link](#abc)`, + `[not link](./doc.md#abz)`, + `[link](./doc.md#abc)`, + )) + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, // Header definition + { uri: docUri, line: 2 }, + { uri: other1Uri, line: 2 }, // Other with ext + { uri: other1Uri, line: 3 }, // Other without ext + { uri: other2Uri, line: 2 }, // Other2 + ); + }); + + test('Should find references without requiring file extensions', async () => { + const docUri = workspacePath('doc.md'); + const other1Uri = workspacePath('other.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `# a B c`, + ``, + `[link 1](#a-b-c)`, + )); + const refs = await getReferences(doc, new vscode.Position(2, 10), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(other1Uri, joinLines( + `[not link](#a-b-c)`, + `[not link](/doc.md#a-b-z)`, + `[with ext](/doc.md#a-b-c)`, + `[without ext](/doc#a-b-c)`, + `[rel with ext](./doc.md#a-b-c)`, + `[rel without ext](./doc#a-b-c)`, + )), + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, // Header definition + { uri: docUri, line: 2 }, + { uri: other1Uri, line: 2 }, // Other with ext + { uri: other1Uri, line: 3 }, // Other without ext + { uri: other1Uri, line: 4 }, // Other relative link with ext + { uri: other1Uri, line: 5 }, // Other relative link without ext + ); + }); + + test('Should find references from link across files when triggered on link without file extension', async () => { + const docUri = workspacePath('doc.md'); + const other1Uri = workspacePath('sub', 'other.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `[with ext](./sub/other#header)`, + `[without ext](./sub/other.md#header)`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 23), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(other1Uri, joinLines( + `pre`, + `# header`, + `post`, + )), + ])); + + assertReferencesEqual(refs!, + { uri: other1Uri, line: 1 }, // Header definition + { uri: docUri, line: 0 }, + { uri: docUri, line: 1 }, + ); + }); + + test('Should include header references when triggered on file link', async () => { + const docUri = workspacePath('doc.md'); + const otherUri = workspacePath('sub', 'other.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `[with ext](./sub/other)`, + `[with ext](./sub/other#header)`, + `[without ext](./sub/other.md#no-such-header)`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 15), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(otherUri, joinLines( + `pre`, + `# header`, // Definition should not be included since we triggered on a file link + `post`, + )), + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 1 }, + { uri: docUri, line: 2 }, + ); + }); + + test('Should not include refs from other file to own header', async () => { + const docUri = workspacePath('doc.md'); + const otherUri = workspacePath('sub', 'other.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `[other](./sub/other)`, // trigger here + )); + + const refs = await getReferences(doc, new vscode.Position(0, 15), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(otherUri, joinLines( + `# header`, // Definition should not be included since we triggered on a file link + `[text](#header)`, // Ref should not be included since it is to own file + )), + ])); + + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + ); + }); + + test('Should find explicit references to own file ', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[bare](doc.md)`, // trigger here + `[rel](./doc.md)`, + `[abs](/doc.md)`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, + { uri, line: 1 }, + { uri, line: 2 }, + ); + }); + + test('Should support finding references to http uri', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[1](http://example.com)`, + `[no](https://example.com)`, + `[2](http://example.com)`, + `[3]: http://example.com`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 13), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, + { uri, line: 2 }, + { uri, line: 3 }, + ); + }); + + test('Should consider authority, scheme and paths when finding references to http uri', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[1](http://example.com/cat)`, + `[2](http://example.com)`, + `[3](http://example.com/dog)`, + `[4](http://example.com/cat/looong)`, + `[5](http://example.com/cat)`, + `[6](http://other.com/cat)`, + `[7](https://example.com/cat)`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 13), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, + { uri, line: 4 }, + ); + }); + + test('Should support finding references to http uri across files', async () => { + const uri1 = workspacePath('doc.md'); + const uri2 = workspacePath('doc2.md'); + const doc = new InMemoryDocument(uri1, joinLines( + `[1](http://example.com)`, + `[3]: http://example.com`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 13), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(uri2, joinLines( + `[other](http://example.com)`, + )) + ])); + assertReferencesEqual(refs!, + { uri: uri1, line: 0 }, + { uri: uri1, line: 1 }, + { uri: uri2, line: 0 }, + ); + }); + + test('Should support finding references to autolinked http links', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[1](http://example.com)`, + ``, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 13), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri, line: 0 }, + { uri, line: 1 }, + ); + }); + + test('Should distinguish between references to file and to header within file', async () => { + const docUri = workspacePath('doc.md'); + const other1Uri = workspacePath('sub', 'other.md'); + + const doc = new InMemoryDocument(docUri, joinLines( + `# abc`, + ``, + `[link 1](#abc)`, + )); + const otherDoc = new InMemoryDocument(other1Uri, joinLines( + `[link](/doc.md#abc)`, + `[link no text](/doc#abc)`, + )); + const workspaceContents = new InMemoryWorkspaceMarkdownDocuments([ + doc, + otherDoc, + ]); + { + // Check refs to header fragment + const headerRefs = await getReferences(otherDoc, new vscode.Position(0, 16), workspaceContents); + assertReferencesEqual(headerRefs!, + { uri: docUri, line: 0 }, // Header definition + { uri: docUri, line: 2 }, + { uri: other1Uri, line: 0 }, + { uri: other1Uri, line: 1 }, + ); + } + { + // Check refs to file itself from link with ext + const fileRefs = await getReferences(otherDoc, new vscode.Position(0, 9), workspaceContents); + assertReferencesEqual(fileRefs!, + { uri: other1Uri, line: 0, endCharacter: 14 }, + { uri: other1Uri, line: 1, endCharacter: 19 }, + ); + } + { + // Check refs to file itself from link without ext + const fileRefs = await getReferences(otherDoc, new vscode.Position(1, 17), workspaceContents); + assertReferencesEqual(fileRefs!, + { uri: other1Uri, line: 0 }, + { uri: other1Uri, line: 1 }, + ); + } + }); + + test('Should support finding references to unknown file', async () => { + const uri1 = workspacePath('doc1.md'); + const doc1 = new InMemoryDocument(uri1, joinLines( + `![img](/images/more/image.png)`, + ``, + `[ref]: /images/more/image.png`, + )); + + const uri2 = workspacePath('sub', 'doc2.md'); + const doc2 = new InMemoryDocument(uri2, joinLines( + `![img](/images/more/image.png)`, + )); + + + const refs = await getReferences(doc1, new vscode.Position(0, 10), new InMemoryWorkspaceMarkdownDocuments([doc1, doc2])); + assertReferencesEqual(refs!, + { uri: uri1, line: 0 }, + { uri: uri1, line: 2 }, + { uri: uri2, line: 0 }, + ); + }); + + suite('Reference links', () => { + test('Should find reference links within file from link', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[link 1][abc]`, // trigger here + ``, + `[abc]: https://example.com`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 2 }, + ); + }); + + test('Should find reference links using shorthand', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[ref]`, // trigger 1 + ``, + `[yes][ref]`, // trigger 2 + ``, + `[ref]: /Hello.md` // trigger 3 + )); + + { + const refs = await getReferences(doc, new vscode.Position(0, 2), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 2 }, + { uri: docUri, line: 4 }, + ); + } + { + const refs = await getReferences(doc, new vscode.Position(2, 7), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 2 }, + { uri: docUri, line: 4 }, + ); + } + { + const refs = await getReferences(doc, new vscode.Position(4, 2), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 2 }, + { uri: docUri, line: 4 }, + ); + } + }); + + test('Should find reference links within file from definition', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[link 1][abc]`, + ``, + `[abc]: https://example.com`, // trigger here + )); + + const refs = await getReferences(doc, new vscode.Position(2, 3), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 2 }, + ); + }); + + test('Should not find reference links across files', async () => { + const docUri = workspacePath('doc.md'); + const doc = new InMemoryDocument(docUri, joinLines( + `[link 1][abc]`, + ``, + `[abc]: https://example.com`, + )); + + const refs = await getReferences(doc, new vscode.Position(0, 12), new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(workspacePath('other.md'), joinLines( + `[link 1][abc]`, + ``, + `[abc]: https://example.com?bad`, + )) + ])); + assertReferencesEqual(refs!, + { uri: docUri, line: 0 }, + { uri: docUri, line: 2 }, + ); + }); + }); +}); diff --git a/extensions/markdown-language-features/src/test/rename.test.ts b/extensions/markdown-language-features/src/test/rename.test.ts new file mode 100644 index 0000000000..d40c6f4abe --- /dev/null +++ b/extensions/markdown-language-features/src/test/rename.test.ts @@ -0,0 +1,616 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdLinkProvider } from '../languageFeatures/documentLinkProvider'; +import { MdReferencesProvider } from '../languageFeatures/references'; +import { MdRenameProvider, MdWorkspaceEdit } from '../languageFeatures/rename'; +import { githubSlugifier } from '../slugify'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { MdWorkspaceContents } from '../workspaceContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; +import { assertRangeEqual, joinLines, noopToken, workspacePath } from './util'; + + +/** + * Get prepare rename info. + */ +function prepareRename(doc: InMemoryDocument, pos: vscode.Position, workspaceContents: MdWorkspaceContents): Promise { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const referencesProvider = new MdReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier); + const renameProvider = new MdRenameProvider(referencesProvider, workspaceContents, githubSlugifier); + return renameProvider.prepareRename(doc, pos, noopToken); +} + +/** + * Get all the edits for the rename. + */ +function getRenameEdits(doc: InMemoryDocument, pos: vscode.Position, newName: string, workspaceContents: MdWorkspaceContents): Promise { + const engine = createNewMarkdownEngine(); + const linkProvider = new MdLinkProvider(engine); + const referencesProvider = new MdReferencesProvider(linkProvider, workspaceContents, engine, githubSlugifier); + const renameProvider = new MdRenameProvider(referencesProvider, workspaceContents, githubSlugifier); + return renameProvider.provideRenameEditsImpl(doc, pos, newName, noopToken); +} + +interface ExpectedTextEdit { + readonly uri: vscode.Uri; + readonly edits: readonly vscode.TextEdit[]; +} + +interface ExpectedFileRename { + readonly originalUri: vscode.Uri; + readonly newUri: vscode.Uri; +} + +function assertEditsEqual(actualEdit: MdWorkspaceEdit, ...expectedEdits: ReadonlyArray) { + // Check file renames + const expectedFileRenames = expectedEdits.filter(expected => 'originalUri' in expected) as ExpectedFileRename[]; + const actualFileRenames = actualEdit.fileRenames ?? []; + assert.strictEqual(actualFileRenames.length, expectedFileRenames.length, `File rename count should match`); + for (let i = 0; i < actualFileRenames.length; ++i) { + const expected = expectedFileRenames[i]; + const actual = actualFileRenames[i]; + assert.strictEqual(actual.from.toString(), expected.originalUri.toString(), `File rename '${i}' should have expected 'from' resource`); + assert.strictEqual(actual.to.toString(), expected.newUri.toString(), `File rename '${i}' should have expected 'to' resource`); + } + + // Check text edits + const actualTextEdits = actualEdit.edit.entries(); + const expectedTextEdits = expectedEdits.filter(expected => 'edits' in expected) as ExpectedTextEdit[]; + assert.strictEqual(actualTextEdits.length, expectedTextEdits.length, `Reference counts should match`); + for (let i = 0; i < actualTextEdits.length; ++i) { + const expected = expectedTextEdits[i]; + const actual = actualTextEdits[i]; + + if ('edits' in expected) { + assert.strictEqual(actual[0].toString(), expected.uri.toString(), `Ref '${i}' has expected document`); + + const actualEditForDoc = actual[1]; + const expectedEditsForDoc = expected.edits; + assert.strictEqual(actualEditForDoc.length, expectedEditsForDoc.length, `Edit counts for '${actual[0]}' should match`); + + for (let g = 0; g < actualEditForDoc.length; ++g) { + assertRangeEqual(actualEditForDoc[g].range, expectedEditsForDoc[g].range, `Edit '${g}' of '${actual[0]}' has expected expected range. Expected range: ${JSON.stringify(actualEditForDoc[g].range)}. Actual range: ${JSON.stringify(expectedEditsForDoc[g].range)}`); + assert.strictEqual(actualEditForDoc[g].newText, expectedEditsForDoc[g].newText, `Edit '${g}' of '${actual[0]}' has expected edits`); + } + } + } +} + +suite('markdown: rename', () => { + + setup(async () => { + // the tests make the assumption that link providers are already registered + await vscode.extensions.getExtension('vscode.markdown-language-features')!.activate(); + }); + + test('Rename on header should not include leading #', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# abc` + )); + + const info = await prepareRename(doc, new vscode.Position(0, 0), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertRangeEqual(info!.range, new vscode.Range(0, 2, 0, 5)); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 0), "New Header", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 2, 0, 5), 'New Header') + ] + }); + }); + + test('Rename on header should include leading or trailing #s', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### abc ###` + )); + + const info = await prepareRename(doc, new vscode.Position(0, 0), new InMemoryWorkspaceMarkdownDocuments([doc])); + assertRangeEqual(info!.range, new vscode.Range(0, 4, 0, 7)); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 0), "New Header", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 7), 'New Header') + ] + }); + }); + + test('Rename on header should pick up links in doc', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### A b C`, // rename here + `[text](#a-b-c)`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 0), "New Header", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'), + ] + }); + }); + + test('Rename on link should use slug for link', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### A b C`, + `[text](#a-b-c)`, // rename here + )); + + const edit = await getRenameEdits(doc, new vscode.Position(1, 10), "New Header", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'), + ] + }); + }); + + test('Rename on link definition should work', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### A b C`, + `[text](#a-b-c)`, + `[ref]: #a-b-c`// rename here + )); + + const edit = await getRenameEdits(doc, new vscode.Position(2, 10), "New Header", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'), + new vscode.TextEdit(new vscode.Range(2, 8, 2, 13), 'new-header'), + ] + }); + }); + + test('Rename on header should pick up links across files', async () => { + const uri = workspacePath('doc.md'); + const otherUri = workspacePath('other.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### A b C`, // rename here + `[text](#a-b-c)`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 0), "New Header", new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(otherUri, joinLines( + `[text](#a-b-c)`, // Should not find this + `[text](./doc.md#a-b-c)`, // But should find this + `[text](./doc#a-b-c)`, // And this + )) + ])); + assertEditsEqual(edit!, { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'), + ] + }, { + uri: otherUri, edits: [ + new vscode.TextEdit(new vscode.Range(1, 16, 1, 21), 'new-header'), + new vscode.TextEdit(new vscode.Range(2, 13, 2, 18), 'new-header'), + ] + }); + }); + + test('Rename on link should pick up links across files', async () => { + const uri = workspacePath('doc.md'); + const otherUri = workspacePath('other.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### A b C`, + `[text](#a-b-c)`, // rename here + )); + + const edit = await getRenameEdits(doc, new vscode.Position(1, 10), "New Header", new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(otherUri, joinLines( + `[text](#a-b-c)`, // Should not find this + `[text](./doc.md#a-b-c)`, // But should find this + `[text](./doc#a-b-c)`, // And this + )) + ])); + assertEditsEqual(edit!, { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'), + ] + }, { + uri: otherUri, edits: [ + new vscode.TextEdit(new vscode.Range(1, 16, 1, 21), 'new-header'), + new vscode.TextEdit(new vscode.Range(2, 13, 2, 18), 'new-header'), + ] + }); + }); + + test('Rename on link in other file should pick up all refs', async () => { + const uri = workspacePath('doc.md'); + const otherUri = workspacePath('other.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### A b C`, + `[text](#a-b-c)`, + )); + + const otherDoc = new InMemoryDocument(otherUri, joinLines( + `[text](#a-b-c)`, + `[text](./doc.md#a-b-c)`, + `[text](./doc#a-b-c)` + )); + + const expectedEdits = [ + { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 9), 'New Header'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 13), 'new-header'), + ] + }, { + uri: otherUri, edits: [ + new vscode.TextEdit(new vscode.Range(1, 16, 1, 21), 'new-header'), + new vscode.TextEdit(new vscode.Range(2, 13, 2, 18), 'new-header'), + ] + } + ]; + + { + // Rename on header with file extension + const edit = await getRenameEdits(otherDoc, new vscode.Position(1, 17), "New Header", new InMemoryWorkspaceMarkdownDocuments([ + doc, + otherDoc + ])); + assertEditsEqual(edit!, ...expectedEdits); + } + { + // Rename on header without extension + const edit = await getRenameEdits(otherDoc, new vscode.Position(2, 15), "New Header", new InMemoryWorkspaceMarkdownDocuments([ + doc, + otherDoc + ])); + assertEditsEqual(edit!, ...expectedEdits); + } + }); + + test('Rename on reference should rename references and definition', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text][ref]`, // rename here + `[other][ref]`, + ``, + `[ref]: https://example.com`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 8), "new ref", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 10), 'new ref'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 11), 'new ref'), + new vscode.TextEdit(new vscode.Range(3, 1, 3, 4), 'new ref'), + ] + }); + }); + + test('Rename on definition should rename references and definitions', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text][ref]`, + `[other][ref]`, + ``, + `[ref]: https://example.com`, // rename here + )); + + const edit = await getRenameEdits(doc, new vscode.Position(3, 3), "new ref", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 10), 'new ref'), + new vscode.TextEdit(new vscode.Range(1, 8, 1, 11), 'new ref'), + new vscode.TextEdit(new vscode.Range(3, 1, 3, 4), 'new ref'), + ] + }); + }); + + test('Rename on definition entry should rename header and references', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# a B c`, + `[ref text][ref]`, + `[direct](#a-b-c)`, + `[ref]: #a-b-c`, // rename here + )); + + const preparedInfo = await prepareRename(doc, new vscode.Position(3, 10), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.strictEqual(preparedInfo!.placeholder, 'a B c'); + assertRangeEqual(preparedInfo!.range, new vscode.Range(3, 8, 3, 13)); + + const edit = await getRenameEdits(doc, new vscode.Position(3, 10), "x Y z", new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 2, 0, 7), 'x Y z'), + new vscode.TextEdit(new vscode.Range(2, 10, 2, 15), 'x-y-z'), + new vscode.TextEdit(new vscode.Range(3, 8, 3, 13), 'x-y-z'), + ] + }); + }); + + test('Rename should not be supported on link text', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `# Header`, + `[text](#header)`, + )); + + await assert.rejects(prepareRename(doc, new vscode.Position(1, 2), new InMemoryWorkspaceMarkdownDocuments([doc]))); + }); + + test('Path rename should use file path as range', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](./doc.md)`, + `[ref]: ./doc.md`, + )); + + const info = await prepareRename(doc, new vscode.Position(0, 10), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.strictEqual(info!.placeholder, './doc.md'); + assertRangeEqual(info!.range, new vscode.Range(0, 7, 0, 15)); + }); + + test('Path rename\'s range should excludes fragment', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](./doc.md#some-header)`, + `[ref]: ./doc.md#some-header`, + )); + + const info = await prepareRename(doc, new vscode.Position(0, 10), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.strictEqual(info!.placeholder, './doc.md'); + assertRangeEqual(info!.range, new vscode.Range(0, 7, 0, 15)); + }); + + test('Path rename should update file and all refs', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](./doc.md)`, + `[ref]: ./doc.md`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 10), './sub/newDoc.md', new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + originalUri: uri, + newUri: workspacePath('sub', 'newDoc.md'), + }, { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 15), './sub/newDoc.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 15), './sub/newDoc.md'), + ] + }); + }); + + test('Path rename using absolute file path should anchor to workspace root', async () => { + const uri = workspacePath('sub', 'doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](/sub/doc.md)`, + `[ref]: /sub/doc.md`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 10), '/newSub/newDoc.md', new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + originalUri: uri, + newUri: workspacePath('newSub', 'newDoc.md'), + }, { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 18), '/newSub/newDoc.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 18), '/newSub/newDoc.md'), + ] + }); + }); + + test('Path rename should use un-encoded paths as placeholder', async () => { + const uri = workspacePath('sub', 'doc with spaces.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](/sub/doc%20with%20spaces.md)`, + )); + + const info = await prepareRename(doc, new vscode.Position(0, 10), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.strictEqual(info!.placeholder, '/sub/doc with spaces.md'); + }); + + test('Path rename should encode paths', async () => { + const uri = workspacePath('sub', 'doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](/sub/doc.md)`, + `[ref]: /sub/doc.md`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 10), '/NEW sub/new DOC.md', new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + originalUri: uri, + newUri: workspacePath('NEW sub', 'new DOC.md'), + }, { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 18), '/NEW%20sub/new%20DOC.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 18), '/NEW%20sub/new%20DOC.md'), + ] + }); + }); + + test('Path rename should work with unknown files', async () => { + const uri1 = workspacePath('doc1.md'); + const doc1 = new InMemoryDocument(uri1, joinLines( + `![img](/images/more/image.png)`, + ``, + `[ref]: /images/more/image.png`, + )); + + const uri2 = workspacePath('sub', 'doc2.md'); + const doc2 = new InMemoryDocument(uri2, joinLines( + `![img](/images/more/image.png)`, + )); + + const edit = await getRenameEdits(doc1, new vscode.Position(0, 10), '/img/test/new.png', new InMemoryWorkspaceMarkdownDocuments([ + doc1, + doc2 + ])); + assertEditsEqual(edit!, + // Should not have file edits since the files don't exist here + { + uri: uri1, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 29), '/img/test/new.png'), + new vscode.TextEdit(new vscode.Range(2, 7, 2, 29), '/img/test/new.png'), + ] + }, + { + uri: uri2, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 29), '/img/test/new.png'), + ] + }); + }); + + test('Path rename should use .md extension on extension-less link', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `[text](/doc#header)`, + `[ref]: /doc#other`, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(0, 10), '/new File', new InMemoryWorkspaceMarkdownDocuments([doc])); + assertEditsEqual(edit!, { + originalUri: uri, + newUri: workspacePath('new File.md'), // Rename on disk should use file extension + }, { + uri: uri, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 11), '/new%20File'), // Links should continue to use extension-less paths + new vscode.TextEdit(new vscode.Range(1, 7, 1, 11), '/new%20File'), + ] + }); + }); + + // TODO: fails on windows + test.skip('Path rename should use correctly resolved paths across files', async () => { + const uri1 = workspacePath('sub', 'doc.md'); + const doc1 = new InMemoryDocument(uri1, joinLines( + `[text](./doc.md)`, + `[ref]: ./doc.md`, + )); + + const uri2 = workspacePath('doc2.md'); + const doc2 = new InMemoryDocument(uri2, joinLines( + `[text](./sub/doc.md)`, + `[ref]: ./sub/doc.md`, + )); + + const uri3 = workspacePath('sub2', 'doc3.md'); + const doc3 = new InMemoryDocument(uri3, joinLines( + `[text](../sub/doc.md)`, + `[ref]: ../sub/doc.md`, + )); + + const uri4 = workspacePath('sub2', 'doc4.md'); + const doc4 = new InMemoryDocument(uri4, joinLines( + `[text](/sub/doc.md)`, + `[ref]: /sub/doc.md`, + )); + + const edit = await getRenameEdits(doc1, new vscode.Position(0, 10), './new/new-doc.md', new InMemoryWorkspaceMarkdownDocuments([ + doc1, doc2, doc3, doc4, + ])); + assertEditsEqual(edit!, { + originalUri: uri1, + newUri: workspacePath('sub', 'new', 'new-doc.md'), + }, { + uri: uri1, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 15), './new/new-doc.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 15), './new/new-doc.md'), + ] + }, { + uri: uri2, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 19), './sub/new/new-doc.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 19), './sub/new/new-doc.md'), + ] + }, { + uri: uri3, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 20), '../sub/new/new-doc.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 20), '../sub/new/new-doc.md'), + ] + }, { + uri: uri4, edits: [ + new vscode.TextEdit(new vscode.Range(0, 7, 0, 18), '/sub/new/new-doc.md'), + new vscode.TextEdit(new vscode.Range(1, 7, 1, 18), '/sub/new/new-doc.md'), + ] + }); + }); + + test('Path rename should resolve on links without prefix', async () => { + const uri1 = workspacePath('sub', 'doc.md'); + const doc1 = new InMemoryDocument(uri1, joinLines( + `![text](sub2/doc3.md)`, + )); + + const uri2 = workspacePath('doc2.md'); + const doc2 = new InMemoryDocument(uri2, joinLines( + `![text](sub/sub2/doc3.md)`, + )); + + const uri3 = workspacePath('sub', 'sub2', 'doc3.md'); + const doc3 = new InMemoryDocument(uri3, joinLines()); + + const edit = await getRenameEdits(doc1, new vscode.Position(0, 10), 'sub2/cat.md', new InMemoryWorkspaceMarkdownDocuments([ + doc1, doc2, doc3 + ])); + assertEditsEqual(edit!, { + originalUri: workspacePath('sub', 'sub2', 'doc3.md'), + newUri: workspacePath('sub', 'sub2', 'cat.md'), + }, { + uri: uri1, edits: [new vscode.TextEdit(new vscode.Range(0, 8, 0, 20), 'sub2/cat.md')] + }, { + uri: uri2, edits: [new vscode.TextEdit(new vscode.Range(0, 8, 0, 24), 'sub/sub2/cat.md')] + }); + }); + + test('Rename on link should use header text as placeholder', async () => { + const uri = workspacePath('doc.md'); + const doc = new InMemoryDocument(uri, joinLines( + `### a B c ###`, + `[text](#a-b-c)`, + )); + + const info = await prepareRename(doc, new vscode.Position(1, 10), new InMemoryWorkspaceMarkdownDocuments([doc])); + assert.strictEqual(info!.placeholder, 'a B c'); + assertRangeEqual(info!.range, new vscode.Range(1, 8, 1, 13)); + }); + + test('Rename on http uri should work', async () => { + const uri1 = workspacePath('doc.md'); + const uri2 = workspacePath('doc2.md'); + const doc = new InMemoryDocument(uri1, joinLines( + `[1](http://example.com)`, + `[2]: http://example.com`, + ``, + )); + + const edit = await getRenameEdits(doc, new vscode.Position(1, 10), "https://example.com/sub", new InMemoryWorkspaceMarkdownDocuments([ + doc, + new InMemoryDocument(uri2, joinLines( + `[4](http://example.com)`, + )) + ])); + assertEditsEqual(edit!, { + uri: uri1, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 22), 'https://example.com/sub'), + new vscode.TextEdit(new vscode.Range(1, 5, 1, 23), 'https://example.com/sub'), + new vscode.TextEdit(new vscode.Range(2, 1, 2, 19), 'https://example.com/sub'), + ] + }, { + uri: uri2, edits: [ + new vscode.TextEdit(new vscode.Range(0, 4, 0, 22), 'https://example.com/sub'), + ] + }); + }); +}); diff --git a/extensions/markdown-language-features/src/test/smartSelect.test.ts b/extensions/markdown-language-features/src/test/smartSelect.test.ts new file mode 100644 index 0000000000..61800d4371 --- /dev/null +++ b/extensions/markdown-language-features/src/test/smartSelect.test.ts @@ -0,0 +1,726 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import { MdSmartSelect } from '../languageFeatures/smartSelect'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { CURSOR, getCursorPositions, joinLines } from './util'; + +const testFileName = vscode.Uri.file('test.md'); + +suite('markdown.SmartSelect', () => { + test('Smart select single word', async () => { + const ranges = await getSelectionRangesForDocument(`Hel${CURSOR}lo`); + assertNestedLineNumbersEqual(ranges![0], [0, 0]); + }); + + test('Smart select multi-line paragraph', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `Many of the core components and extensions to ${CURSOR}VS Code live in their own repositories on GitHub. `, + `For example, the[node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter]`, + `(https://github.com/microsoft/vscode-mono-debug) have their own repositories. For a complete list, please visit the [Related Projects](https://github.com/microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/microsoft/vscode/wiki).` + )); + assertNestedLineNumbersEqual(ranges![0], [0, 2]); + }); + + test('Smart select paragraph', async () => { + const ranges = await getSelectionRangesForDocument(`Many of the core components and extensions to ${CURSOR}VS Code live in their own repositories on GitHub. For example, the [node debug adapter](https://github.com/microsoft/vscode-node-debug) and the [mono debug adapter](https://github.com/microsoft/vscode-mono-debug) have their own repositories. For a complete list, please visit the [Related Projects](https://github.com/microsoft/vscode/wiki/Related-Projects) page on our [wiki](https://github.com/microsoft/vscode/wiki).`); + + assertNestedLineNumbersEqual(ranges![0], [0, 0]); + }); + + test('Smart select html block', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `

`, + `${CURSOR}VS Code in action`, + `

`)); + + assertNestedLineNumbersEqual(ranges![0], [0, 2]); + }); + + test('Smart select header on header line', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# Header${CURSOR}`, + `Hello`)); + + assertNestedLineNumbersEqual(ranges![0], [0, 1]); + + }); + + test('Smart select single word w grandparent header on text line', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `## ParentHeader`, + `# Header`, + `${CURSOR}Hello` + )); + + assertNestedLineNumbersEqual(ranges![0], [2, 2], [1, 2]); + }); + + test('Smart select html block w parent header', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# Header`, + `${CURSOR}

`, + `VS Code in action`, + `

`)); + + assertNestedLineNumbersEqual(ranges![0], [1, 1], [1, 3], [0, 3]); + }); + + test('Smart select fenced code block', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `~~~`, + `a${CURSOR}`, + `~~~`)); + + assertNestedLineNumbersEqual(ranges![0], [0, 2]); + }); + + test('Smart select list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `- item 1`, + `- ${CURSOR}item 2`, + `- item 3`, + `- item 4`)); + assertNestedLineNumbersEqual(ranges![0], [1, 1], [0, 3]); + }); + + test('Smart select list with fenced code block', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `- item 1`, + `- ~~~`, + ` ${CURSOR}a`, + ` ~~~`, + `- item 3`, + `- item 4`)); + + assertNestedLineNumbersEqual(ranges![0], [1, 3], [0, 5]); + }); + + test('Smart select multi cursor', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `- ${CURSOR}item 1`, + `- ~~~`, + ` a`, + ` ~~~`, + `- ${CURSOR}item 3`, + `- item 4`)); + + assertNestedLineNumbersEqual(ranges![0], [0, 0], [0, 5]); + assertNestedLineNumbersEqual(ranges![1], [4, 4], [0, 5]); + }); + + test('Smart select nested block quotes', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `> item 1`, + `> item 2`, + `>> ${CURSOR}item 3`, + `>> item 4`)); + assertNestedLineNumbersEqual(ranges![0], [2, 2], [2, 3], [0, 3]); + }); + + test('Smart select multi nested block quotes', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `> item 1`, + `>> item 2`, + `>>> ${CURSOR}item 3`, + `>>>> item 4`)); + assertNestedLineNumbersEqual(ranges![0], [2, 2], [2, 3], [1, 3], [0, 3]); + }); + + test('Smart select subheader content', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + `content 1`, + `## sub header 1`, + `${CURSOR}content 2`, + `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [3, 3], [2, 3], [1, 3], [0, 3]); + }); + + test('Smart select subheader line', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + `content 1`, + `## sub header 1${CURSOR}`, + `content 2`, + `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [2, 3], [1, 3], [0, 3]); + }); + + test('Smart select blank line', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + `content 1`, + `${CURSOR} `, + `content 2`, + `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [1, 3], [0, 3]); + }); + + test('Smart select line between paragraphs', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `paragraph 1`, + `${CURSOR}`, + `paragraph 2`)); + + assertNestedLineNumbersEqual(ranges![0], [0, 2]); + }); + + test('Smart select empty document', async () => { + const ranges = await getSelectionRangesForDocument(``, [new vscode.Position(0, 0)]); + assert.strictEqual(ranges!.length, 0); + }); + + test('Smart select fenced code block then list then subheader content then subheader then header content then header', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + /* 00 */ `# main header 1`, + /* 01 */ `content 1`, + /* 02 */ `## sub header 1`, + /* 03 */ `- item 1`, + /* 04 */ `- ~~~`, + /* 05 */ ` ${CURSOR}a`, + /* 06 */ ` ~~~`, + /* 07 */ `- item 3`, + /* 08 */ `- item 4`, + /* 09 */ ``, + /* 10 */ `more content`, + /* 11 */ `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [4, 6], [3, 8], [3, 10], [2, 10], [1, 10], [0, 10]); + }); + + test('Smart select list with one element without selecting child subheader', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + /* 00 */ `# main header 1`, + /* 01 */ ``, + /* 02 */ `- list ${CURSOR}`, + /* 03 */ ``, + /* 04 */ `## sub header`, + /* 05 */ ``, + /* 06 */ `content 2`, + /* 07 */ `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [2, 2], [1, 3], [1, 6], [0, 6]); + }); + + test('Smart select content under header then subheaders and their content', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main ${CURSOR}header 1`, + ``, + `- list`, + `paragraph`, + `## sub header`, + ``, + `content 2`, + `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [0, 3], [0, 6]); + }); + + test('Smart select last blockquote element under header then subheaders and their content', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `> block`, + `> block`, + `>> block`, + `>> ${CURSOR}block`, + ``, + `paragraph`, + `## sub header`, + ``, + `content 2`, + `# main header 2`)); + + assertNestedLineNumbersEqual(ranges![0], [5, 5], [4, 5], [2, 5], [1, 7], [1, 10], [0, 10]); + }); + + test('Smart select content of subheader then subheader then content of main header then main header', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `> block`, + `> block`, + `>> block`, + `>> block`, + ``, + `paragraph`, + `## sub header`, + ``, + ``, + `${CURSOR}`, + ``, + `### main header 2`, + `- content 2`, + `- content 2`, + `- content 2`, + `content 2`)); + + assertNestedLineNumbersEqual(ranges![0], [11, 11], [9, 12], [9, 17], [8, 17], [1, 17], [0, 17]); + }); + + test('Smart select last line content of subheader then subheader then content of main header then main header', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `> block`, + `> block`, + `>> block`, + `>> block`, + ``, + `paragraph`, + `## sub header`, + ``, + ``, + ``, + ``, + `### main header 2`, + `- content 2`, + `- content 2`, + `- content 2`, + `- ${CURSOR}content 2`)); + + assertNestedLineNumbersEqual(ranges![0], [17, 17], [14, 17], [13, 17], [9, 17], [8, 17], [1, 17], [0, 17]); + }); + + test('Smart select last line content after content of subheader then subheader then content of main header then main header', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `> block`, + `> block`, + `>> block`, + `>> block`, + ``, + `paragraph`, + `## sub header`, + ``, + ``, + ``, + ``, + `### main header 2`, + `- content 2`, + `- content 2`, + `- content 2`, + `- content 2${CURSOR}`)); + + assertNestedLineNumbersEqual(ranges![0], [17, 17], [14, 17], [13, 17], [9, 17], [8, 17], [1, 17], [0, 17]); + }); + + test('Smart select fenced code block then list then rest of content', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `> block`, + `> block`, + `>> block`, + `>> block`, + ``, + `- paragraph`, + `- ~~~`, + ` my`, + ` ${CURSOR}code`, + ` goes here`, + ` ~~~`, + `- content`, + `- content 2`, + `- content 2`, + `- content 2`, + `- content 2`)); + + assertNestedLineNumbersEqual(ranges![0], [9, 11], [8, 12], [8, 12], [7, 17], [1, 17], [0, 17]); + }); + + test('Smart select fenced code block then list then rest of content on fenced line', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `> block`, + `> block`, + `>> block`, + `>> block`, + ``, + `- paragraph`, + `- ~~~${CURSOR}`, + ` my`, + ` code`, + ` goes here`, + ` ~~~`, + `- content`, + `- content 2`, + `- content 2`, + `- content 2`, + `- content 2`)); + + assertNestedLineNumbersEqual(ranges![0], [8, 12], [7, 17], [1, 17], [0, 17]); + }); + + test('Smart select without multiple ranges', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + ``, + `- ${CURSOR}paragraph`, + `- content`)); + + assertNestedLineNumbersEqual(ranges![0], [3, 3], [3, 4], [1, 4], [0, 4]); + }); + + test('Smart select on second level of a list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `* level 0`, + ` * level 1`, + ` * level 1`, + ` * level 2`, + ` * level 1`, + ` * level ${CURSOR}1`, + `* level 0`)); + + assertNestedLineNumbersEqual(ranges![0], [5, 5], [1, 5], [0, 5], [0, 6]); + }); + + test('Smart select on third level of a list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `* level 0`, + ` * level 1`, + ` * level 1`, + ` * level ${CURSOR}2`, + ` * level 2`, + ` * level 1`, + ` * level 1`, + `* level 0`)); + assertNestedLineNumbersEqual(ranges![0], [3, 3], [3, 4], [2, 4], [1, 6], [0, 6], [0, 7]); + }); + + test('Smart select level 2 then level 1', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `* level 1`, + ` * level ${CURSOR}2`, + ` * level 2`, + `* level 1`)); + assertNestedLineNumbersEqual(ranges![0], [1, 1], [1, 2], [0, 2], [0, 3]); + }); + + test('Smart select last list item', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `- level 1`, + `- level 2`, + `- level 2`, + `- level ${CURSOR}1`)); + assertNestedLineNumbersEqual(ranges![0], [3, 3], [0, 3]); + }); + + test('Smart select without multiple ranges', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + ``, + `- ${CURSOR}paragraph`, + `- content`)); + + assertNestedLineNumbersEqual(ranges![0], [3, 3], [3, 4], [1, 4], [0, 4]); + }); + + test('Smart select on second level of a list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `* level 0`, + ` * level 1`, + ` * level 1`, + ` * level 2`, + ` * level 1`, + ` * level ${CURSOR}1`, + `* level 0`)); + + assertNestedLineNumbersEqual(ranges![0], [5, 5], [1, 5], [0, 5], [0, 6]); + }); + + test('Smart select on third level of a list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `* level 0`, + ` * level 1`, + ` * level 1`, + ` * level ${CURSOR}2`, + ` * level 2`, + ` * level 1`, + ` * level 1`, + `* level 0`)); + assertNestedLineNumbersEqual(ranges![0], [3, 3], [3, 4], [2, 4], [1, 6], [0, 6], [0, 7]); + }); + + test('Smart select level 2 then level 1', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `* level 1`, + ` * level ${CURSOR}2`, + ` * level 2`, + `* level 1`)); + assertNestedLineNumbersEqual(ranges![0], [1, 1], [1, 2], [0, 2], [0, 3]); + }); + + test('Smart select bold', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `stuff here **new${CURSOR}item** and here` + )); + assertNestedRangesEqual(ranges![0], [0, 13, 0, 30], [0, 11, 0, 32], [0, 0, 0, 41]); + }); + + test('Smart select link', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `stuff here [text](https${CURSOR}://google.com) and here` + )); + assertNestedRangesEqual(ranges![0], [0, 18, 0, 46], [0, 17, 0, 47], [0, 11, 0, 47], [0, 0, 0, 56]); + }); + + test('Smart select brackets', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `stuff here [te${CURSOR}xt](https://google.com) and here` + )); + assertNestedRangesEqual(ranges![0], [0, 12, 0, 26], [0, 11, 0, 27], [0, 11, 0, 47], [0, 0, 0, 56]); + }); + + test('Smart select brackets under header in list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `- list`, + `paragraph`, + `## sub header`, + `- list`, + `- stuff here [te${CURSOR}xt](https://google.com) and here`, + `- list` + )); + assertNestedRangesEqual(ranges![0], [6, 14, 6, 28], [6, 13, 6, 29], [6, 13, 6, 49], [6, 0, 6, 58], [5, 0, 7, 6], [4, 0, 7, 6], [1, 0, 7, 6], [0, 0, 7, 6]); + }); + + test('Smart select link under header in list', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `- list`, + `paragraph`, + `## sub header`, + `- list`, + `- stuff here [text](${CURSOR}https://google.com) and here`, + `- list` + )); + assertNestedRangesEqual(ranges![0], [6, 20, 6, 48], [6, 19, 6, 49], [6, 13, 6, 49], [6, 0, 6, 58], [5, 0, 7, 6], [4, 0, 7, 6], [1, 0, 7, 6], [0, 0, 7, 6]); + }); + + test('Smart select bold within list where multiple bold elements exists', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `# main header 1`, + ``, + `- list`, + `paragraph`, + `## sub header`, + `- list`, + `- stuff here [text] **${CURSOR}items in here** and **here**`, + `- list` + )); + assertNestedRangesEqual(ranges![0], [6, 22, 6, 45], [6, 20, 6, 47], [6, 0, 6, 60], [5, 0, 7, 6], [4, 0, 7, 6], [1, 0, 7, 6], [0, 0, 7, 6]); + }); + + test('Smart select link in paragraph with multiple links', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `This[extension](https://marketplace.visualstudio.com/items?itemName=meganrogge.template-string-converter) addresses this [requ${CURSOR}est](https://github.com/microsoft/vscode/issues/56704) to convert Javascript/Typescript quotes to backticks when has been entered within a string.` + )); + assertNestedRangesEqual(ranges![0], [0, 123, 0, 140], [0, 122, 0, 141], [0, 122, 0, 191], [0, 0, 0, 283]); + }); + + test('Smart select bold link', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `**[extens${CURSOR}ion](https://google.com)**` + )); + assertNestedRangesEqual(ranges![0], [0, 3, 0, 22], [0, 2, 0, 23], [0, 2, 0, 43], [0, 2, 0, 43], [0, 0, 0, 45], [0, 0, 0, 45]); + }); + + test('Smart select inline code block', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `[\`code ${CURSOR} link\`]` + )); + assertNestedRangesEqual(ranges![0], [0, 2, 0, 22], [0, 1, 0, 23], [0, 0, 0, 24]); + }); + + test('Smart select link with inline code block text', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `[\`code ${CURSOR} link\`](http://example.com)` + )); + assertNestedRangesEqual(ranges![0], [0, 2, 0, 22], [0, 1, 0, 23], [0, 1, 0, 23], [0, 0, 0, 24], [0, 0, 0, 44], [0, 0, 0, 44]); + }); + + test('Smart select italic', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `*some nice ${CURSOR}text*` + )); + assertNestedRangesEqual(ranges![0], [0, 1, 0, 25], [0, 0, 0, 26], [0, 0, 0, 26]); + }); + + test('Smart select italic link', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `*[extens${CURSOR}ion](https://google.com)*` + )); + assertNestedRangesEqual(ranges![0], [0, 2, 0, 21], [0, 1, 0, 22], [0, 1, 0, 42], [0, 1, 0, 42], [0, 0, 0, 43], [0, 0, 0, 43]); + }); + + test('Smart select italic on end', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `*word1 word2 word3${CURSOR}*` + )); + assertNestedRangesEqual(ranges![0], [0, 1, 0, 28], [0, 0, 0, 29], [0, 0, 0, 29]); + }); + + test('Smart select italic then bold', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `outer text **bold words *italic ${CURSOR} words* bold words** outer text` + )); + assertNestedRangesEqual(ranges![0], [0, 25, 0, 48], [0, 24, 0, 49], [0, 13, 0, 60], [0, 11, 0, 62], [0, 0, 0, 73]); + }); + + test('Smart select bold then italic', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `outer text *italic words **bold ${CURSOR} words** italic words* outer text` + )); + assertNestedRangesEqual(ranges![0], [0, 27, 0, 48], [0, 25, 0, 50], [0, 12, 0, 63], [0, 11, 0, 64], [0, 0, 0, 75]); + }); + + test('Third level header from release notes', async () => { + const ranges = await getSelectionRangesForDocument( + joinLines( + `---`, + `Order: 60`, + `TOCTitle: October 2020`, + `PageTitle: Visual Studio Code October 2020`, + `MetaDescription: Learn what is new in the Visual Studio Code October 2020 Release (1.51)`, + `MetaSocialImage: 1_51/release-highlights.png`, + `Date: 2020-11-6`, + `DownloadVersion: 1.51.1`, + `---`, + `# October 2020 (version 1.51)`, + ``, + `**Update 1.51.1**: The update addresses these [issues](https://github.com/microsoft/vscode/issues?q=is%3Aissue+milestone%3A%22October+2020+Recovery%22+is%3Aclosed+).`, + ``, + ``, + ``, + `---`, + ``, + `Welcome to the October 2020 release of Visual Studio Code. As announced in the [October iteration plan](https://github.com/microsoft/vscode/issues/108473), we focused on housekeeping GitHub issues and pull requests as documented in our issue grooming guide.`, + ``, + `We also worked with our partners at GitHub on GitHub Codespaces, which ended up being more involved than originally anticipated. To that end, we'll continue working on housekeeping for part of the November iteration.`, + ``, + `During this housekeeping milestone, we also addressed several feature requests and community [pull requests](#thank-you). Read on to learn about new features and settings.`, + ``, + `## Workbench`, + ``, + `### More prominent pinned tabs`, + ``, + `${CURSOR}Pinned tabs will now always show their pin icon, even while inactive, to make them easier to identify. If an editor is both pinned and contains unsaved changes, the icon reflects both states.`, + ``, + `![Inactive pinned tabs showing pin icons](images/1_51/pinned-tabs.png)` + ) + ); + assertNestedRangesEqual(ranges![0], [27, 0, 27, 201], [26, 0, 29, 70], [25, 0, 29, 70], [24, 0, 29, 70], [23, 0, 29, 70], [10, 0, 29, 70], [9, 0, 29, 70]); + }); + +}); + + +function assertNestedLineNumbersEqual(range: vscode.SelectionRange, ...expectedRanges: [number, number][]) { + const lineage = getLineage(range); + assert.strictEqual(lineage.length, expectedRanges.length, `expected depth: ${expectedRanges.length}, but was ${lineage.length} ${getValues(lineage)}`); + for (let i = 0; i < lineage.length; i++) { + assertLineNumbersEqual(lineage[i], expectedRanges[i][0], expectedRanges[i][1], `parent at a depth of ${i}`); + } +} + +function assertNestedRangesEqual(range: vscode.SelectionRange, ...expectedRanges: [number, number, number, number][]) { + const lineage = getLineage(range); + assert.strictEqual(lineage.length, expectedRanges.length, `expected depth: ${expectedRanges.length}, but was ${lineage.length} ${getValues(lineage)}`); + for (let i = 0; i < lineage.length; i++) { + assertLineNumbersEqual(lineage[i], expectedRanges[i][0], expectedRanges[i][2], `parent at a depth of ${i}`); + assert(lineage[i].range.start.character === expectedRanges[i][1], `parent at a depth of ${i} on start char`); + assert(lineage[i].range.end.character === expectedRanges[i][3], `parent at a depth of ${i} on end char`); + } +} + +function getLineage(range: vscode.SelectionRange): vscode.SelectionRange[] { + const result: vscode.SelectionRange[] = []; + let currentRange: vscode.SelectionRange | undefined = range; + while (currentRange) { + result.push(currentRange); + currentRange = currentRange.parent; + } + return result; +} + +function getValues(ranges: vscode.SelectionRange[]): string[] { + return ranges.map(range => { + return range.range.start.line + ' ' + range.range.start.character + ' ' + range.range.end.line + ' ' + range.range.end.character; + }); +} + +function assertLineNumbersEqual(selectionRange: vscode.SelectionRange, startLine: number, endLine: number, message: string) { + assert.strictEqual(selectionRange.range.start.line, startLine, `failed on start line ${message}`); + assert.strictEqual(selectionRange.range.end.line, endLine, `failed on end line ${message}`); +} + +function getSelectionRangesForDocument(contents: string, pos?: vscode.Position[]): Promise { + const doc = new InMemoryDocument(testFileName, contents); + const provider = new MdSmartSelect(createNewMarkdownEngine()); + const positions = pos ? pos : getCursorPositions(contents, doc); + return provider.provideSelectionRanges(doc, positions, new vscode.CancellationTokenSource().token); +} diff --git a/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts b/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts new file mode 100644 index 0000000000..6e8029061e --- /dev/null +++ b/extensions/markdown-language-features/src/test/tableOfContentsProvider.test.ts @@ -0,0 +1,130 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { TableOfContents } from '../tableOfContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryDocument } from '../util/inMemoryDocument'; + + +const testFileName = vscode.Uri.file('test.md'); + +suite('markdown.TableOfContentsProvider', () => { + test('Lookup should not return anything for empty document', async () => { + const doc = new InMemoryDocument(testFileName, ''); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual(provider.lookup(''), undefined); + assert.strictEqual(provider.lookup('foo'), undefined); + }); + + test('Lookup should not return anything for document with no headers', async () => { + const doc = new InMemoryDocument(testFileName, 'a *b*\nc'); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual(provider.lookup(''), undefined); + assert.strictEqual(provider.lookup('foo'), undefined); + assert.strictEqual(provider.lookup('a'), undefined); + assert.strictEqual(provider.lookup('b'), undefined); + }); + + test('Lookup should return basic #header', async () => { + const doc = new InMemoryDocument(testFileName, `# a\nx\n# c`); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + { + const entry = provider.lookup('a'); + assert.ok(entry); + assert.strictEqual(entry!.line, 0); + } + { + assert.strictEqual(provider.lookup('x'), undefined); + } + { + const entry = provider.lookup('c'); + assert.ok(entry); + assert.strictEqual(entry!.line, 2); + } + }); + + test('Lookups should be case in-sensitive', async () => { + const doc = new InMemoryDocument(testFileName, `# fOo\n`); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual((provider.lookup('fOo'))!.line, 0); + assert.strictEqual((provider.lookup('foo'))!.line, 0); + assert.strictEqual((provider.lookup('FOO'))!.line, 0); + }); + + test('Lookups should ignore leading and trailing white-space, and collapse internal whitespace', async () => { + const doc = new InMemoryDocument(testFileName, `# f o o \n`); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual((provider.lookup('f o o'))!.line, 0); + assert.strictEqual((provider.lookup(' f o o'))!.line, 0); + assert.strictEqual((provider.lookup(' f o o '))!.line, 0); + assert.strictEqual((provider.lookup('f o o'))!.line, 0); + assert.strictEqual((provider.lookup('f o o'))!.line, 0); + + assert.strictEqual(provider.lookup('f'), undefined); + assert.strictEqual(provider.lookup('foo'), undefined); + assert.strictEqual(provider.lookup('fo o'), undefined); + }); + + test('should handle special characters #44779', async () => { + const doc = new InMemoryDocument(testFileName, `# Indentação\n`); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual((provider.lookup('indentação'))!.line, 0); + }); + + test('should handle special characters 2, #48482', async () => { + const doc = new InMemoryDocument(testFileName, `# Инструкция - Делай Раз, Делай Два\n`); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual((provider.lookup('инструкция---делай-раз-делай-два'))!.line, 0); + }); + + test('should handle special characters 3, #37079', async () => { + const doc = new InMemoryDocument(testFileName, `## Header 2 +### Header 3 +## Заголовок 2 +### Заголовок 3 +### Заголовок Header 3 +## Заголовок`); + + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + assert.strictEqual((provider.lookup('header-2'))!.line, 0); + assert.strictEqual((provider.lookup('header-3'))!.line, 1); + assert.strictEqual((provider.lookup('Заголовок-2'))!.line, 2); + assert.strictEqual((provider.lookup('Заголовок-3'))!.line, 3); + assert.strictEqual((provider.lookup('Заголовок-header-3'))!.line, 4); + assert.strictEqual((provider.lookup('Заголовок'))!.line, 5); + }); + + test('Lookup should support suffixes for repeated headers', async () => { + const doc = new InMemoryDocument(testFileName, `# a\n# a\n## a`); + const provider = await TableOfContents.create(createNewMarkdownEngine(), doc); + + { + const entry = provider.lookup('a'); + assert.ok(entry); + assert.strictEqual(entry!.line, 0); + } + { + const entry = provider.lookup('a-1'); + assert.ok(entry); + assert.strictEqual(entry!.line, 1); + } + { + const entry = provider.lookup('a-2'); + assert.ok(entry); + assert.strictEqual(entry!.line, 2); + } + }); +}); diff --git a/extensions/markdown-language-features/src/test/util.ts b/extensions/markdown-language-features/src/test/util.ts index 433e7ab32e..9d7d4f6f6f 100644 --- a/extensions/markdown-language-features/src/test/util.ts +++ b/extensions/markdown-language-features/src/test/util.ts @@ -5,11 +5,33 @@ import * as assert from 'assert'; import * as os from 'os'; import * as vscode from 'vscode'; -import { DisposableStore } from '../util/dispose'; +import { InMemoryDocument } from '../util/inMemoryDocument'; export const joinLines = (...args: string[]) => args.join(os.platform() === 'win32' ? '\r\n' : '\n'); +export const noopToken = new class implements vscode.CancellationToken { + _onCancellationRequestedEmitter = new vscode.EventEmitter(); + onCancellationRequested = this._onCancellationRequestedEmitter.event; + + get isCancellationRequested() { return false; } +}; + +export const CURSOR = '$$CURSOR$$'; + +export function getCursorPositions(contents: string, doc: InMemoryDocument): vscode.Position[] { + let positions: vscode.Position[] = []; + let index = 0; + let wordLength = 0; + while (index !== -1) { + index = contents.indexOf(CURSOR, index + wordLength); + if (index !== -1) { + positions.push(doc.positionAt(index)); + } + wordLength = CURSOR.length; + } + return positions; +} export function workspacePath(...segments: string[]): vscode.Uri { return vscode.Uri.joinPath(vscode.workspace.workspaceFolders![0].uri, ...segments); @@ -21,14 +43,3 @@ export function assertRangeEqual(expected: vscode.Range, actual: vscode.Range, m assert.strictEqual(expected.end.line, actual.end.line, message); assert.strictEqual(expected.end.character, actual.end.character, message); } - -export function withStore(fn: (this: Mocha.Context, store: DisposableStore) => Promise) { - return async function (this: Mocha.Context): Promise { - const store = new DisposableStore(); - try { - return await fn.call(this, store); - } finally { - store.dispose(); - } - }; -} diff --git a/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts b/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts new file mode 100644 index 0000000000..4fe98b6bd3 --- /dev/null +++ b/extensions/markdown-language-features/src/test/workspaceSymbolProvider.test.ts @@ -0,0 +1,103 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import 'mocha'; +import * as vscode from 'vscode'; +import { MdDocumentSymbolProvider } from '../languageFeatures/documentSymbolProvider'; +import { MdWorkspaceSymbolProvider } from '../languageFeatures/workspaceSymbolProvider'; +import { SkinnyTextDocument } from '../workspaceContents'; +import { createNewMarkdownEngine } from './engine'; +import { InMemoryDocument } from '../util/inMemoryDocument'; +import { InMemoryWorkspaceMarkdownDocuments } from './inMemoryWorkspace'; + + +const symbolProvider = new MdDocumentSymbolProvider(createNewMarkdownEngine()); + +suite('markdown.WorkspaceSymbolProvider', () => { + test('Should not return anything for empty workspace', async () => { + const provider = new MdWorkspaceSymbolProvider(symbolProvider, new InMemoryWorkspaceMarkdownDocuments([])); + + assert.deepStrictEqual(await provider.provideWorkspaceSymbols(''), []); + }); + + test('Should return symbols from workspace with one markdown file', async () => { + const testFileName = vscode.Uri.file('test.md'); + + const provider = new MdWorkspaceSymbolProvider(symbolProvider, new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(testFileName, `# header1\nabc\n## header2`) + ])); + + const symbols = await provider.provideWorkspaceSymbols(''); + assert.strictEqual(symbols.length, 2); + assert.strictEqual(symbols[0].name, '# header1'); + assert.strictEqual(symbols[1].name, '## header2'); + }); + + test('Should return all content basic workspace', async () => { + const fileNameCount = 10; + const files: SkinnyTextDocument[] = []; + for (let i = 0; i < fileNameCount; ++i) { + const testFileName = vscode.Uri.file(`test${i}.md`); + files.push(new InMemoryDocument(testFileName, `# common\nabc\n## header${i}`)); + } + + const provider = new MdWorkspaceSymbolProvider(symbolProvider, new InMemoryWorkspaceMarkdownDocuments(files)); + + const symbols = await provider.provideWorkspaceSymbols(''); + assert.strictEqual(symbols.length, fileNameCount * 2); + }); + + test('Should update results when markdown file changes symbols', async () => { + const testFileName = vscode.Uri.file('test.md'); + + const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(testFileName, `# header1`, 1 /* version */) + ]); + + const provider = new MdWorkspaceSymbolProvider(symbolProvider, workspaceFileProvider); + + assert.strictEqual((await provider.provideWorkspaceSymbols('')).length, 1); + + // Update file + workspaceFileProvider.updateDocument(new InMemoryDocument(testFileName, `# new header\nabc\n## header2`, 2 /* version */)); + const newSymbols = await provider.provideWorkspaceSymbols(''); + assert.strictEqual(newSymbols.length, 2); + assert.strictEqual(newSymbols[0].name, '# new header'); + assert.strictEqual(newSymbols[1].name, '## header2'); + }); + + test('Should remove results when file is deleted', async () => { + const testFileName = vscode.Uri.file('test.md'); + + const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(testFileName, `# header1`) + ]); + + const provider = new MdWorkspaceSymbolProvider(symbolProvider, workspaceFileProvider); + assert.strictEqual((await provider.provideWorkspaceSymbols('')).length, 1); + + // delete file + workspaceFileProvider.deleteDocument(testFileName); + const newSymbols = await provider.provideWorkspaceSymbols(''); + assert.strictEqual(newSymbols.length, 0); + }); + + test('Should update results when markdown file is created', async () => { + const testFileName = vscode.Uri.file('test.md'); + + const workspaceFileProvider = new InMemoryWorkspaceMarkdownDocuments([ + new InMemoryDocument(testFileName, `# header1`) + ]); + + const provider = new MdWorkspaceSymbolProvider(symbolProvider, workspaceFileProvider); + assert.strictEqual((await provider.provideWorkspaceSymbols('')).length, 1); + + // Creat file + workspaceFileProvider.createDocument(new InMemoryDocument(vscode.Uri.file('test2.md'), `# new header\nabc\n## header2`)); + const newSymbols = await provider.provideWorkspaceSymbols(''); + assert.strictEqual(newSymbols.length, 3); + }); +}); diff --git a/extensions/markdown-language-features/src/types/textDocument.ts b/extensions/markdown-language-features/src/types/textDocument.ts deleted file mode 100644 index 7c1b74c062..0000000000 --- a/extensions/markdown-language-features/src/types/textDocument.ts +++ /dev/null @@ -1,22 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -/** - * Minimal version of {@link vscode.TextDocument}. - */ -export interface ITextDocument { - readonly uri: vscode.Uri; - readonly version: number; - readonly lineCount: number; - - getText(range?: vscode.Range): string; - positionAt(offset: number): vscode.Position; -} - -export function getLine(doc: ITextDocument, line: number): string { - return doc.getText(new vscode.Range(line, 0, line, Number.MAX_VALUE)).replace(/\r?\n$/, ''); -} diff --git a/extensions/markdown-language-features/src/util/async.ts b/extensions/markdown-language-features/src/util/async.ts index 78c9b9b40e..704fbfdeae 100644 --- a/extensions/markdown-language-features/src/util/async.ts +++ b/extensions/markdown-language-features/src/util/async.ts @@ -25,10 +25,6 @@ export class Delayer { this.task = null; } - dispose() { - this.cancelTimeout(); - } - public trigger(task: ITask, delay: number = this.defaultDelay): Promise { this.task = task; if (delay >= 0) { diff --git a/extensions/markdown-language-features/src/util/cancellation.ts b/extensions/markdown-language-features/src/util/cancellation.ts deleted file mode 100644 index 27f756f49b..0000000000 --- a/extensions/markdown-language-features/src/util/cancellation.ts +++ /dev/null @@ -1,13 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -export const noopToken = new class implements vscode.CancellationToken { - _onCancellationRequestedEmitter = new vscode.EventEmitter(); - onCancellationRequested = this._onCancellationRequestedEmitter.event; - - get isCancellationRequested() { return false; } -}; diff --git a/extensions/markdown-language-features/src/util/dispose.ts b/extensions/markdown-language-features/src/util/dispose.ts index 7526357e2c..43c903ff56 100644 --- a/extensions/markdown-language-features/src/util/dispose.ts +++ b/extensions/markdown-language-features/src/util/dispose.ts @@ -5,36 +5,13 @@ import * as vscode from 'vscode'; -export class MultiDisposeError extends Error { - constructor( - public readonly errors: any[] - ) { - super(`Encountered errors while disposing of store. Errors: [${errors.join(', ')}]`); +export function disposeAll(disposables: vscode.Disposable[]) { + while (disposables.length) { + const item = disposables.pop(); + item?.dispose(); } } -export function disposeAll(disposables: Iterable) { - const errors: any[] = []; - - for (const disposable of disposables) { - try { - disposable.dispose(); - } catch (e) { - errors.push(e); - } - } - - if (errors.length === 1) { - throw errors[0]; - } else if (errors.length > 1) { - throw new MultiDisposeError(errors); - } -} - -export interface IDisposable { - dispose(): void; -} - export abstract class Disposable { private _isDisposed = false; @@ -48,7 +25,7 @@ export abstract class Disposable { disposeAll(this._disposables); } - protected _register(value: T): T { + protected _register(value: T): T { if (this._isDisposed) { value.dispose(); } else { @@ -61,22 +38,3 @@ export abstract class Disposable { return this._isDisposed; } } - -export class DisposableStore extends Disposable { - private readonly items = new Set(); - - public override dispose() { - super.dispose(); - disposeAll(this.items); - this.items.clear(); - } - - public add(item: T): T { - if (this.isDisposed) { - console.warn('Adding to disposed store. Item will be leaked'); - } - - this.items.add(item); - return item; - } -} diff --git a/extensions/markdown-language-features/src/util/dom.ts b/extensions/markdown-language-features/src/util/dom.ts deleted file mode 100644 index 0435f52b71..0000000000 --- a/extensions/markdown-language-features/src/util/dom.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; - -export function escapeAttribute(value: string | vscode.Uri): string { - return value.toString().replace(/"/g, '"'); -} - -export function getNonce() { - let text = ''; - const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - for (let i = 0; i < 64; i++) { - text += possible.charAt(Math.floor(Math.random() * possible.length)); - } - return text; -} diff --git a/extensions/markdown-language-features/src/util/file.ts b/extensions/markdown-language-features/src/util/file.ts index 97082955e7..7ce14bffe0 100644 --- a/extensions/markdown-language-features/src/util/file.ts +++ b/extensions/markdown-language-features/src/util/file.ts @@ -4,24 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as URI from 'vscode-uri'; - -export const markdownFileExtensions = Object.freeze([ - 'md', - 'mkd', - 'mdwn', - 'mdown', - 'markdown', - 'markdn', - 'mdtxt', - 'mdtext', - 'workbook', -]); export function isMarkdownFile(document: vscode.TextDocument) { return document.languageId === 'markdown'; } - -export function looksLikeMarkdownPath(resolvedHrefPath: vscode.Uri) { - return markdownFileExtensions.includes(URI.Utils.extname(resolvedHrefPath).toLowerCase().replace('.', '')); -} diff --git a/extensions/markdown-language-features/src/util/inMemoryDocument.ts b/extensions/markdown-language-features/src/util/inMemoryDocument.ts index 9e147bb64c..e25038ce46 100644 --- a/extensions/markdown-language-features/src/util/inMemoryDocument.ts +++ b/extensions/markdown-language-features/src/util/inMemoryDocument.ts @@ -5,12 +5,14 @@ import * as vscode from 'vscode'; import { TextDocument } from 'vscode-languageserver-textdocument'; -import { ITextDocument } from '../types/textDocument'; +import { SkinnyTextDocument, SkinnyTextLine } from '../workspaceContents'; -export class InMemoryDocument implements ITextDocument { +export class InMemoryDocument implements SkinnyTextDocument { private readonly _doc: TextDocument; + private lines: SkinnyTextLine[] | undefined; + constructor( public readonly uri: vscode.Uri, contents: string, public readonly version = 0, @@ -23,6 +25,16 @@ export class InMemoryDocument implements ITextDocument { return this._doc.lineCount; } + lineAt(index: any): SkinnyTextLine { + if (!this.lines) { + this.lines = this._doc.getText().split(/\r?\n/).map(text => ({ + text, + get isEmptyOrWhitespace() { return /^\s*$/.test(text); } + })); + } + return this.lines[index]; + } + positionAt(offset: number): vscode.Position { const pos = this._doc.positionAt(offset); return new vscode.Position(pos.line, pos.character); diff --git a/extensions/markdown-language-features/src/util/openDocumentLink.ts b/extensions/markdown-language-features/src/util/openDocumentLink.ts index 4a189feb64..85f7514b43 100644 --- a/extensions/markdown-language-features/src/util/openDocumentLink.ts +++ b/extensions/markdown-language-features/src/util/openDocumentLink.ts @@ -6,9 +6,8 @@ import * as path from 'path'; import * as vscode from 'vscode'; import * as uri from 'vscode-uri'; -import { MdTableOfContentsProvider } from '../tableOfContents'; -import { ITextDocument } from '../types/textDocument'; -import { IMdWorkspace } from '../workspace'; +import { MarkdownEngine } from '../markdownEngine'; +import { TableOfContents } from '../tableOfContents'; import { isMarkdownFile } from './file'; export interface OpenDocumentLinkArgs { @@ -23,7 +22,7 @@ enum OpenMarkdownLinks { } export function resolveDocumentLink(href: string, markdownFile: vscode.Uri): vscode.Uri { - const [hrefPath, fragment] = href.split('#').map(c => decodeURIComponent(c)); + let [hrefPath, fragment] = href.split('#').map(c => decodeURIComponent(c)); if (hrefPath[0] === '/') { // Absolute path. Try to resolve relative to the workspace @@ -38,10 +37,10 @@ export function resolveDocumentLink(href: string, markdownFile: vscode.Uri): vsc return vscode.Uri.joinPath(dirnameUri, hrefPath).with({ fragment }); } -export async function openDocumentLink(tocProvider: MdTableOfContentsProvider, targetResource: vscode.Uri, fromResource: vscode.Uri): Promise { +export async function openDocumentLink(engine: MarkdownEngine, targetResource: vscode.Uri, fromResource: vscode.Uri): Promise { const column = getViewColumn(fromResource); - if (await tryNavigateToFragmentInActiveEditor(tocProvider, targetResource)) { + if (await tryNavigateToFragmentInActiveEditor(engine, targetResource)) { return; } @@ -59,7 +58,7 @@ export async function openDocumentLink(tocProvider: MdTableOfContentsProvider, t try { const stat = await vscode.workspace.fs.stat(dotMdResource); if (stat.type === vscode.FileType.File) { - await tryOpenMdFile(tocProvider, dotMdResource, column); + await tryOpenMdFile(engine, dotMdResource, column); return; } } catch { @@ -70,33 +69,25 @@ export async function openDocumentLink(tocProvider: MdTableOfContentsProvider, t return vscode.commands.executeCommand('revealInExplorer', targetResource); } - await tryOpenMdFile(tocProvider, targetResource, column); + await tryOpenMdFile(engine, targetResource, column); } -async function tryOpenMdFile(tocProvider: MdTableOfContentsProvider, resource: vscode.Uri, column: vscode.ViewColumn): Promise { +async function tryOpenMdFile(engine: MarkdownEngine, resource: vscode.Uri, column: vscode.ViewColumn): Promise { await vscode.commands.executeCommand('vscode.open', resource.with({ fragment: '' }), column); - return tryNavigateToFragmentInActiveEditor(tocProvider, resource); + return tryNavigateToFragmentInActiveEditor(engine, resource); } -async function tryNavigateToFragmentInActiveEditor(tocProvider: MdTableOfContentsProvider, resource: vscode.Uri): Promise { - const notebookEditor = vscode.window.activeNotebookEditor; - if (notebookEditor?.notebook.uri.fsPath === resource.fsPath) { - if (await tryRevealLineInNotebook(tocProvider, notebookEditor, resource.fragment)) { - return true; - } - } - +async function tryNavigateToFragmentInActiveEditor(engine: MarkdownEngine, resource: vscode.Uri): Promise { const activeEditor = vscode.window.activeTextEditor; if (activeEditor?.document.uri.fsPath === resource.fsPath) { if (isMarkdownFile(activeEditor.document)) { - if (await tryRevealLineUsingTocFragment(tocProvider, activeEditor, resource.fragment)) { + if (await tryRevealLineUsingTocFragment(engine, activeEditor, resource.fragment)) { return true; } } tryRevealLineUsingLineFragment(activeEditor, resource.fragment); return true; } - return false; } @@ -112,26 +103,8 @@ function getViewColumn(resource: vscode.Uri): vscode.ViewColumn { } } -async function tryRevealLineInNotebook(tocProvider: MdTableOfContentsProvider, editor: vscode.NotebookEditor, fragment: string): Promise { - const toc = await tocProvider.createForNotebook(editor.notebook); - const entry = toc.lookup(fragment); - if (!entry) { - return false; - } - - const cell = editor.notebook.getCells().find(cell => cell.document.uri.toString() === entry.sectionLocation.uri.toString()); - if (!cell) { - return false; - } - - const range = new vscode.NotebookRange(cell.index, cell.index); - editor.selection = range; - editor.revealRange(range); - return true; -} - -async function tryRevealLineUsingTocFragment(tocProvider: MdTableOfContentsProvider, editor: vscode.TextEditor, fragment: string): Promise { - const toc = await tocProvider.getForDocument(editor.document); +async function tryRevealLineUsingTocFragment(engine: MarkdownEngine, editor: vscode.TextEditor, fragment: string): Promise { + const toc = await TableOfContents.create(engine, editor.document); const entry = toc.lookup(fragment); if (entry) { const lineStart = new vscode.Range(entry.line, 0, entry.line, 0); @@ -156,9 +129,9 @@ function tryRevealLineUsingLineFragment(editor: vscode.TextEditor, fragment: str return false; } -export async function resolveUriToMarkdownFile(workspace: IMdWorkspace, resource: vscode.Uri): Promise { +export async function resolveUriToMarkdownFile(resource: vscode.Uri): Promise { try { - const doc = await workspace.getOrLoadMarkdownDocument(resource); + const doc = await tryResolveUriToMarkdownFile(resource); if (doc) { return doc; } @@ -168,8 +141,21 @@ export async function resolveUriToMarkdownFile(workspace: IMdWorkspace, resource // If no extension, try with `.md` extension if (uri.Utils.extname(resource) === '') { - return workspace.getOrLoadMarkdownDocument(resource.with({ path: resource.path + '.md' })); + return tryResolveUriToMarkdownFile(resource.with({ path: resource.path + '.md' })); } return undefined; } + +async function tryResolveUriToMarkdownFile(resource: vscode.Uri): Promise { + let document: vscode.TextDocument; + try { + document = await vscode.workspace.openTextDocument(resource); + } catch { + return undefined; + } + if (isMarkdownFile(document)) { + return document; + } + return undefined; +} diff --git a/extensions/markdown-language-features/src/util/resourceMap.ts b/extensions/markdown-language-features/src/util/resourceMap.ts deleted file mode 100644 index 749227bad6..0000000000 --- a/extensions/markdown-language-features/src/util/resourceMap.ts +++ /dev/null @@ -1,68 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; - -type ResourceToKey = (uri: vscode.Uri) => string; - -const defaultResourceToKey = (resource: vscode.Uri): string => resource.toString(); - -export class ResourceMap { - - private readonly map = new Map(); - - private readonly toKey: ResourceToKey; - - constructor(toKey: ResourceToKey = defaultResourceToKey) { - this.toKey = toKey; - } - - public set(uri: vscode.Uri, value: T): this { - this.map.set(this.toKey(uri), { uri, value }); - return this; - } - - public get(resource: vscode.Uri): T | undefined { - return this.map.get(this.toKey(resource))?.value; - } - - public has(resource: vscode.Uri): boolean { - return this.map.has(this.toKey(resource)); - } - - public get size(): number { - return this.map.size; - } - - public clear(): void { - this.map.clear(); - } - - public delete(resource: vscode.Uri): boolean { - return this.map.delete(this.toKey(resource)); - } - - public *values(): IterableIterator { - for (const entry of this.map.values()) { - yield entry.value; - } - } - - public *keys(): IterableIterator { - for (const entry of this.map.values()) { - yield entry.uri; - } - } - - public *entries(): IterableIterator<[vscode.Uri, T]> { - for (const entry of this.map.values()) { - yield [entry.uri, entry.value]; - } - } - - public [Symbol.iterator](): IterableIterator<[vscode.Uri, T]> { - return this.entries(); - } -} diff --git a/extensions/markdown-language-features/src/util/schemes.ts b/extensions/markdown-language-features/src/util/schemes.ts index ff99b43f30..830bb7b96d 100644 --- a/extensions/markdown-language-features/src/util/schemes.ts +++ b/extensions/markdown-language-features/src/util/schemes.ts @@ -3,15 +3,44 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export const Schemes = Object.freeze({ - file: 'file', +import * as vscode from 'vscode'; + +export const Schemes = { + http: 'http:', + https: 'https:', + file: 'file:', untitled: 'untitled', - mailto: 'mailto', - vscode: 'vscode', - 'vscode-insiders': 'vscode-insiders', - notebookCell: 'vscode-notebook-cell', -}); + mailto: 'mailto:', + data: 'data:', + vscode: 'vscode:', + 'vscode-insiders': 'vscode-insiders:', +}; + +const knownSchemes = [ + ...Object.values(Schemes), + `${vscode.env.uriScheme}:` +]; + +export function getUriForLinkWithKnownExternalScheme(link: string): vscode.Uri | undefined { + if (knownSchemes.some(knownScheme => isOfScheme(knownScheme, link))) { + return vscode.Uri.parse(link); + } + + return undefined; +} export function isOfScheme(scheme: string, link: string): boolean { - return link.toLowerCase().startsWith(scheme + ':'); + return link.toLowerCase().startsWith(scheme); } + +export const MarkdownFileExtensions: readonly string[] = [ + '.md', + '.mkd', + '.mdwn', + '.mdown', + '.markdown', + '.markdn', + '.mdtxt', + '.mdtext', + '.workbook', +]; diff --git a/extensions/markdown-language-features/src/util/workspaceCache.ts b/extensions/markdown-language-features/src/util/workspaceCache.ts deleted file mode 100644 index 2231c7d109..0000000000 --- a/extensions/markdown-language-features/src/util/workspaceCache.ts +++ /dev/null @@ -1,116 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import { ITextDocument } from '../types/textDocument'; -import { IMdWorkspace } from '../workspace'; -import { Disposable } from './dispose'; -import { Lazy, lazy } from './lazy'; -import { ResourceMap } from './resourceMap'; - -class LazyResourceMap { - private readonly _map = new ResourceMap>>(); - - public has(resource: vscode.Uri): boolean { - return this._map.has(resource); - } - - public get(resource: vscode.Uri): Promise | undefined { - return this._map.get(resource)?.value; - } - - public set(resource: vscode.Uri, value: Lazy>) { - this._map.set(resource, value); - } - - public delete(resource: vscode.Uri) { - this._map.delete(resource); - } - - public entries(): Promise> { - return Promise.all(Array.from(this._map.entries(), async ([key, entry]) => { - return [key, await entry.value] as [vscode.Uri, T]; // {{SQL CARBON EDIT}} lewissanchez - Added strict typing - })); - } -} - -/** - * Cache of information per-document in the workspace. - * - * The values are computed lazily and invalidated when the document changes. - */ -export class MdDocumentInfoCache extends Disposable { - - private readonly _cache = new LazyResourceMap(); - private readonly _loadingDocuments = new ResourceMap>(); - - public constructor( - private readonly workspace: IMdWorkspace, - private readonly getValue: (document: ITextDocument) => Promise, - ) { - super(); - - this._register(this.workspace.onDidChangeMarkdownDocument(doc => this.invalidate(doc))); - this._register(this.workspace.onDidDeleteMarkdownDocument(this.onDidDeleteDocument, this)); - } - - public async get(resource: vscode.Uri): Promise { - let existing = this._cache.get(resource); - if (existing) { - return existing; - } - - const doc = await this.loadDocument(resource); - if (!doc) { - return undefined; - } - - // Check if we have invalidated - existing = this._cache.get(resource); - if (existing) { - return existing; - } - - return this.resetEntry(doc)?.value; - } - - public async getForDocument(document: ITextDocument): Promise { - const existing = this._cache.get(document.uri); - if (existing) { - return existing; - } - return this.resetEntry(document).value; - } - - private loadDocument(resource: vscode.Uri): Promise { - const existing = this._loadingDocuments.get(resource); - if (existing) { - return existing; - } - - const p = this.workspace.getOrLoadMarkdownDocument(resource); - this._loadingDocuments.set(resource, p); - p.finally(() => { - this._loadingDocuments.delete(resource); - }); - return p; - } - - private resetEntry(document: ITextDocument): Lazy> { - const value = lazy(() => this.getValue(document)); - this._cache.set(document.uri, value); - return value; - } - - private invalidate(document: ITextDocument): void { - if (this._cache.has(document.uri)) { - this.resetEntry(document); - } - } - - private onDidDeleteDocument(resource: vscode.Uri) { - this._cache.delete(resource); - } -} diff --git a/extensions/markdown-language-features/src/workspace.ts b/extensions/markdown-language-features/src/workspaceContents.ts similarity index 57% rename from extensions/markdown-language-features/src/workspace.ts rename to extensions/markdown-language-features/src/workspaceContents.ts index a31ea18244..386bd3d98d 100644 --- a/extensions/markdown-language-features/src/workspace.ts +++ b/extensions/markdown-language-features/src/workspaceContents.ts @@ -4,36 +4,48 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { ITextDocument } from './types/textDocument'; import { coalesce } from './util/arrays'; import { Disposable } from './util/dispose'; -import { isMarkdownFile, looksLikeMarkdownPath } from './util/file'; +import { isMarkdownFile } from './util/file'; import { InMemoryDocument } from './util/inMemoryDocument'; import { Limiter } from './util/limiter'; -import { ResourceMap } from './util/resourceMap'; + +/** + * Minimal version of {@link vscode.TextLine}. Used for mocking out in testing. + */ +export interface SkinnyTextLine { + readonly text: string; + readonly isEmptyOrWhitespace: boolean; +} + +/** + * Minimal version of {@link vscode.TextDocument}. Used for mocking out in testing. + */ +export interface SkinnyTextDocument { + readonly uri: vscode.Uri; + readonly version: number; + readonly lineCount: number; + + getText(range?: vscode.Range): string; + lineAt(line: number): SkinnyTextLine; + positionAt(offset: number): vscode.Position; +} /** * Provides set of markdown files in the current workspace. */ -export interface IMdWorkspace { +export interface MdWorkspaceContents { /** * Get list of all known markdown files. */ - getAllMarkdownDocuments(): Promise>; + getAllMarkdownDocuments(): Promise>; - /** - * Check if a document already exists in the workspace contents. - */ - hasMarkdownDocument(resource: vscode.Uri): boolean; - - getOrLoadMarkdownDocument(resource: vscode.Uri): Promise; + getMarkdownDocument(resource: vscode.Uri): Promise; pathExists(resource: vscode.Uri): Promise; - readDirectory(resource: vscode.Uri): Promise<[string, vscode.FileType][]>; - - readonly onDidChangeMarkdownDocument: vscode.Event; - readonly onDidCreateMarkdownDocument: vscode.Event; + readonly onDidChangeMarkdownDocument: vscode.Event; + readonly onDidCreateMarkdownDocument: vscode.Event; readonly onDidDeleteMarkdownDocument: vscode.Event; } @@ -42,16 +54,14 @@ export interface IMdWorkspace { * * This includes both opened text documents and markdown files in the workspace. */ -export class VsCodeMdWorkspace extends Disposable implements IMdWorkspace { +export class VsCodeMdWorkspaceContents extends Disposable implements MdWorkspaceContents { - private readonly _onDidChangeMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); - private readonly _onDidCreateMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); + private readonly _onDidChangeMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); + private readonly _onDidCreateMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); private readonly _onDidDeleteMarkdownDocumentEmitter = this._register(new vscode.EventEmitter()); private _watcher: vscode.FileSystemWatcher | undefined; - private readonly _documentCache = new ResourceMap(); - private readonly utf8Decoder = new TextDecoder('utf-8'); /** @@ -60,19 +70,19 @@ export class VsCodeMdWorkspace extends Disposable implements IMdWorkspace { * * @returns Array of processed .md files. */ - async getAllMarkdownDocuments(): Promise { + async getAllMarkdownDocuments(): Promise { const maxConcurrent = 20; - const foundFiles = new ResourceMap(); - const limiter = new Limiter(maxConcurrent); + const foundFiles = new Set(); + const limiter = new Limiter(maxConcurrent); // Add files on disk const resources = await vscode.workspace.findFiles('**/*.md', '**/node_modules/**'); const onDiskResults = await Promise.all(resources.map(resource => { return limiter.queue(async () => { - const doc = await this.getOrLoadMarkdownDocument(resource); + const doc = await this.getMarkdownDocument(resource); if (doc) { - foundFiles.set(resource); + foundFiles.add(doc.uri.toString()); } return doc; }); @@ -80,7 +90,7 @@ export class VsCodeMdWorkspace extends Disposable implements IMdWorkspace { // Add opened files (such as untitled files) const openTextDocumentResults = await Promise.all(vscode.workspace.textDocuments - .filter(doc => !foundFiles.has(doc.uri) && this.isRelevantMarkdownDocument(doc))); + .filter(doc => !foundFiles.has(doc.uri.toString()) && isMarkdownFile(doc))); return coalesce([...onDiskResults, ...openTextDocumentResults]); } @@ -108,80 +118,47 @@ export class VsCodeMdWorkspace extends Disposable implements IMdWorkspace { this._watcher = this._register(vscode.workspace.createFileSystemWatcher('**/*.md')); this._register(this._watcher.onDidChange(async resource => { - this._documentCache.delete(resource); - const document = await this.getOrLoadMarkdownDocument(resource); + const document = await this.getMarkdownDocument(resource); if (document) { this._onDidChangeMarkdownDocumentEmitter.fire(document); } })); this._register(this._watcher.onDidCreate(async resource => { - const document = await this.getOrLoadMarkdownDocument(resource); + const document = await this.getMarkdownDocument(resource); if (document) { this._onDidCreateMarkdownDocumentEmitter.fire(document); } })); this._register(this._watcher.onDidDelete(resource => { - this._documentCache.delete(resource); this._onDidDeleteMarkdownDocumentEmitter.fire(resource); })); - this._register(vscode.workspace.onDidOpenTextDocument(e => { - this._documentCache.delete(e.uri); - if (this.isRelevantMarkdownDocument(e)) { - this._onDidCreateMarkdownDocumentEmitter.fire(e); - } - })); - this._register(vscode.workspace.onDidChangeTextDocument(e => { - if (this.isRelevantMarkdownDocument(e.document)) { + if (isMarkdownFile(e.document)) { this._onDidChangeMarkdownDocumentEmitter.fire(e.document); } })); - - this._register(vscode.workspace.onDidCloseTextDocument(e => { - this._documentCache.delete(e.uri); - })); } - private isRelevantMarkdownDocument(doc: vscode.TextDocument) { - return isMarkdownFile(doc) && doc.uri.scheme !== 'vscode-bulkeditpreview'; - } - - public async getOrLoadMarkdownDocument(resource: vscode.Uri): Promise { - const existing = this._documentCache.get(resource); - if (existing) { - return existing; - } - - const matchingDocument = vscode.workspace.textDocuments.find((doc) => this.isRelevantMarkdownDocument(doc) && doc.uri.toString() === resource.toString()); + public async getMarkdownDocument(resource: vscode.Uri): Promise { + const matchingDocument = vscode.workspace.textDocuments.find((doc) => doc.uri.toString() === resource.toString()); if (matchingDocument) { - this._documentCache.set(resource, matchingDocument); return matchingDocument; } - if (!looksLikeMarkdownPath(resource)) { - return undefined; - } - try { const bytes = await vscode.workspace.fs.readFile(resource); // We assume that markdown is in UTF-8 const text = this.utf8Decoder.decode(bytes); - const doc = new InMemoryDocument(resource, text, 0); - this._documentCache.set(resource, doc); - return doc; + return new InMemoryDocument(resource, text, 0); } catch { return undefined; } } - public hasMarkdownDocument(resolvedHrefPath: vscode.Uri): boolean { - return this._documentCache.has(resolvedHrefPath); - } - public async pathExists(target: vscode.Uri): Promise { let targetResourceStat: vscode.FileStat | undefined; try { @@ -191,8 +168,4 @@ export class VsCodeMdWorkspace extends Disposable implements IMdWorkspace { } return targetResourceStat.type === vscode.FileType.File || targetResourceStat.type === vscode.FileType.Directory; } - - public async readDirectory(resource: vscode.Uri): Promise<[string, vscode.FileType][]> { - return vscode.workspace.fs.readDirectory(resource); - } } diff --git a/extensions/markdown-language-features/tsconfig.json b/extensions/markdown-language-features/tsconfig.json index 75edc8fdac..097d805796 100644 --- a/extensions/markdown-language-features/tsconfig.json +++ b/extensions/markdown-language-features/tsconfig.json @@ -6,6 +6,6 @@ "include": [ "src/**/*", "../../src/vscode-dts/vscode.d.ts", - "../../src/vscode-dts/vscode.proposed.documentPaste.d.ts" + "../../src/vscode-dts/vscode.proposed.textEditorDrop.d.ts", ] } diff --git a/extensions/markdown-language-features/yarn.lock b/extensions/markdown-language-features/yarn.lock index 1ee3f6751e..03cb648102 100644 --- a/extensions/markdown-language-features/yarn.lock +++ b/extensions/markdown-language-features/yarn.lock @@ -2,42 +2,6 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - "@types/dompurify@^2.3.1": version "2.3.3" resolved "https://registry.yarnpkg.com/@types/dompurify/-/dompurify-2.3.3.tgz#c24c92f698f77ed9cc9d9fa7888f90cf2bfaa23f" @@ -75,11 +39,6 @@ resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== -"@types/picomatch@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" - integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== - "@types/trusted-types@*": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" @@ -95,41 +54,20 @@ resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.4.10": + version "0.4.10" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.4.10.tgz#be960c05bdcbea0933866346cf244acad6cac910" + integrity sha512-XgyUoWWRQExTmd9DynIIUQo1NPex/zIeetdUAXeBjVuW9ioojM1TcDaSqOa/5QLC7lx+oEXwSU1r0XSBgzyz6w== argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -dompurify@^2.3.3: - version "2.4.4" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.4.4.tgz#c17803931dd524e1b68e0e940a84567f9498f4bd" - integrity sha512-1e2SpqHiRx4DPvmRuXU5J0di3iQACwJM+mFGE2HAkkK7Tbnfk9WcghcAmyWc9CRrjyRRUpmuhPUH6LphQQR3EQ== +dompurify@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.1.tgz#a47059ca21fd1212d3c8f71fdea6943b8bfbdf6a" + integrity sha512-xGWt+NHAQS+4tpgbOAI08yxW0Pr256Gu/FNE2frZVTbgrBUn8M7tz7/ktS/LZ2MHeGqz6topj0/xY+y8R5FBFw== entities@~2.1.0: version "2.1.0" @@ -153,13 +91,6 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - markdown-it-front-matter@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/markdown-it-front-matter/-/markdown-it-front-matter-0.2.1.tgz#dca49a827bb3cebb0528452c1d87dff276eb28dc" @@ -181,104 +112,27 @@ mdurl@^1.0.1: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= -minimatch@^3.0.4: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - morphdom@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/morphdom/-/morphdom-2.6.1.tgz#e868e24f989fa3183004b159aed643e628b4306e" integrity sha512-Y8YRbAEP3eKykroIBWrjcfMw7mmwJfjhqdpSvoqinu8Y702nAwikpXcNFDiIkyvfCLxLM9Wu95RZqo4a9jFBaA== -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -semver@^7.3.5: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.5.tgz#0c65f15f815aa08b560a61ce8b4db7ffc3f45376" integrity sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg== -vscode-jsonrpc@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e" - integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ== - -vscode-languageclient@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz#bf5535c4463a78daeaca0bcb4f5868aec86bb301" - integrity sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw== - dependencies: - minimatch "^3.0.4" - semver "^7.3.5" - vscode-languageserver-protocol "3.17.1" - -vscode-languageserver-protocol@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed" - integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg== - dependencies: - vscode-jsonrpc "8.0.1" - vscode-languageserver-types "3.17.1" - vscode-languageserver-textdocument@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz#3cd56dd14cec1d09e86c4bb04b09a246cb3df157" integrity sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ== -vscode-languageserver-textdocument@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz#838769940ece626176ec5d5a2aa2d0aa69f5095c" - integrity sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg== - -vscode-languageserver-types@3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16" - integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ== - -vscode-languageserver-types@^3.17.1, vscode-languageserver-types@^3.17.2: - version "3.17.2" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2" - integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA== - -vscode-markdown-languageservice@^0.0.0-alpha.10: - version "0.0.0-alpha.10" - resolved "https://registry.yarnpkg.com/vscode-markdown-languageservice/-/vscode-markdown-languageservice-0.0.0-alpha.10.tgz#53b69c981eed7fd5efa155ab8c0f169995568681" - integrity sha512-rJ85nJ+d45yCz9lBhipavoWXz/vW5FknqqUpLqhe3/2xkrhxt8zcekhSoDepgkKFcTORAFV6g1SnnqxbVhX+uA== - dependencies: - picomatch "^2.3.1" - vscode-languageserver-textdocument "^1.0.5" - vscode-languageserver-types "^3.17.1" - vscode-nls "^5.0.1" - vscode-uri "^3.0.3" - vscode-nls@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840" integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA== -vscode-nls@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2" - integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A== - vscode-uri@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84" integrity sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/extensions/markdown-math/.gitignore b/extensions/markdown-math/.gitignore index 93d9e664ea..67c177886f 100644 --- a/extensions/markdown-math/.gitignore +++ b/extensions/markdown-math/.gitignore @@ -1,2 +1 @@ notebook-out -languageService diff --git a/extensions/markdown-math/notebook/katex.ts b/extensions/markdown-math/notebook/katex.ts index 8a58c6ea6d..c9576e56e9 100644 --- a/extensions/markdown-math/notebook/katex.ts +++ b/extensions/markdown-math/notebook/katex.ts @@ -8,9 +8,9 @@ import type { RendererContext } from 'vscode-notebook-renderer'; const styleHref = import.meta.url.replace(/katex.js$/, 'katex.min.css'); export async function activate(ctx: RendererContext) { - const markdownItRenderer = (await ctx.getRenderer('vscode.markdown-it-renderer')) as undefined | any; + const markdownItRenderer = (await ctx.getRenderer('markdownItRenderer')) as undefined | any; if (!markdownItRenderer) { - throw new Error(`Could not load 'vscode.markdown-it-renderer'`); + throw new Error('Could not load markdownItRenderer'); } // Add katex styles to be copied to shadow dom diff --git a/extensions/markdown-math/package.json b/extensions/markdown-math/package.json index 045da771eb..8267989dae 100644 --- a/extensions/markdown-math/package.json +++ b/extensions/markdown-math/package.json @@ -6,7 +6,7 @@ "icon": "icon.png", "publisher": "vscode", "license": "MIT", - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "^1.54.0" }, @@ -58,10 +58,10 @@ ], "notebookRenderer": [ { - "id": "vscode.markdown-it-katex-extension", + "id": "markdownItRenderer-katex", "displayName": "Markdown it KaTeX renderer", "entrypoint": { - "extends": "vscode.markdown-it-renderer", + "extends": "markdownItRenderer", "path": "./notebook-out/katex.js" } } @@ -90,7 +90,7 @@ "build-notebook": "node ./esbuild" }, "dependencies": { - "@iktakahiro/markdown-it-katex": "mjbvz/markdown-it-katex" + "@iktakahiro/markdown-it-katex": "https://github.com/mjbvz/markdown-it-katex.git" }, "devDependencies": { "@types/markdown-it": "^0.0.0", diff --git a/extensions/markdown-math/preview-styles/index.css b/extensions/markdown-math/preview-styles/index.css index dd205f5905..183ac33479 100644 --- a/extensions/markdown-math/preview-styles/index.css +++ b/extensions/markdown-math/preview-styles/index.css @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. + * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ .katex-error { diff --git a/extensions/markdown-math/yarn.lock b/extensions/markdown-math/yarn.lock index 2b97993578..013a6eb85f 100644 --- a/extensions/markdown-math/yarn.lock +++ b/extensions/markdown-math/yarn.lock @@ -2,9 +2,9 @@ # yarn lockfile v1 -"@iktakahiro/markdown-it-katex@mjbvz/markdown-it-katex": +"@iktakahiro/markdown-it-katex@https://github.com/mjbvz/markdown-it-katex.git": version "4.0.1" - resolved "https://codeload.github.com/mjbvz/markdown-it-katex/tar.gz/1e0d09f9174b3ee1537de2586ce8d8a460284ce4" + resolved "https://github.com/mjbvz/markdown-it-katex.git#b1ed14de467031f5d4f9c1588dd1868cab0b8744" dependencies: katex "^0.13.0" diff --git a/extensions/merge-conflict/package.json b/extensions/merge-conflict/package.json index efc984ed5b..128538a8ad 100644 --- a/extensions/merge-conflict/package.json +++ b/extensions/merge-conflict/package.json @@ -6,7 +6,7 @@ "icon": "media/icon.png", "version": "1.0.0", "license": "MIT", - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "^1.5.0" }, @@ -77,7 +77,6 @@ "title": "%command.next%", "original": "Next Conflict", "command": "merge-conflict.next", - "enablement": "!isMergeEditor", "icon": "$(arrow-down)" }, { @@ -85,7 +84,6 @@ "title": "%command.previous%", "original": "Previous Conflict", "command": "merge-conflict.previous", - "enablement": "!isMergeEditor", "icon": "$(arrow-up)" }, { @@ -112,12 +110,12 @@ { "command": "merge-conflict.previous", "group": "navigation@1", - "when": "!isMergeEditor && mergeConflictsCount && mergeConflictsCount != 0" + "when": "mergeConflictsCount && mergeConflictsCount != 0" }, { "command": "merge-conflict.next", "group": "navigation@2", - "when": "!isMergeEditor && mergeConflictsCount && mergeConflictsCount != 0" + "when": "mergeConflictsCount && mergeConflictsCount != 0" } ] }, diff --git a/extensions/merge-conflict/src/codelensProvider.ts b/extensions/merge-conflict/src/codelensProvider.ts index 7e99edcb9c..68a24c5677 100644 --- a/extensions/merge-conflict/src/codelensProvider.ts +++ b/extensions/merge-conflict/src/codelensProvider.ts @@ -52,7 +52,7 @@ export default class MergeConflictCodeLensProvider implements vscode.CodeLensPro return null; } - const conflicts = await this.tracker.getConflicts(document); + let conflicts = await this.tracker.getConflicts(document); const conflictsCount = conflicts?.length ?? 0; vscode.commands.executeCommand('setContext', 'mergeConflictsCount', conflictsCount); @@ -60,28 +60,28 @@ export default class MergeConflictCodeLensProvider implements vscode.CodeLensPro return null; } - const items: vscode.CodeLens[] = []; + let items: vscode.CodeLens[] = []; conflicts.forEach(conflict => { - const acceptCurrentCommand: vscode.Command = { + let acceptCurrentCommand: vscode.Command = { command: 'merge-conflict.accept.current', title: localize('acceptCurrentChange', 'Accept Current Change'), arguments: ['known-conflict', conflict] }; - const acceptIncomingCommand: vscode.Command = { + let acceptIncomingCommand: vscode.Command = { command: 'merge-conflict.accept.incoming', title: localize('acceptIncomingChange', 'Accept Incoming Change'), arguments: ['known-conflict', conflict] }; - const acceptBothCommand: vscode.Command = { + let acceptBothCommand: vscode.Command = { command: 'merge-conflict.accept.both', title: localize('acceptBothChanges', 'Accept Both Changes'), arguments: ['known-conflict', conflict] }; - const diffCommand: vscode.Command = { + let diffCommand: vscode.Command = { command: 'merge-conflict.compare', title: localize('compareChanges', 'Compare Changes'), arguments: [conflict] diff --git a/extensions/merge-conflict/src/commandHandler.ts b/extensions/merge-conflict/src/commandHandler.ts index 10bead294f..ed1aa229b4 100644 --- a/extensions/merge-conflict/src/commandHandler.ts +++ b/extensions/merge-conflict/src/commandHandler.ts @@ -107,8 +107,8 @@ export default class CommandHandler implements vscode.Disposable { const scheme = editor.document.uri.scheme; let range = conflict.current.content; - const leftRanges = conflicts.map(conflict => [conflict.current.content, conflict.range]); - const rightRanges = conflicts.map(conflict => [conflict.incoming.content, conflict.range]); + let leftRanges = conflicts.map(conflict => [conflict.current.content, conflict.range]); + let rightRanges = conflicts.map(conflict => [conflict.incoming.content, conflict.range]); const leftUri = editor.document.uri.with({ scheme: ContentProvider.scheme, @@ -120,7 +120,7 @@ export default class CommandHandler implements vscode.Disposable { const rightUri = leftUri.with({ query: JSON.stringify({ scheme, ranges: rightRanges }) }); let mergeConflictLineOffsets = 0; - for (const nextconflict of conflicts) { + for (let nextconflict of conflicts) { if (nextconflict.range.isEqual(conflict.range)) { break; } else { @@ -158,7 +158,7 @@ export default class CommandHandler implements vscode.Disposable { } async acceptSelection(editor: vscode.TextEditor): Promise { - const conflict = await this.findConflictContainingSelection(editor); + let conflict = await this.findConflictContainingSelection(editor); if (!conflict) { vscode.window.showWarningMessage(localize('cursorNotInConflict', 'Editor cursor is not within a merge conflict')); @@ -202,7 +202,7 @@ export default class CommandHandler implements vscode.Disposable { } private async navigate(editor: vscode.TextEditor, direction: NavigationDirection): Promise { - const navigationResult = await this.findConflictForNavigation(editor, direction); + let navigationResult = await this.findConflictForNavigation(editor, direction); if (!navigationResult) { // Check for autoNavigateNextConflict, if it's enabled(which indicating no conflict remain), then do not show warning @@ -258,7 +258,7 @@ export default class CommandHandler implements vscode.Disposable { } private async acceptAll(type: interfaces.CommitType, editor: vscode.TextEditor): Promise { - const conflicts = await this.tracker.getConflicts(editor.document); + let conflicts = await this.tracker.getConflicts(editor.document); if (!conflicts || conflicts.length === 0) { vscode.window.showWarningMessage(localize('noConflicts', 'No merge conflicts found in this file')); @@ -323,7 +323,7 @@ export default class CommandHandler implements vscode.Disposable { return null; } - const selection = editor.selection.active; + let selection = editor.selection.active; if (conflicts.length === 1) { if (conflicts[0].range.contains(selection)) { return { diff --git a/extensions/merge-conflict/src/contentProvider.ts b/extensions/merge-conflict/src/contentProvider.ts index 40931039b4..54dae56174 100644 --- a/extensions/merge-conflict/src/contentProvider.ts +++ b/extensions/merge-conflict/src/contentProvider.ts @@ -32,7 +32,7 @@ export default class MergeConflictContentProvider implements vscode.TextDocument let lastPosition = new vscode.Position(0, 0); ranges.forEach(rangeObj => { - const [conflictRange, fullRange] = rangeObj; + let [conflictRange, fullRange] = rangeObj; const [start, end] = conflictRange; const [fullStart, fullEnd] = fullRange; @@ -41,7 +41,7 @@ export default class MergeConflictContentProvider implements vscode.TextDocument lastPosition = new vscode.Position(fullEnd.line, fullEnd.character); }); - const documentEnd = document.lineAt(document.lineCount - 1).range.end; + let documentEnd = document.lineAt(document.lineCount - 1).range.end; text += document.getText(new vscode.Range(lastPosition.line, lastPosition.character, documentEnd.line, documentEnd.character)); return text; diff --git a/extensions/merge-conflict/src/delayer.ts b/extensions/merge-conflict/src/delayer.ts index a3b64512f9..c67cd774c3 100644 --- a/extensions/merge-conflict/src/delayer.ts +++ b/extensions/merge-conflict/src/delayer.ts @@ -35,7 +35,7 @@ export class Delayer { }).then(() => { this.completionPromise = null; this.onSuccess = null; - const result = this.task!(); + let result = this.task!(); this.task = null; return result; }); @@ -56,7 +56,7 @@ export class Delayer { return null; } this.cancelTimeout(); - const result = this.completionPromise; + let result = this.completionPromise; this.onSuccess!(undefined); return result; } diff --git a/extensions/merge-conflict/src/documentMergeConflict.ts b/extensions/merge-conflict/src/documentMergeConflict.ts index d6ba25a743..677e4e8410 100644 --- a/extensions/merge-conflict/src/documentMergeConflict.ts +++ b/extensions/merge-conflict/src/documentMergeConflict.ts @@ -45,11 +45,11 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict // ] if (type === interfaces.CommitType.Current) { // Replace [ Conflict Range ] with [ Current Content ] - const content = document.getText(this.current.content); + let content = document.getText(this.current.content); this.replaceRangeWithContent(content, edit); } else if (type === interfaces.CommitType.Incoming) { - const content = document.getText(this.incoming.content); + let content = document.getText(this.incoming.content); this.replaceRangeWithContent(content, edit); } else if (type === interfaces.CommitType.Both) { diff --git a/extensions/merge-conflict/src/documentTracker.ts b/extensions/merge-conflict/src/documentTracker.ts index ac3f4ab9a1..9fd9da905a 100644 --- a/extensions/merge-conflict/src/documentTracker.ts +++ b/extensions/merge-conflict/src/documentTracker.ts @@ -50,7 +50,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable, getConflicts(document: vscode.TextDocument, origin: string): PromiseLike { // Attempt from cache - const key = this.getCacheKey(document); + let key = this.getCacheKey(document); if (!key) { // Document doesn't have a uri, can't cache it, so return @@ -67,9 +67,11 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable, } return cacheItem.delayTask.trigger(() => { - const conflicts = this.getConflictsOrEmpty(document, Array.from(cacheItem!.origins)); + let conflicts = this.getConflictsOrEmpty(document, Array.from(cacheItem!.origins)); - this.cache?.delete(key!); + if (this.cache) { + this.cache.delete(key!); + } return conflicts; }); @@ -80,7 +82,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable, return false; } - const key = this.getCacheKey(document); + let key = this.getCacheKey(document); if (!key) { return false; } @@ -98,7 +100,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable, } forget(document: vscode.TextDocument) { - const key = this.getCacheKey(document); + let key = this.getCacheKey(document); if (key) { this.cache.delete(key); diff --git a/extensions/merge-conflict/src/mergeConflictParser.ts b/extensions/merge-conflict/src/mergeConflictParser.ts index 26794ad49e..7889da782b 100644 --- a/extensions/merge-conflict/src/mergeConflictParser.ts +++ b/extensions/merge-conflict/src/mergeConflictParser.ts @@ -67,7 +67,7 @@ export class MergeConflictParser { // Create a full descriptor from the lines that we matched. This can return // null if the descriptor could not be completed. - const completeDescriptor = MergeConflictParser.scanItemTolMergeConflictDescriptor(document, currentConflict); + let completeDescriptor = MergeConflictParser.scanItemTolMergeConflictDescriptor(document, currentConflict); if (completeDescriptor !== null) { conflictDescriptors.push(completeDescriptor); @@ -90,7 +90,7 @@ export class MergeConflictParser { return null; } - const tokenAfterCurrentBlock: vscode.TextLine = scanned.commonAncestors[0] || scanned.splitter; + let tokenAfterCurrentBlock: vscode.TextLine = scanned.commonAncestors[0] || scanned.splitter; // Assume that descriptor.current.header, descriptor.incoming.header and descriptor.splitter // have valid ranges, fill in content and total ranges from these parts. @@ -110,7 +110,7 @@ export class MergeConflictParser { name: scanned.startHeader.text.substring(startHeaderMarker.length + 1) }, commonAncestors: scanned.commonAncestors.map((currentTokenLine, index, commonAncestors) => { - const nextTokenLine = commonAncestors[index + 1] || scanned.splitter; + let nextTokenLine = commonAncestors[index + 1] || scanned.splitter; return { header: currentTokenLine.range, decoratorContent: new vscode.Range( @@ -146,7 +146,7 @@ export class MergeConflictParser { return false; } - const text = document.getText(); + let text = document.getText(); return text.includes(startHeaderMarker) && text.includes(endFooterMarker); } diff --git a/extensions/merge-conflict/src/mergeDecorator.ts b/extensions/merge-conflict/src/mergeDecorator.ts index a56af985e2..b62df990c6 100644 --- a/extensions/merge-conflict/src/mergeDecorator.ts +++ b/extensions/merge-conflict/src/mergeDecorator.ts @@ -137,7 +137,7 @@ export default class MergeDecorator implements vscode.Disposable { private generateBlockRenderOptions(backgroundColor: string, overviewRulerColor: string, config: interfaces.IExtensionConfiguration): vscode.DecorationRenderOptions { - const renderOptions: vscode.DecorationRenderOptions = {}; + let renderOptions: vscode.DecorationRenderOptions = {}; if (config.enableDecorations) { renderOptions.backgroundColor = new vscode.ThemeColor(backgroundColor); @@ -176,7 +176,7 @@ export default class MergeDecorator implements vscode.Disposable { try { this.updating.set(editor, true); - const conflicts = await this.tracker.getConflicts(editor.document); + let conflicts = await this.tracker.getConflicts(editor.document); if (vscode.window.visibleTextEditors.indexOf(editor) === -1) { return; } @@ -188,9 +188,9 @@ export default class MergeDecorator implements vscode.Disposable { // Store decorations keyed by the type of decoration, set decoration wants a "style" // to go with it, which will match this key (see constructor); - const matchDecorations: { [key: string]: vscode.Range[] } = {}; + let matchDecorations: { [key: string]: vscode.Range[] } = {}; - const pushDecoration = (key: string, d: vscode.Range) => { + let pushDecoration = (key: string, d: vscode.Range) => { matchDecorations[key] = matchDecorations[key] || []; matchDecorations[key].push(d); }; @@ -224,7 +224,7 @@ export default class MergeDecorator implements vscode.Disposable { // For each match we've generated, apply the generated decoration with the matching decoration type to the // editor instance. Keys in both matches and decorations should match. Object.keys(matchDecorations).forEach(decorationKey => { - const decorationType = this.decorations[decorationKey]; + let decorationType = this.decorations[decorationKey]; if (decorationType) { editor.setDecorations(decorationType, matchDecorations[decorationKey]); @@ -242,7 +242,7 @@ export default class MergeDecorator implements vscode.Disposable { // Race condition, while editing the settings, it's possible to // generate regions before the configuration has been refreshed - const decorationType = this.decorations[decorationKey]; + let decorationType = this.decorations[decorationKey]; if (decorationType) { editor.setDecorations(decorationType, []); diff --git a/extensions/merge-conflict/src/services.ts b/extensions/merge-conflict/src/services.ts index 64de4ecd6b..172b0dd0fa 100644 --- a/extensions/merge-conflict/src/services.ts +++ b/extensions/merge-conflict/src/services.ts @@ -21,7 +21,7 @@ export default class ServiceWrapper implements vscode.Disposable { begin() { - const configuration = this.createExtensionConfiguration(); + let configuration = this.createExtensionConfiguration(); const documentTracker = new DocumentTracker(); this.services.push( @@ -48,19 +48,6 @@ export default class ServiceWrapper implements vscode.Disposable { } createExtensionConfiguration(): interfaces.IExtensionConfiguration { - - // PRAGMATIC way to avoid conflicting with the new merge editor: when git opts into - // using the merge editor we disable this extension - for the merge editor but also - // for "other" editors - const gitConfig = vscode.workspace.getConfiguration('git'); - if (gitConfig.get('mergeEditor')) { - return { - enableCodeLens: false, - enableDecorations: false, - enableEditorOverview: false - }; - } - const workspaceConfiguration = vscode.workspace.getConfiguration(ConfigurationSectionName); const codeLensEnabled: boolean = workspaceConfiguration.get('codeLens.enabled', true); const decoratorsEnabled: boolean = workspaceConfiguration.get('decorators.enabled', true); @@ -77,3 +64,4 @@ export default class ServiceWrapper implements vscode.Disposable { this.services = []; } } + diff --git a/extensions/microsoft-authentication/package.json b/extensions/microsoft-authentication/package.json index f8b8a6931d..58118fefe5 100644 --- a/extensions/microsoft-authentication/package.json +++ b/extensions/microsoft-authentication/package.json @@ -36,7 +36,7 @@ } ] }, - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "main": "./out/extension.js", "browser": "./dist/browser/extension.js", "scripts": { @@ -60,7 +60,7 @@ "sha.js": "2.4.11", "stream": "0.0.2", "uuid": "^8.2.0", - "@vscode/extension-telemetry": "0.6.2", + "@vscode/extension-telemetry": "0.4.10", "vscode-nls": "^5.0.0" }, "repository": { diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts index 6ae27b3a2b..3e30d4cd12 100644 --- a/extensions/microsoft-authentication/src/AADHelper.ts +++ b/extensions/microsoft-authentication/src/AADHelper.ts @@ -11,7 +11,7 @@ import * as nls from 'vscode-nls'; import { v4 as uuid } from 'uuid'; import fetch, { Response } from 'node-fetch'; import Logger from './logger'; -import { isSupportedEnvironment, toBase64UrlEncoding } from './utils'; +import { toBase64UrlEncoding } from './utils'; import { sha256 } from './env/node/sha256'; import { BetterTokenStorage, IDidChangeInOtherWindowEvent } from './betterSecretStorage'; import { LoopbackAuthServer } from './authServer'; @@ -109,7 +109,7 @@ export class AzureActiveDirectoryService { public async initialize(): Promise { Logger.info('Reading sessions from secret storage...'); - const sessions = await this._tokenStorage.getAll(); + let sessions = await this._tokenStorage.getAll(); Logger.info(`Got ${sessions.length} stored sessions`); const refreshes = sessions.map(async session => { @@ -319,7 +319,13 @@ export class AzureActiveDirectoryService { }, 5000); } - const session = await this.exchangeCodeForSession(codeToExchange, codeVerifier, scopeData); + const token = await this.exchangeCodeForToken(codeToExchange, codeVerifier, scopeData); + if (token.expiresIn) { + this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER); + } + await this.setToken(token, scopeData); + Logger.info(`Login successful for scopes: ${scopeData.scopeStr}`); + const session = await this.convertToSession(token); return session; } @@ -346,14 +352,12 @@ export class AzureActiveDirectoryService { code_challenge_method: 'S256', code_challenge: codeChallenge, }); - const uri = vscode.Uri.parse(`${signInUrl}?${oauthStartQuery.toString()}`); + let uri = vscode.Uri.parse(`${signInUrl}?${oauthStartQuery.toString()}`); vscode.env.openExternal(uri); - let inputBox: vscode.InputBox | undefined; const timeoutPromise = new Promise((_: (value: vscode.AuthenticationSession) => void, reject) => { const wait = setTimeout(() => { clearTimeout(wait); - inputBox?.dispose(); reject('Login timed out.'); }, 1000 * 60 * 5); }); @@ -365,12 +369,7 @@ export class AzureActiveDirectoryService { // before completing it. let existingPromise = this._codeExchangePromises.get(scopeData.scopeStr); if (!existingPromise) { - if (isSupportedEnvironment(callbackUri)) { - existingPromise = this.handleCodeResponse(scopeData); - } else { - inputBox = vscode.window.createInputBox(); - existingPromise = Promise.race([this.handleCodeInputBox(inputBox, codeVerifier, scopeData), this.handleCodeResponse(scopeData)]); - } + existingPromise = this.handleCodeResponse(scopeData); this._codeExchangePromises.set(scopeData.scopeStr, existingPromise); } @@ -660,7 +659,13 @@ export class AzureActiveDirectoryService { throw new Error('No available code verifier'); } - const session = await this.exchangeCodeForSession(code, verifier, scopeData); + const token = await this.exchangeCodeForToken(code, verifier, scopeData); + if (token.expiresIn) { + this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER); + } + await this.setToken(token, scopeData); + + const session = await this.convertToSession(token); resolve(session); } catch (err) { reject(err); @@ -675,33 +680,8 @@ export class AzureActiveDirectoryService { }); } - private async handleCodeInputBox(inputBox: vscode.InputBox, verifier: string, scopeData: IScopeData): Promise { - inputBox.ignoreFocusOut = true; - inputBox.title = localize('pasteCodeTitle', 'Microsoft Authentication'); - inputBox.prompt = localize('pasteCodePrompt', 'Provide the authorization code to complete the sign in flow.'); - inputBox.placeholder = localize('pasteCodePlaceholder', 'Paste authorization code here...'); - return new Promise((resolve: (value: vscode.AuthenticationSession) => void, reject) => { - inputBox.show(); - inputBox.onDidAccept(async () => { - const code = inputBox.value; - if (code) { - inputBox.dispose(); - const session = await this.exchangeCodeForSession(code, verifier, scopeData); - resolve(session); - } - }); - inputBox.onDidHide(() => { - if (!inputBox.value) { - inputBox.dispose(); - reject('Cancelled'); - } - }); - }); - } - - private async exchangeCodeForSession(code: string, codeVerifier: string, scopeData: IScopeData): Promise { + private async exchangeCodeForToken(code: string, codeVerifier: string, scopeData: IScopeData): Promise { Logger.info(`Exchanging login code for token for scopes: ${scopeData.scopeStr}`); - let token: IToken | undefined; try { const postData = querystring.stringify({ grant_type: 'authorization_code', @@ -718,18 +698,11 @@ export class AzureActiveDirectoryService { const json = await this.fetchTokenResponse(endpoint, postData, scopeData); Logger.info(`Exchanging login code for token (for scopes: ${scopeData.scopeStr}) succeeded!`); - token = this.convertToTokenSync(json, scopeData); + return this.convertToTokenSync(json, scopeData); } catch (e) { Logger.error(`Error exchanging code for token (for scopes ${scopeData.scopeStr}): ${e}`); throw e; } - - if (token.expiresIn) { - this.setSessionTimeout(token.sessionId, token.refreshToken, scopeData, token.expiresIn * AzureActiveDirectoryService.REFRESH_TIMEOUT_MODIFIER); - } - await this.setToken(token, scopeData); - Logger.info(`Login successful for scopes: ${scopeData.scopeStr}`); - return await this.convertToSession(token); } private async fetchTokenResponse(endpoint: string, postData: string, scopeData: IScopeData): Promise { diff --git a/extensions/microsoft-authentication/src/extension.ts b/extensions/microsoft-authentication/src/extension.ts index 661d16b034..41ebe75777 100644 --- a/extensions/microsoft-authentication/src/extension.ts +++ b/extensions/microsoft-authentication/src/extension.ts @@ -21,9 +21,7 @@ export async function activate(context: vscode.ExtensionContext) { try { /* __GDPR__ "login" : { - "owner": "TylerLeonhardt", - "comment": "Used to determine the usage of the Microsoft Auth Provider.", - "scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." } + "scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" } } */ telemetryReporter.sendTelemetryEvent('login', { @@ -36,7 +34,7 @@ export async function activate(context: vscode.ExtensionContext) { return session; } catch (e) { /* __GDPR__ - "loginFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." } + "loginFailed" : { } */ telemetryReporter.sendTelemetryEvent('loginFailed'); @@ -46,7 +44,7 @@ export async function activate(context: vscode.ExtensionContext) { removeSession: async (id: string) => { try { /* __GDPR__ - "logout" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." } + "logout" : { } */ telemetryReporter.sendTelemetryEvent('logout'); @@ -56,7 +54,7 @@ export async function activate(context: vscode.ExtensionContext) { } } catch (e) { /* __GDPR__ - "logoutFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." } + "logoutFailed" : { } */ telemetryReporter.sendTelemetryEvent('logoutFailed'); } diff --git a/extensions/microsoft-authentication/src/utils.ts b/extensions/microsoft-authentication/src/utils.ts index 5371e02576..912cc56035 100644 --- a/extensions/microsoft-authentication/src/utils.ts +++ b/extensions/microsoft-authentication/src/utils.ts @@ -2,40 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { env, UIKind, Uri } from 'vscode'; export function toBase64UrlEncoding(base64string: string) { return base64string.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_'); // Need to use base64url encoding } - -const LOCALHOST_ADDRESSES = ['localhost', '127.0.0.1', '0:0:0:0:0:0:0:1', '::1']; -function isLocalhost(uri: Uri): boolean { - if (!/^https?$/i.test(uri.scheme)) { - return false; - } - const host = uri.authority.split(':')[0]; - return LOCALHOST_ADDRESSES.indexOf(host) >= 0; -} - -export function isSupportedEnvironment(uri: Uri): boolean { - if (env.uiKind === UIKind.Desktop) { - return true; - } - // local development (localhost:* or 127.0.0.1:*) - if (isLocalhost(uri)) { - return true; - } - // At this point we should only ever see https - if (uri.scheme !== 'https') { - return false; - } - - return ( - // vscode.dev & insiders.vscode.dev - /(?:^|\.)vscode\.dev$/.test(uri.authority) || - // github.dev & codespaces - /(?:^|\.)github\.dev$/.test(uri.authority) || - // github.dev/codespaces local setup (github.localhost) - /(?:^|\.)github\.localhost$/.test(uri.authority) - ); -} diff --git a/extensions/microsoft-authentication/yarn.lock b/extensions/microsoft-authentication/yarn.lock index 9328b1d4b1..b3ad2657f8 100644 --- a/extensions/microsoft-authentication/yarn.lock +++ b/extensions/microsoft-authentication/yarn.lock @@ -2,42 +2,6 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - "@types/node-fetch@^2.5.7": version "2.5.7" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" @@ -75,13 +39,10 @@ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0" integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw== -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.4.10": + version "0.4.10" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.4.10.tgz#be960c05bdcbea0933866346cf244acad6cac910" + integrity sha512-XgyUoWWRQExTmd9DynIIUQo1NPex/zIeetdUAXeBjVuW9ioojM1TcDaSqOa/5QLC7lx+oEXwSU1r0XSBgzyz6w== asynckit@^0.4.0: version "0.4.0" diff --git a/extensions/notebook-renderers/package.json b/extensions/notebook-renderers/package.json index f78839bbee..15b6751e20 100644 --- a/extensions/notebook-renderers/package.json +++ b/extensions/notebook-renderers/package.json @@ -17,7 +17,7 @@ "contributes": { "notebookRenderer": [ { - "id": "vscode.builtin-renderer", + "id": "vscode-builtin-notebook-renderer", "entrypoint": "./renderer-out/index.js", "displayName": "VS Code Builtin Notebook Output Renderer", "requiresMessaging": "never", diff --git a/extensions/notebook-renderers/src/index.ts b/extensions/notebook-renderers/src/index.ts index 82f7637c10..ae457fcaec 100644 --- a/extensions/notebook-renderers/src/index.ts +++ b/extensions/notebook-renderers/src/index.ts @@ -10,21 +10,13 @@ interface IDisposable { dispose(): void; } -interface HtmlRenderingHook { - /** - * Invoked after the output item has been rendered but before it has been appended to the document. - * - * @return A new `HTMLElement` or `undefined` to continue using the provided element. - */ - postRender(outputItem: OutputItem, element: HTMLElement): HTMLElement | undefined; -} - function clearContainer(container: HTMLElement) { while (container.firstChild) { container.removeChild(container.firstChild); } } + function renderImage(outputInfo: OutputItem, element: HTMLElement): IDisposable { const blob = new Blob([outputInfo.data()], { type: outputInfo.mime }); const src = URL.createObjectURL(blob); @@ -72,17 +64,12 @@ const domEval = (container: Element) => { } }; -function renderHTML(outputInfo: OutputItem, container: HTMLElement, hooks: Iterable): void { +function renderHTML(outputInfo: OutputItem, container: HTMLElement): void { clearContainer(container); - let element: HTMLElement = document.createElement('div'); const htmlContent = outputInfo.text(); + const element = document.createElement('div'); const trustedHtml = ttPolicy?.createHTML(htmlContent) ?? htmlContent; element.innerHTML = trustedHtml as string; - - for (const hook of hooks) { - element = hook.postRender(outputInfo, element) ?? element; - } - container.appendChild(element); domEval(element); } @@ -180,8 +167,6 @@ function renderText(outputInfo: OutputItem, container: HTMLElement, ctx: Rendere export const activate: ActivationFunction = (ctx) => { const disposables = new Map(); - const htmlHooks = new Set(); - const latestContext = ctx as (RendererContext & { readonly settings: { readonly lineLimit: number } }); const style = document.createElement('style'); @@ -225,7 +210,6 @@ export const activate: ActivationFunction = (ctx) => { } `; document.body.appendChild(style); - return { renderOutputItem: (outputInfo, element) => { switch (outputInfo.mime) { @@ -236,7 +220,7 @@ export const activate: ActivationFunction = (ctx) => { return; } - renderHTML(outputInfo, element, htmlHooks); + renderHTML(outputInfo, element); } break; case 'application/javascript': @@ -283,6 +267,8 @@ export const activate: ActivationFunction = (ctx) => { default: break; } + + }, disposeOutputItem: (id: string | undefined) => { if (id) { @@ -290,14 +276,6 @@ export const activate: ActivationFunction = (ctx) => { } else { disposables.forEach(d => d.dispose()); } - }, - experimental_registerHtmlRenderingHook: (hook: HtmlRenderingHook): IDisposable => { - htmlHooks.add(hook); - return { - dispose: () => { - htmlHooks.delete(hook); - } - }; } }; }; diff --git a/extensions/package.json b/extensions/package.json index 31b83174c2..0ace79a008 100644 --- a/extensions/package.json +++ b/extensions/package.json @@ -12,6 +12,6 @@ "devDependencies": { "@parcel/watcher": "2.0.5", "esbuild": "^0.11.12", - "vscode-grammar-updater": "^1.1.0" + "vscode-grammar-updater": "^1.0.4" } } diff --git a/extensions/resource-deployment/src/test/utils.ts b/extensions/resource-deployment/src/test/utils.ts index b62095d34e..d537006d33 100644 --- a/extensions/resource-deployment/src/test/utils.ts +++ b/extensions/resource-deployment/src/test/utils.ts @@ -7,7 +7,7 @@ export class Deferred { promise: Promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; - }); + });; resolve!: (value: T | PromiseLike) => void; reject!: (reason?: any) => void; } diff --git a/extensions/search-result/src/extension.ts b/extensions/search-result/src/extension.ts index d78694d28f..4ba6e50e37 100644 --- a/extensions/search-result/src/extension.ts +++ b/extensions/search-result/src/extension.ts @@ -225,7 +225,7 @@ function parseSearchResults(document: vscode.TextDocument, token?: vscode.Cancel const metadataOffset = (indentation + _lineNumber + separator).length; const targetRange = new vscode.Range(Math.max(lineNumber - 3, 0), 0, lineNumber + 3, line.length); - const locations: Required[] = []; + let locations: Required[] = []; let lastEnd = metadataOffset; let offset = 0; @@ -256,7 +256,7 @@ function parseSearchResults(document: vscode.TextDocument, token?: vscode.Cancel } // Allow line number, indentation, etc to take you to definition as well. - const convenienceLocation: Required = { + let convenienceLocation: Required = { targetRange, targetSelectionRange: new vscode.Range(lineNumber, 0, lineNumber, 1), targetUri: currentTarget, diff --git a/extensions/shared.webpack.config.js b/extensions/shared.webpack.config.js index 1e122b9537..c3319c11f9 100644 --- a/extensions/shared.webpack.config.js +++ b/extensions/shared.webpack.config.js @@ -13,11 +13,11 @@ const fs = require('fs'); const merge = require('merge-options'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const { NLSBundlePlugin } = require('vscode-nls-dev/lib/webpack-bundler'); -const { DefinePlugin, optimize } = require('webpack'); +const { DefinePlugin } = require('webpack'); function withNodeDefaults(/**@type WebpackConfig*/extConfig) { /** @type WebpackConfig */ - const defaultConfig = { + let defaultConfig = { mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') target: 'node', // extensions run in a node context node: { @@ -94,7 +94,7 @@ function nodePlugins(context) { function withBrowserDefaults(/**@type WebpackConfig*/extConfig, /** @type AdditionalBrowserConfig */ additionalOptions = {}) { /** @type WebpackConfig */ - const defaultConfig = { + let defaultConfig = { mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') target: 'webworker', // extensions run in a webworker context resolve: { @@ -146,16 +146,12 @@ function withBrowserDefaults(/**@type WebpackConfig*/extConfig, /** @type Additi } const browserPlugins = [ - new optimize.LimitChunkCountPlugin({ - maxChunks: 1 - }), new CopyWebpackPlugin({ patterns: [ { from: 'src', to: '.', globOptions: { ignore: ['**/test/**', '**/*.ts'] }, noErrorOnMissing: true } ] }), new DefinePlugin({ - 'process.platform': JSON.stringify('web'), 'process.env': JSON.stringify({}), 'process.env.BROWSER_ENV': JSON.stringify('true') }) diff --git a/extensions/simple-browser/.vscodeignore b/extensions/simple-browser/.vscodeignore index d1006b25b7..ec298ce176 100644 --- a/extensions/simple-browser/.vscodeignore +++ b/extensions/simple-browser/.vscodeignore @@ -11,4 +11,3 @@ cgmanifest.json yarn.lock preview-src/** webpack.config.js -esbuild-preview.js diff --git a/extensions/simple-browser/package.json b/extensions/simple-browser/package.json index 08344e234f..711ffbd81e 100644 --- a/extensions/simple-browser/package.json +++ b/extensions/simple-browser/package.json @@ -9,7 +9,7 @@ "icon": "media/icon.png", "publisher": "vscode", "license": "MIT", - "aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255", + "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "engines": { "vscode": "^1.53.0" }, @@ -67,7 +67,7 @@ "watch-web": "npx webpack-cli --config extension-browser.webpack.config --mode none --watch --info-verbosity verbose" }, "dependencies": { - "@vscode/extension-telemetry": "0.6.2", + "@vscode/extension-telemetry": "0.4.10", "vscode-nls": "^5.0.0" }, "devDependencies": { diff --git a/extensions/simple-browser/yarn.lock b/extensions/simple-browser/yarn.lock index 5faf627618..af6b2add33 100644 --- a/extensions/simple-browser/yarn.lock +++ b/extensions/simple-browser/yarn.lock @@ -2,54 +2,15 @@ # yarn lockfile v1 -"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7" - integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g== - dependencies: - "@microsoft/applicationinsights-core-js" "2.8.4" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/1ds-post-js@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216" - integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ== - dependencies: - "@microsoft/1ds-core-js" "3.2.3" - "@microsoft/applicationinsights-shims" "^2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-core-js@2.8.4": - version "2.8.4" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596" - integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ== - dependencies: - "@microsoft/applicationinsights-shims" "2.0.1" - "@microsoft/dynamicproto-js" "^1.1.6" - -"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" - integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== - -"@microsoft/dynamicproto-js@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" - integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== - "@types/vscode-webview@^1.57.0": version "1.57.0" resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf" integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA== -"@vscode/extension-telemetry@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e" - integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w== - dependencies: - "@microsoft/1ds-core-js" "^3.2.3" - "@microsoft/1ds-post-js" "^3.2.3" +"@vscode/extension-telemetry@0.4.10": + version "0.4.10" + resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.4.10.tgz#be960c05bdcbea0933866346cf244acad6cac910" + integrity sha512-XgyUoWWRQExTmd9DynIIUQo1NPex/zIeetdUAXeBjVuW9ioojM1TcDaSqOa/5QLC7lx+oEXwSU1r0XSBgzyz6w== vscode-codicons@^0.0.14: version "0.0.14" diff --git a/extensions/sql-migration/src/models/loginMigrationModel.ts b/extensions/sql-migration/src/models/loginMigrationModel.ts index 3f645787c4..55b3daf5d1 100644 --- a/extensions/sql-migration/src/models/loginMigrationModel.ts +++ b/extensions/sql-migration/src/models/loginMigrationModel.ts @@ -59,7 +59,7 @@ export interface Login { export class LoginMigrationModel { public resultsPerStep: Map; public collectedSourceLogins: boolean = false; - public collectedTargetLogins: boolean = false; + public collectedTargetLogins: boolean = false;; public loginsOnSource: LoginTableInfo[] = []; public loginsOnTarget: string[] = []; public loginMigrationsResult!: contracts.StartLoginMigrationResult; diff --git a/extensions/sql/cgmanifest.json b/extensions/sql/cgmanifest.json index 82846c1e67..da31bda5d0 100644 --- a/extensions/sql/cgmanifest.json +++ b/extensions/sql/cgmanifest.json @@ -14,4 +14,4 @@ } ], "version": 1 -} +} \ No newline at end of file diff --git a/extensions/sql/syntaxes/sql.tmLanguage.json b/extensions/sql/syntaxes/sql.tmLanguage.json index a3399137d3..9797bff195 100644 --- a/extensions/sql/syntaxes/sql.tmLanguage.json +++ b/extensions/sql/syntaxes/sql.tmLanguage.json @@ -624,4 +624,4 @@ ] } } -} +} \ No newline at end of file diff --git a/extensions/theme-defaults/themes/dark_vs.json b/extensions/theme-defaults/themes/dark_vs.json index 8072b0bdd6..768a6b3038 100644 --- a/extensions/theme-defaults/themes/dark_vs.json +++ b/extensions/theme-defaults/themes/dark_vs.json @@ -12,7 +12,7 @@ "activityBarBadge.background": "#007ACC", "sideBarTitle.foreground": "#BBBBBB", "input.placeholderForeground": "#A6A6A6", - "menu.background": "#303031", + "menu.background": "#252526", "menu.foreground": "#CCCCCC", "statusBarItem.remoteForeground": "#FFF", "statusBarItem.remoteBackground": "#16825D", diff --git a/extensions/theme-defaults/themes/light_vs.json b/extensions/theme-defaults/themes/light_vs.json index ae3ab6645b..d2349f3124 100644 --- a/extensions/theme-defaults/themes/light_vs.json +++ b/extensions/theme-defaults/themes/light_vs.json @@ -25,8 +25,7 @@ "notebook.cellBorderColor": "#E8E8E8", "notebook.selectedCellBackground": "#c8ddf150", "statusBarItem.errorBackground": "#c72e0f", - "list.activeSelectionIconForeground": "#FFF", - "list.focusAndSelectionOutline": "#90C2F9" + "list.activeSelectionIconForeground": "#FFF" }, "tokenColors": [ { diff --git a/extensions/theme-seti/build/update-icon-theme.js b/extensions/theme-seti/build/update-icon-theme.js index 412472af75..41d95b81af 100644 --- a/extensions/theme-seti/build/update-icon-theme.js +++ b/extensions/theme-seti/build/update-icon-theme.js @@ -45,8 +45,7 @@ const nonBuiltInLanguages = { // { fileNames, extensions } const inheritIconFromLanguage = { "jsonc": 'json', "postcss": 'css', - "django-html": 'html', - "blade": 'php' + "django-html": 'html' } const FROM_DISK = true; // set to true to take content from a repo checked out next to the vscode repo diff --git a/extensions/theme-seti/cgmanifest.json b/extensions/theme-seti/cgmanifest.json index 919b27b7c9..00e2991fb9 100644 --- a/extensions/theme-seti/cgmanifest.json +++ b/extensions/theme-seti/cgmanifest.json @@ -6,7 +6,7 @@ "git": { "name": "seti-ui", "repositoryUrl": "https://github.com/jesseweed/seti-ui", - "commitHash": "2d10473b7575ec00c47eda751ea9caeec6b0b606" + "commitHash": "8dba1bc311dad1b9bc23c4779149f3bf9baa8cb0" } }, "version": "0.1.0" diff --git a/extensions/theme-seti/icons/seti.woff b/extensions/theme-seti/icons/seti.woff index f0e47486995b58f1484c564f76d10182211ecd47..aeb87b845af6596a1b72e1590613ea35a538cc52 100644 GIT binary patch delta 33189 zcmV)5K*_(*q5{;S0u*;oMn(Vu00000kyHQ+00000+`N$#Uw?c60L180exbH#Wnp9h z0E%n?001rk001^0n-;2QXk}pl0E(Od000~S001NhyaiHdZFG150E)N(001oj00M-0 zQvd*LZ)0Hq0E*}U00Be*00BfID^u2OVR&!=0E{dE0018V001BYdI}J3VQpmq0E|ok z00ABV00HLSN(vdwaBp*T0050_vHbc2e_UsECs^Np_oePuxAv<0s_H$xz1Al^={@UN zyKKp_B}?7}0)xN{wqqy61~~>B3;_qzj-5c8Wz3kK5Q7bA2n5HZNqcZ&HzX_x9TEZ! z9TOAWfu9qCdt5W;ySJWXW?<$ws#jIF?)oj~JLmsD=X{@XGzb5PfuG44xngd6e{O#+ zhnfqhzlOS16WSIO=q}m zn^2fQ$PyeK>t6cWOM5-|=%V@Nf9melq}I5jS^Xx)gi=Px%_lXD@HeAXM1<=2TYXm( z^z;xR%!J``0@cH59T8c|9nake_2Yposf7feMa@OrPMU(-hg}pA+t(&!hh2WA3^20#>N|quLWG%o&GU$(nXI~*aIiJ`*f3umPd4^fG zh3%=a2_L4TdbYlCW*k&Fp8=B#@&)0;2XK_{IgmS&X z+j&tiLnvFLVp|A(DXuoEe-@{h*rBQE!iY_k3QTfHwjur>q>4(4F7=-i{rYUHJ!XM`4;`a7|Gh z&+)5vUYRnu>T^X?yn5&qMV^26!yo?cBM*M?6O%g3v`52kDl-ApuH$bW?ZY6EM+fpWd52K=Ae9U0MbI8= zC>?1bdWkChWS5Y;9A+AK@_W_1AO<05j?#i(rIx8OhBUOOddCez1ZvwZP>hZasBLJJ zQk1CH4(M|bJFiTR*QuLl!r|1g7`1$A>6oD$r$=TmvOi^*fAow%8d1l4T}FQFsasdN zO=vG_GI-|3!QZ;U)irHt%gTC)5kGlIFqN4gAZT&@)KQZw3Sp)CjwRDrn^T$Qs)crG zRDf?Pg0@nDrcB$@A{XRt$h|f9F=)-v5C&R0=w!PEU66qQ`dY{V7Ipk2h?;ODfJO-t z5k$do9fv^=e||~H@FRH<3_>{E3wrW8IJY+%!a$XJs5=~i%nXKEKP;j?3|cwZlgSCt zCw!FkS2}9fQD5F@*po+kgC2bPqB%$co^bs6Z3XJIt0%6$XsUrIq6~D9;hTcNh$Ehk zK%>D1b#;~Y`&eL1gW|#0U=UAC85JfLyr_qvOXq@of6LZ!*lQg8MNnxs?=@hz9h~=L7*sv+ZrfD z%rWs)q)-ld-8LLA*njC>I4>6t1(m_ySiy$20h%GI=H9is>=OK zHFGK=f8x}YS_xB4SLdII952GuvpVEPrXo&>W-wbA%+!UssK{vC!{7NGmha<4*iK~sKUunIFh?+(lQQ4eYnA3 ze<+oR9O0ubSQZdEc?t{#IJAH|V3`&OjD#>)LvV*0T9Ue=m&z{4yWjy_JV@}E&zFNcVx54=8M8!)D5Amog_?^Ydf)^iXiFIB0^32?Ln9p zI4e^6>OrNVUI?SB16|T?azE@q6(f1ie@>e?1Z>ilqqEcp&E#N$DGtkR1C&lIqV1)M zMI282<$N4Qr`DDtnF`5+y@dPa7c5>0 zK!gh+Hh#y85y(53ctwsYuzGCPY!(Zg2#NtuV8v0WA#^jaG|M4J4NB&xz=9H+f0RR~ z48ue*U=V0!*mW{&))yP~|1I`b7(Cur1)WBZ(_K;ukJ&JYWfJxTiK2kRrCa1{M2v%WuvT7;TW{aHL9>|AmpFvFr zWno>|x_s%>ajRr##KbDp3Ny=Lf0{-aQ&j|KUO~dvUdh3TmcVAf$y_x+1Aq;H zZJ|@`WOJd>SgL=4gRT(@rUo{Ns$s=5v}6&pE%g=9eV|h?fl`9;3DsCLe^jngD5JQ> zE$97$w*vJLSXG%WhgD`nFTjt%s26}A5*SlKV*n5$Az;*5UkZBETL6=qf=y7`AeGoe z>o2|M<%2|uHvnW@Z8)Zjhc@gZ(vA~Y=-)%MjqPt)>;e;U5$SarK#*E-dM z2bTpAYStytP-`vK#zoSF-BmE0w8Uy#?)fQg{xaS@Fs zO%#fDM~ncfv?r!je>9;oK?r6t)gge7ni2sv6s=nH8>Hj)t-t-kr-V3s6@-Qw91!ZLr%eEtjBnUfWAdA#2Y~c#FRvFIgny)&# z%f$KU8;wg3IZw~U-$>B=Vs$+(lnV{7pwB$OIwxXkYzU3zf6e9gyk>|Mf^iI($&A4~ zA~4cbzeV}_PivMZ?I^&Og88$vHfjm~x7?Q8j@+eEYLiWZuz(~zNUeYbt+I|l1|~cL zP9RBYGk`>-bU|wJR!TcKv<#^3s#NPyPu>B&(CQbrG~-zyK$`7OpSMRjJafaV%z__> zTA*P;9ylcUf7;1))32BF_5957*9nHUqI}K4LVOpBtk39`TdIcPsTNL7fkxH2M+^|l zi}Q}JM-1^gHFdjwsAfVlVBGe|_&eOAs*_Ll#XvPeCayl=S{}y;tq^j8XhbOsKp#f# zEPvWUw&a3bW)B;(bKR;mca78-x_tsjz0quUTtK_MKL!Y)OWM(%@l_!|4_G9Q_M(TF zM>o{HrD*)S#e|}|<)bSKO^Uz0p_0d992tM|l9&ZgmCIIM^}IK-Y&fJJHvWs;42*{NNt1yPgcpxT zyiB}$0whwk!5YpSTqxdRS%EseACnvrC;`}$MG-*(wUdVtBY(sY!U!ZffXfY?i*tP` zG3Ow+C--W}W3%pomk+}iT2wZwWCId^p|l6!HEc^*HbFw&A*tduoE}S0kK`c`y1}q2 zWkdc+*8wny3ZUQbx0SN8ve*u0R9QKDeNc@mWuQ_sJYqX8Z#s$&0~n52jmoGyV9sBm zo!8xQ{Tjj>!+)(i*RHA7e+IB+YfM1zshIVeb|P$(>BP*gX${H)CH0ZzDN(k z1!<$AA8G|kqLNcn4P8B6X*MfV<8EGqiaB}fnU>j_Sw6Dl+GQ=AZM5>_;9D--y|#UN z%anTW?pxc*Y!JEz=BSk{U%WVoSL+oJV1zDQ-#|a`mZ~Ce0$B0u#Xkto+rJ*Vp;ZT> zW02X1!GFLY`K61O+Ea}ZDU`RG`3v82L8CTOIePNEQOLmjKoQ{Cd$yIMEyC2;g>PxK zH}&J!@E?O6u4Nj6gYFj+8ZS=d22_$nexf5f_-lw91Q_?h_j850tyrk!w$n_o=k#dd z)5jj(b_~4G1+@!!5z2()6eiv;G=YKwa@drj1pR?5o*`0IYnajC#>0Lp9 zp8(%Pqbgd%0H<8&h&3#m*uvx&9s|*rw1s&Q!D~Bj7>Hm|M2|61xbGAD($1dAHGk&yp?DCEL zRD1rqP7wVgDy)rva8A!(2jlb=vQC|LO4>7a)yothP!lOMz<@IHC7pNe^hnm+ok2gz z95Fn*Si+J8N$z0;uc3*@K>!0n7c<3Iw0}iE@tS%xcm0`L_O?9{cuuXLOV1Y)RAmKb zn}XIhSjT8)AtFdM_l1(VE5Z=Yw9PEH-d^bRy+J%vZfd5-s`GV05z?)ES$}9C z#u%No#|4tlJ&=1y+T%q8oUIS7u?8k^0okZIXv+;r(S{igNgJY>vb~Nx!vap}Cz%^G zJuY{pR%l|KrO>Y8cY6`c0?j}u<7G6qMR(P|xb+b_Lc@BGyfxoQec0n)y|9|2yK@#+& z|7wto2IqbNl-@C)tfaKXRdwGCy#Q#7GYz!G++CS&EzW_huuNfwXgJsH!r$iytE+?U zn694O;X7?fQwZUzo(zGe_<2>&A8z=0+iKVat2TGHZ}&Ea=L@u2&@l) zBuJghT5g9dqJ}^({I3tA{eNix!!KTXDLQc}x$zaR7~l286X?ya7+-Y%{r6AmpIvL_ zyq8_w8G#n_pcO`)vp4z9CqFs!*0&!1u4gT#sv~lLl znI{e(2F{e>3w^?KZ76q?J_{JH=Qdmhw;xR&^NYT}g}dYF4}bVuzvz!>FMS=)-8?fh zGuV7jPfzD~CMSdeTWjT}!44eE9hcIQLgPqej;R!ePQ)aYkB+QnF9K`SOJ%5+Dn;0~ zWb|hTT1DL|2CFfPMt=bu!+o$Ah)lO`UEkf`J>O~+LS4hfs90}pfgR_)xjlpDV{KN8 z=VId6|1$)Yr3#IPENJ-Z4Kuc5Dj+N7mdMdHPN}9@nC@R&T~n07p(?_mpENGqaDB#- z!>fk2w&OfntG)e5w|iv2%T!Gm{=vPaf^9~XeZnbC6>V|D34fyGtG0eNz61UGd``>d zq3%AQHy1Dl(1L!tHN@Zk!0&$OQ|~_5Zk>5(eR%0H^y2MrMK5eruh{;P@n?^m!-i#2 zf;-5T%%z$%X~IYj{2GGMBYB<-e6^DXk~(zYB2s$utCf;ous&{FsRZBp+3E4ubzcd^ z9;~Y4AEM*W-hZNVbRF)z>D8*C9Or-H8r9%ir_o;lvD$;i^;>i|K&|m_pL;$9o7V!Q zby;TjvKJVuVK39EDR4SVGyz~lpsSPAxFu)Lmiz%aJ4$0G>9N!pWCuW50QOtl)-^&y zn2c&ouYX?q!q;B{8bFQBxos6|^i!QVRr6PW7k7(W8h>U%TRSkg?6^aT8GbRIOa9y5u{5zkhh7JqvVpUBw)O{qQ^h3P9m8Q2K%k z_Ry*b!ga-{MZkop5&>KD6idZMDFzGFDhsZLa?= z#Z!mBtoT5FlG$KSnL1WDXXblbO@l^ZU>KAw50_Slm+)4ltl(D!T7?CgqqaBlGo4x` zKkTjTTpA{xGu^s4!n9i6GtqHl{8iBSmW-nYA__W83_vgk(Q{8d@W4~pf9iejdw&Xt zpF45qohLp=;EUXO#b?jz$1jt^(8JTxqqiBx7a6S1ggPrU^d(8vM+ek$1=^qnrd>BF zZ&#Pvmvs8coMUGqW^fM@$=oQR0WoB@8cRB`K5`Fgdrc%YXBWOA`Uo;b|}^jRpgN?TE}nGU!VjB;!HRxgsA| z>|a`7xVx^cAFeG{oP4`p97I;RS}LD^xG`0opIVuB-g~w>S1I-{t4w2dzJYcPYg4`< zLOU)8-T_na^H&;kju~tz+4lHdn^n!64pU?bYRq!VWTb_;oQfKqXwX6~a(^3=6QZcm zaYqgG!uY#*?S?zXUx4pdj(>9dd*1V&@n779>TkPq{380^_`CQ1#{XGIwU@q#b|UM; z@45FqXz6Wl8-MrCbM|8%{}9lUn+tNeQ3l9^RGqa6;6E3T;Nz8TC!#B&GwX}}_%GkS zw)W!UmG7FmZ;Cv1>fpt*1bXGJ2*O_4|LCq8$xW+4<+iw}D~V`(YUy`@Kz|wC(u#!{2e@Gj zOoVSy+v=t0TN}G;q&@fa%xq|Fwbsg1bKZ&=SITyxAWV|AnzzqG_#<%1!pr?Zm9%%{ zs6uj7kx|e>K_r52A@$C?Pn`l2{iD0@#van%e%IUIj*L@JTm_qVzy0oW`e2^ykmwI6 zlK@OL>Wt6}r@r}t_J0?@*naS@$@V8}4}A0LtH1d`ZPT{l7sv@1$I{1MmOhn^Ob`f| zC-tHyO}lIek9Yv#@UFcZO_3MlpML4DRhR7k@66P7oqg|1U%CvN0$;lEwhMLrtN)7L z)YP~+zTuq&1M4JjM{gRx4R0}tan4uptHjIQpZj?3k8;oCzJH#2aYZuh06^qY6SvcF zWY+kZdp`=H9FuGYFmr>FOX(z1VUgu>QGQ&<=%IZ2AFrI=Ju*Fe0oCH-<_%f6+RC#+YvYXGQdKXTg#1v%F zhU8|7HLR^+t$#q2ic7RuE6#3hV{UClL+>lPZIVlnMhE9mUjL#U-R_ znL4h?*uARhPMMiyk~cM_(XtppEVipOSO}@I0Lail3Z;mfJF2e^b*^iTyjokBHw{In z4CIo7$rg;#@g3CnFj;88yOavQ?wRe7thRRofN2WLcpe+XU=AR7evFmu^#{ zN`9#rxVmfuRL{hi)DhRc-FGi6f+AtKJZJ(BIMmh+U zbAR8x_nvJRpA>T^Ko6xg!cjMnR#6Tb3HdFsfHL@=#-5)3>Lo~F{O|9iY zFS};B{G&?c2Oyk)#SG?^&ELmDMbE1W2Y-nF0fe_w20#rn_M4n5#ZulW6*c&EPgjQS zy@1v8PJqdPaJVN)<9Uh?H+{Zb{zsJv1gCmM`}dh*OxmGOw&bo!V?2}LEz`q>0K1bc z?vb?9Dt9LEGss|9lzQ`Jdc<-XgX|I=i{J?&wqNm!n!GP2O?_!`cjD@M#F*zxQ1;;7d3=tlyTD?$qOtszG z*PNnc*G;=Gy70goLf`kVIbfIsG{x0$rL#C(GYrK7c+$j_V$&e`JTNGrL6{iz22`U| zn-5)h;lZ0@rdbDl8_aZu zIc%`ocw)KzTv5i$T3+IjWLb(6BfU<$DN3lfEZx7%OQiilFTCzAUiZ59)-dJB`PqBd zu!H|7`#JvS?B|Ek?c=wi+iy`E_9JxrKd9*w;{+S#DoD=6dxqs!{k=&`= z&AGSceufkjq5;~AE<>+EuSdUv-i+Rf?nUpHJU8tV*?B?|){Y-`hkcoo(n%RSpZF1@ zewuXxurKPu?m!-cbDF7(A?Oi5jJh)YHASaT zphW7H&1BFF*tQpOR!-pQ(%~w&mxcuU8E>c}xjQ2c(zr!U>5Yw~e>UJ@cOtHG95i7R zw4*_Pf$#t>^urMpu>)Gv!XkC#NQbzrXhye2{iff8OET)!4Mi7@Nq<@!Mon2IXe*fm zH1eDMUJ!!z=))eU2i{&x81=2$zzc8`XghUV*M*|Lp`5pcVon3dQA-tKSO)xEZJ019 zc%ESxBMP=GlLrhy8Ay&y5;IK=D`0S$peiO!rh@4JjG}Rj%E0UxVkSc$<&+bKbyqYs zP)nX6RMnDBVXk7(RDUpj77LUWiieIa)fCNZ=goi^z`AXRF@>qXlw}kRQ?1IFqf(11 z+~k~6wy?f`l@J)n3VqJuUPyvu!SX3f-f34#s%RIcTt(RV?Is6%0k<%*W*L?Z*1*&i znOS5}6M;&QMOK*1N8kpGcdRlfe^EAztvA8izCUXV70zQ4fqz}E5fwAX;0B<8ML6Lj zK*7N%KUORheODEt?t3LcR#el>158`C%uc?_fE~sQVofy+&oI;)=vqQZUSpI{(2+cE z0;mvzQqttAhCydDVM3w1oGG9pOamh*l?HZ)Vk1vvMi0W{5@C#)mQE|nR$#>WeV#$# z91YCadTlssP=6v~BMuD4e5GXZqQW$@RfnTnM*G^7V28>_GERt^5A>!}iUtXlRzZa- znOv&5Xi@9E6xv^BvPV2>=RE1t2Cxlc^l=Gf+9_U<8jk zI4i7bDNH~^8z%ga7{-?ARDxsr#W3``3)F{r^j7tS2hDOCh2q~52L%Vv*in6eD;rZRfrSIA~H?8Q4h3zv3u2uB4 z+4B_pD#Qo%b&E%Zsi^_3VgqA?Ov^8w%n%(Dja&{^8{`x$d9gYwP7|Iu3NQP@aFpft zP7Q3>+Mey}meGu+*}tK7(%ZLIPlUN|?Zo;V41erDKtzy6Q?b^Ii@M{LWD|>t&uyGr z2ZVMccQSW-?l*Jy$!I9h^~_xPinNY)Z#yB%}khnSwf*00N4B5vAa6xhvBtTVd+a9<0H$qRg~3Ir{u;9TCL@ zD1Rmj#hT|^SAy_f1geO>5_kc-h%kDk>w2|fLD-Z_L9fr+re)ifc|5Gw=Nk>+6Y2N0 zLf0)_e*~_0ReC8yoSuTaUA*u7>#jS0-}sYAbA4AsK{a?RsD@!Rz%QvzQUbL_4DOiC zdM$sy%IGw2QO0PCPgADeAC~G((-As>(|>9;M=h2yF8_&q;Cy}Zsfr%gG~N^HyWkQS zq3t#l02s%#;;%RB_2#<&dd<~!SF?k_hBrKXGbZx}LV@vK2ffo-2D<>ZY?N9eUwT>6 zD3d=C?nz#2y1$o5Cn=c0Kqlc z4>*O+ZJPrMMte*k$L}0(6b(&gKU=D0eLZrl5QN=^QDshVZNqRAUeyQ)X^Dn)sii1} z4cH5`vQBCR(=fv$-Ak{$5fmM*bbmS($~V6S-Lbr_vax$KnBMdmTnk)eI(H~{lVl=k zM0HZf%tJhCyv+KikyQW`n_=i6+bf%Q^O9z#J4}-+ZQcUqAPj9Y@3BJywRH}7=gH3$DF8wyMN8HtpcDV z*mS_65xjdEtjUp=@`u1scMgN?@N7vr>FgFz_68Hoa7HDBK>CRaoJI9&LABIN3e8%3 zuAA&i3cX4*nlg3J&!E7NOLc}vmeO(aMrft7Yk9Wk6rORVET!5&1N^ z;Ky+LO>yKYv-CI9#M?rs)LfyeN=uxlb~%5fG{b_!SSbgE|(*06$Hp zW1$&N90S^LTwG?BJwW%9TYz=-)7T;Cj&v@Okog|6=h||XRc8=-a#oGMiCjAUG;>6bqe0jKE8NXUP?~#~ z`thw0c+^!3wi?JrEO~jQ}fq84s90Jn?fslcIYxh1Groh z1=i<@e*lx^EH6wwPo9#J)qFduApA6_&E`9%hzgU@de3Y?IY3BLNkY`7JFM zyz|or;sVF*CXkD*)`so9^uP5e$86-}5bvw|dCl_Bhv-k-9 zYU%pYMR%T0!V{tN)xsAcQ}<4#@9{3;R;&lf8?Pq$z4=hv*MhpF?l_`J?I9J&&$F_uT4Jk8c0r54Uf|ZSZ4Y z(=ha7EthKzA}P+oOsD>sfi2;ASDZX}{-M5o zg|_YSPhEzbLgG2&e?gjO*paDK&|Tx|p?}>M9@)8RKj#Tay=l2t8U+*5Z5-iy$4@=@ zAX<6w9}ge?;Nipn09w}?|Ky$W-{u&99{=wkdFIc>YdeGJ#mDct=W+DH=il?5&tvb= zBWKPWd6YbQ^vs!~k4|JH#9xC}oz88|9hEkFAPp@~9a(U|?EjjB%9ln0>s$F1)3Kg#G0pHph zt}XQ6$lRccfkg~kx;a*A3a^RQT#XY?d({mpHMmC(uHJTqg+FS7snym=fTG#gX*RDE zoS4|2rn@%P?x;=gZ5%pyzg-Me6@Ls}dt{$dXH=!Ew30cV7l$ossGeg6*Q%TGDhodk zJ-wJaFLxk!xg4o(Lne933iaEwsA*%Vs-dbGl8_OkNKUgz#|a;02UChD_lBL!116JV z`b`O8fQw3c(rFX(r7z>|k7}Tqzzi|E0hZsRxXCcr0os;1fGxTRCI#Q zW^j;foHRY#R1MPuki+px3~F$BA_o=x6X0n^&I38mp-dO~VN0fxHQbKq2xyg_+raOS z8jZz9WBkYH+v64VsT+6y=6}toJKnV&-GRPRhXafC-yfercLw86+;QZ-d(k7~M^SlG zA1#qBAZy*+{@lf>Es~mOHX|z)^s;0Qsgv3R)SRTzrm6GNfj(-=NeG<*YzMuRn$N=E zA9OZLOXk^p$j)z>E9bLS2q5CTr?eye4!SPf3c5L6hcYnwF{=K&*Q+WUO zHDD?!YdICyRLv_tesxr>&sFQ#*}r#rr=_YZ`(Io0y2rO4sryVjy7LO?mZnh0f742C zyZ5%Fh4*gXA-_)n%tB9Nf?`9v*Nfwq>a%tDds(a;^hcaq%I%ONER8Ho($&*C4>KEz z(yU=Q)g+R%0_d z0sAc^hKTpvx-VIsLd|V^<>xBCJ-=(o9L{cDkzRZ3!1yuLYTo)=zrGjEd1`Zsu58_R z>u&V+$yM9-?nov&X@P77{`nT!XHe4NWD>o6CCwlUh6GuVWPfr1c4zTjY5ciJQVb~Z z;bxFG#rQHFpC<9hFf1U%;XqDNO=nB5rOO~lur5jIBq}R+k$IJYJOeS|RA`(D%>#G{ zcw42KDTxfOJJS)qnDWpovQQRiO)ycc!Hm7TvbE>S>PcwRp#G7InrwFo61uZU7Ed8;$0A zDO3djYZ0H0je@W&Ko%vLi-w7APt}&aSwQXZQ0f@w@q->yG((aItwPOwbqd=G#adi3 zHZ*1f0TG1yP_MJRszDk#KgAKL}0Gmiys6@Stk7oSeS! z{K1^Z^M85}mMV@h-Cb)^M~eQ{kbx zC2g=Y-zRFPDH)Prr^)=%Wzx<@dX}#-$i^)E`SK1UnQbxxyC};7wz0#PmZjnw zruB`Qa+QnGpd)yDAX&5Il{qjK3}e+G z?Crb|2*+tFo^J@m92=41%z0W^oSQQu6~i!fx8h5MGW2Vr7tc#-0$ywWyxG+VP z6WDLO}T$Vfnz+nI&YH39gnd zpIJ#(;O3&FSTP}1Np)OIRh4zhD!`|_O`+{(p}d9&>TaVyqtOzazK24+34fFxC@3|o zy38CVNMQLCT(XSlE9DSqqzt(s0G5$wIT#xh#0|!3r2D8~5S26Hl?|0UBFM|M6r!k( zsVVc7m8n>Dp`MCkl)-2@0hLWfXmpJldoIE_l(T^)N_9+{&XA|l)9FSPuI8VY{%4X; zrdlBsO7`H}xem=@m& z*dgfJu1H;anePCe(CG#89fi_+AtTQN3CIVaR^h5N$pVbhpd;r;0>)aNq;s81xR%;+ z2z@n(dVb)`B#lI>nh_La9Ys*qWUz_?s7G5WH@KV}gu%Gw=o>CyD70%v5rmtW9EPb7 zo@Zjqwp9Vc520;z9)B0iP6(PrMTQ*2vb(axBy1M=H0zeCC|yN@DLRY-l{FdxseF(X z(0;ZdrkLU06~`CG^p%J@k*?Z0{s!F5n}34pVPX|^A`42HX3Cmy zBMm=8O*MWoG4d)>K@5e;-Ow%q$O0@y0e1<(4YV*bkLL{2RhdgoTQN0Dz#taPG>i0@ zdLr++PF~KVCl;tTyI>04auwSEojRCbnw7fDMrs~(itQT_VY*`amc?|!6@o7nswqH% zsa#`5jszjcrhhFMG+llCF@(>D3u05wA;)5HA5pkQstA33&-r-Q1Gd4CWzlm!X*?z( zH1DF0m2--xx@!BNr}7XPstC zNev|Uk=bDBe75v9z31vOmWNk*u^Dwkx4{5mnf&VZ0>Vk7hj-8@SC zz=*pmAP1m=fr;39peCN@ilv3sIOc|}a5Jy9VTa=QEj@1s^<=Y^Eb>J)QN8BL zLEJTgKDT^F5w6$P@+Nnd3S@O*DLo$O_Bn2X@V@}-izTx3{50#UzaS@fvX}qpy!^+r zjg^g+Mt}N&+UK_Kd)e+cG$vb($=}9Gy}t6phWt$Tp3Tq0Um;ZH!=k|J4SG?J3`WvZ zisI9Y@wE?r?vaO&#RNStzV*QeQRuw*n|GfrH<*$%?+Ae3NW~2myXbo;kDQmjjq>B? zskU4f?=2 z2Wgny%A#VO&D?u=8USTED?9t^O9_}@I>0?CJeD5u?63qyYc$IM0-D>F&?hCkUO$^p z2PXqZ0+EwKm1WH4u`!p8O#9noT=qe8}Fn0hl|AZFRRA1 zY=3IT&iRU8$cKTVRP$00 zF@aeEm8Wsb2eJh%uWA}mLrtdLaBOiEGzi6NTrXZ{0<@8S+=y6AB^2ub95f`uM_^AG zqjb7j*d|jDR(CV_3i&~>d*$kXLTNVfhJWSwFpmQKP|fK4@skGV70Uwhrlt$sQByDk_0lv>RE@#4+JE5# zJxiulboU+U5{22@?MH!fE`62z3^?aQWe1Gz@rf^Z3i$t_+?}}(Fb+eZ8-}Tj9?nF^?RdC)ns#xqE5KUHe`~b6y4Dp zPL=t_MM9xai)D;6?el;_gLl~z(bjOc~Vq_5^4U$l0F=N@)Mi_AJ3YqoFHr1 zk(});G;MaNIOW*{=()p9fK%lfrXInf(wZ)o!9c!C0!&qn^CiGmAieNYH=KEyx@Cg^ z5H;_rBo=vQf*k~93uNEhmtU;OHIU>3RVaiIRG4KhbD!iYb%X)D|A3MxukHl|d9q{- zP(DCcUO!(UV8|3kqBPW+cWBXo8?*W4stJ2F)r`SdGizYE``qwoNDM>ht^uYz54Der zyiQ4JaUp;k%E>>(FsqbmP>2;k=n4~YdD?HG%cPUxJ{Es?LS)K02`sr{k_y9-k6*bV z`3{jrorEepycTNV!?k#^j))-xFEBzy%-5U^yL63At~q(uU-c{kDFuzS2VDg0`D*kg z^fvT6=%eUk=n?cE(dW@0qd!H@pua+Yi~bvW7X1_Y31G{YQvL$00bAGuL>u7(j&T*& z@Dy(0HlBaQOL%~{;dQ(V@5hJmCHMrs3}234fnSMVgI|lU#W&)c@Eh@)@fmzO{te({ zZ^3utci`W`@4@%u2k?XV1Nb5QAMnTVC-9^A)A%#^5AoypkMR@u3-~|dC-Kwx8T?=H zm!&o7rW5vi!@)K*fbH%M)R#Fx71Z07#=d}^_T+y8fFn3EtVtehBM{vrbt@*ru8cp+ z1^)c(Dxc5dHtgu7LA$0Oz)|?yf+ibH9X4?f45JD^2Tye!!|q= z!0&(NQ(6Fz-PCo>gF!pHX$1QQ={`6m8Dw z-;R2nCX}mdBY8jG6j6c(LFkLDti4cl;8=fP%N3ABf7kI25d-B>}(SOCCM@1!ut>;IhtSM~8o> z-`HOs1f%8jgtKR3^a4&@8!0nTJ%Ll-Jwi=T7zv?@5Gqac5vqi!aAXc6(^JJkP+R;a z7?ACcQugG;Ju-P={2T!WF@8?!3D9B)aOn6!P7+Gc?@^4E@coOx?H&|)3 z57Y|XF2Lv;a!FSmMh84Nb}(uJPnLgb6N>SE4EOk=w9ez>GEeqXQcaG#GUrmPGU-hK zmGoSS+dY+1#LA$dE|(XXlGy(E$3R=@_(z1)E5|q@-3`1#v2EB1A%6{_Yw3cuAaF?J`JG_G6%53JTZU%Jt)?r zm{zASx**LD#^@f|Dj}2(xm~nXCc?rErKwTUC2OP>Jx0*HT(WBX^zoxd;HrxcNy2o2 zynH`}o*{eT=Xq=L_ix=Hmlw+B{2=st`61_P5EA62tw}p;auB8G4Pj#m-b32WE|Yrv z>|HYoRjrJD}PQ5z|jB$Zq|plm)rk5`7Y`fK$~k zaKgVRyZHhBeraz-D4T=Ek}?mVg5!sTe9rjxItZKs@c%B52NaSA0dh(S!Yyc---et0 z-G2?gO7XL)m!r(fM5g6DiRpUkp?LwG`2O9P9>EA$JenEL9oi>zUdJ^;6nCAF8A1%t z{t;Xq$mCx~UX)%bU4%rgo&sho6M!Wy`{LJO>r!Yt{Qdg)o5y9x96Nd>6#{f{U)ove zC*UP$wza3^_8(2n)y zPZ9>4PTooSa>bbi2@ETU^u`DGW4641y1!>X;`7x~3m3+Jhmw7U*4a_v>cxZo2<>O0 zQYUz}yzgc4Dmzz@vG!Ioi@~MA9N$7-HZ!8%?#Yz@EPWF_z5mSq18X}k+;>|twSWIi zr?IrKYiaRJV-YVTjfLgM_n-Og+mkj%`**D0cV<8O%cYIwmf!43S^TrEqyz}Z$6EhwgXn5Og<3C3)#7|DRyG1cXZwLHK2n5v$eKRJ(|$%VOMu9}-oBOWfBi!Ju# zG7;&zm8)owPL59}$Ty^qY=Q$kX}V?pleO*|G2#}{)AsTbeKO<_Rh_(y8xfa9hPfecCtw@ z;W>X>x(02!IEHM}wQLo$C}{W3Wv!>h)8S}oJC*BDYoQ7T>LrtgMmIon{Ul(VOyxSc z)!e?^>m{p`v5kt1Ck;}Fm$=z_jcHz-+m{@!5p@D@vfi6qFDqLLH<_$`FIPW7A{|t- zawUnA{YDsnaT1#38=fL!DiA8(eDf@j>fUa~TKi63wvDmfy;${H>+SaXf%R5v-EOI- zp|#|EnrTJXm1)=jod7#P#J@BT>hwOsPg2eo!~9Jz{Tk_uw9P5rtIlqFJJj zfnp#{DFng)W8?Qe0~<(JJ}19SV!|~Sq}Tk%VrzV#uFNYsK6ax9-v&B*)8zLST`Y+7 zf3kVin8@$7`0kv5TFBWd9T>yu+D(lCOXNaMgI<(=hN6-EPJgi^=$-k-!|0ZmzB4^@ z^x>}@JNht~s`m8E-1M;*$Df*+!FRtnH}le8-g@i956^wMd*iL}@8P*4=f=$DGs9dn z^*R3HXR=@Z$gdtd`cZDcR#$mWzSC_)huvDX0(Z7pLT_|7)EjLs`;tv9PD7?uxx{Fi8Y36>FO>6- z)71+kCk_3HyE>b0ntErt($N@gD%xImuz&`wkzCq1o3@%drFoRD_?f0|lgUXSEX>(l za7B89$ULPbHJxHN4va+pClQXK08CdDmj2HVzMgtkxI%PL2Bw@Qr;`;*CIRe|JW3}9 zd=kdd2jG)wN*pf|`ef}k^V}+fK>jsBLi&IIG$ z``*3pzI}=JUPNR>#+LCS_a)Y<%BoDMN+p$4o0b9Ex%Zs^*xC>(Eo|N>34+)?^$2>MSjIm*Wn>0>k7#A_`M0!<2yf?K^wG(!&9${AxxcwaS10djZh}^~ zarTMFnfibGtH-B5%v@_uZdX^{*Ib)~TNiF^9p3!PaCi#-dcE%qlVKTNSjBv;^gebO zXg-6&p~A(5YYI0P3gfmCm$+CC#NLlxhI9<14pgc9&WAf}I9R9MVP7pac4jSLvkx6$ zBQb@8UrftPew zPIj!yg;(El;LyufmyedonbFIZR!=OL<)bfr*`WisTzz51>YQBZzQpQoXW7AQ^7X~- zth;~RwGLi#@qsr+-qE#}x$z%gQ8kUNwA$a}p+(?3*F)dDy6`r{36657L|h{tPMznv z)8N5g?m3}isN!6p?g4w{I+sh(!Afm=WNp=m?W*k zt#ZVL$#jhi=Cg(7d;|Ug$!DR{LsK)Umuf*!Hn|<(G}aUCxEa27Zh>=VF-@>QuTH)| z$Xo?|JWNA#;`_m9lE7COnsqR9N!76hlwwC3J)T)B7F(&cmWnZxB9y*Uu7#~OTke0O zPXTC1Hcu=aw=&Q`v&@7!3eLl0+Tv2JWC2qO?eEz=C$dThVV)D5r-+BEU+2U;;tbSD zdyZUIEk_99VCc3lHG8HD6+v%&GmKrK)6QWBHpp-m41t?KU6rRrg=ytJNx-~k*%4+E zV;*<1+sbJOw=6+W;s(*oy-pqHF+6_}Irtz`bfJi1Fg}k}ipRj9`S1o*JU~xKD-ES9 z`?b{1cx1Lr(7?4yrRZ7IHVO5M3&lpWyOwY-5q`BE*~0Z~S1r`ggwkl(1qP{^6gPx? zssoF*HZ11wRF4kL0h86B*J`}+26#W}xKwii#G=oqHB_rCUal)Au#L+LrREIg1H zh)H5XS#HhWyvQhexOt;%tJfOU&C|-{N(dIB6Eey6!QA886Y#nm|R?`Rq9+W zTNUh9SNQ=?(MfZ>JGEPr_7Z@R1l zlrDZn?;_|WXHF>$eX6A*6Zv5XSBm zlscZ(N~b!_GJUG>p2CBLKg!Ww)rL_zgQ}ad1+}Au%w`5#JvH3YWQKHsHxBdc9vIY< zO!eA1qJU+5N2Vl zq9}lwkI1|9N)mBt0!x1|InW?Z$rQoq0_X;VqPq?wPW^zUcY~5$-d!I$aA>XW`a*@k z!$^Q6KeW(B4MF3hm7S$yWrS)&XE2TVRTS4C(}e|$i9#8|G=kPDn1&$s#e74fy6gQW zr@(@AhWn^Y)1?+VhAFA!CV5LkI-F^y6x@_PgMly>Qc8r52#J5pv|z~X^4dkmE~?pF z1ctS|FxMDJ9dYI`2A)RJGeN^z-@MqcbwmiUbiKCrBGc1}&NX6!WkW}EphDS!amuoF z5g9HoH$0oiz`KkntD~W-<5B-M7|f7i8UkR6&~k(Qs%}WAik!-sfJG{r>4L(gg_A1& zRQY@=WO)H%K-qt+iYK8%Ge$+K)JVfNt{NduJ&aqYH&0xu_NnBYN z@wH=z#9FULU(Q+q0`sl+CPresaxL0pPV6u{zd8wrrt8?DmLAj4_*B558`IcG3S3;wsV~~S1syR>P2&t)wwP_ zV(z-@_VoEX*{LZ`VIgY9O^nMy9M!w%{JFpXTa3OTNB-t-*vY><48MhG9v`2L3w6+@ z_7yHH+)(%zg; z|7)>Ugue#b+d_Zls2-SplGM|q$zuQ1fkT7MmPXF&;E>@x#_0KEpUIZx4TQq+hpk=+1-BP;Li5;HW_X|x{XB{ zQ$HERd0iu05DxD};h^i+#2evyWs^&Lr(AU$OT4T#Te6rU& zdDwO?IlUnd>cz;nDw9vuSL*QhME(zfLp(P$9mfn^&xuOqh1N>v!216F(cS$!qeEMV zj$E}gx9ys4vorb8;zIL+FdU77=z@QyA1$rTMfUc#9nF=vVVXv=u-NEy?d_A>&f-GW z4Gv#E`fsM&>NH=M)a$GB^GW`1ihKHp^ou}g^}>O|)rA)oK2-Qf;gf~W6#k^}#lqt- z2K$Ks@uyrk(pDZVF-zXj9%bV^JO;N@r&(?Cz?dD9bq0OZ^px9Aj@gx-Uw41ix73oV z%9(&(n<7z(BI2P->U(gU$UA@q?a*ExQ;l3`worj@_=HZ@OZSYy&Hd#3m%$+t7l)hi za74dy+%keFkY;^BdH0&N_SV9@sj2AA_TTHW+A0S%ru*wAu|UEYMEGvWr?p8HF0TdU zR@Jo~k9sA~=fp5HYEijP?!JE*1siKMgA*sHfewoPx2Z_Dx*|j;+xxmw11flUR=#Wa)@fScL6FL|mwyvGB(-oM~VKkt}pXom{`60Z03O{_K^=2X7+`5fk0dKd#7xJFXUx(if_*ldf zcTbNO3w!!DVMbxCFa`_uUtnpHVJ;Z;TM1fw-FuOqDrOLNp zpln?95C*-p1`}cGudx?*o{cdmWi-X~N_!*n{oQ6)R#zjBd;ZGjKw~1W5PG%l9~@Ld z3)H8DX7U!d=zFH+-m#Nk3dU=GDZTZ7b}7}m&3$H8FYhdE8q7zh@Wr-tnCWoGl9qFO zbAdfgv)v8s{&C?sC*R<~jNk;Nu&G{e=_2O>Tmodqd%F z(A0mw@NWvA&m+5kE(t}AG;@8`W~(pgYXk-FAY<5mYRxe#^$9@?<`L3?%pWz9Qr0a4$dR6M;E_aI|8jHrXNT;UQfb*FB&tv8p#xV5M z)?iem9_oL5Kj^-=hUU;ino!0;Jwlg16^RaJ?fd7_k~HUAYfhy&S|9H2tNQJrmX>?H zPWc5ZzEOmm$mA)biK~k}qTg?GUgc1F`STbS!hj7>7Lu!=HW8u@i1-;PSqRp2u@Pl3HTPm^&Kg zD0$PUo9X7S@{d;1Vv6J0wY{~q*?gGLPch%rS)K(;?S|^f@7-yX^kn&g^ z&FH5&D5-PBg%oj+5g}Hp<#L#U0oSWG>ggQlP_){&q9lpz za@hEs4l0WyffSk7(5zv#?AXGUj7irv!JdEP(R(9V-B(W%zwD8>fHDY!ZQJFhTPX)w zJbAEJrIdz^vXjJ>hOY2z_A^1Hmbm4TR}p?)o|-&CFu;au^-?jmQzL9}w(xeRoECc$ zBTh(hIYRe;Axu#Q!gr1z<7F=V*JwsyU_eP{pEmh#@Fu_E+EE`U9q3IY7&?lizud3O! zwq-KtkcwkjZn@~=?qjK!*vEo2==y;r-dF80)~j>Jlfkm@g|edyO3GPm28N8PQQ2$g zF!Sm`HTHpf`m)56Oqzekt*Vn2(@=kKR~AJ%<41!q5Z+c&@xi)gLYEx0KQc6`hA25d zE5Ls%S`%(H7>a|3&EiWBOQ+U%Iu58mGaLlA2J#J2*%r{U3!0c|0t0c!xvnkXwL-gU zw+S6<#Uu2NbN4>A9>sC=TYviISH0@aFE%f3Z|uBcbFjkJ&fWX$rBOTT_11s3$Xf5n zksqxtj*~r`A_e{4F0A4_bI+$Y?*v8Rs>Ex!s7e+3V=x%*FqlIuZSFggd&ajWpCUxY zw&BV7InzsG)N*7{46G)7S7TqRvF{?h@S4em)3fLjqOLb<zK#qc>6IJ}bRWtlwkGDfhh8c!JMI8v$q<{^Xt`yqbZvf=xWGT$#vvIB=6yt&8w7)|!J|09kXg>ls3}euV`tuBRfw+j$I*%qrXpbVCt&+W9SMkv_~s_j9$+sYK?7~Ho9ZZ?F&*#IuU+~xfdx|ZWo;SL@5 zal;Y{9c^Q@1tO;6zGojSrXgs87>70*Do1uqKAiT|zUEGj*9`jNF5Mw@+VABXvZ~#< zt%+Nz*mX${-QRyjXgxrcT6|+88r_V*=AWcM9H*t}^{W2g(s@SEh{$ah*VwhADcQ_OKBdc5HGU zCuRmx+nKHXMAPM>UOK}=pdV#Sj}*uO<5d&I2`;loAVGf&gxD#A#b#q3Od(CJ%xt(& z4>64)#id1zVbfGnUyAPN8SYxboQgCIMU~vKaRUc;au6|!p-U=e_tk7>QC}uZGK|aD zF(gx9kShEonsL5Dbx8$!-Vv-1Mov_P%{+ zn?B58V%x%@X4#HGN``1vY)^I|yw8)(9U>V5JUM`6@LF^j%OcY^EE^ zn-ufKTY?%GK8isOEW!0~4uTgqjdfBrH5do@3Z^r3Mj3>)BQe8{R!$h7N0LCjQ%2Z( zY9xQo*X9?-L4#pXG{(Tr22SO3C`%0vx`Ns&btF|)&@eJ1lAsyDP1Wa91XKcBmmu;i z)`y_)Co4mxaC8nHZ5UCKClFsE&@~+VH&RPdUJ-0{iw;%i6p4d4(`km zYRg)?N7+%_Q}>{&)o^+=e+cb|opI<{!v!$oc~mtcTPA@)asFt_^JN(e+gmzza=L;3P zIL=P3ATl3Oak`DImHNV_VJytAoq54VSvsJ!mhEj#qqeiL2xRz<<@rFTzSn<_E$D(T zTWM=)bzw!M;GHbzh7nB67<6`IbG0*oPB@S^vcXUw%*<- zb>}q?^U}NXyjS+O{iXf$jL+RVcWft+_T*C_6{2HNvsYSb0&6f}>Zc3MqwW=pR>+*Y z7;|;QV!#vlUCh>Wp$ik3iumYV+`@eIFji3dT^MF%h8#r7JMO~82VH1}f~UC)Hxx~2 z!KHh96^Mh>E9_$S1@wR0#`!-_(;Vowji~V|jM$^IN#8}A0d%SH^TTi-k?zqOM~zCU ze-#*7W~`#k-v_0YReXlHk6m;&Dv!=?@-u6vuRp!94sYwUQLdB*FX(}-dgO-jQncAc z_xblByo1BbAjZYLYdUu?xoMpfdmV4O4&F}9@(t4OgKd)(8ft&_?!v;U!daE67oorq z2o;g!go>OVf>PLN&YY6P^Dod9jSZV{K|9XZ@G|}9E;xU9?^)!Pm5kD?k8hu_&BaC2 zrq#(;Nzb(Hca--|O)jxb%+ZEt@fv&b4RzlDxOImZUxgF)xu`H7@}2_!Hkf9by6G7P z-ra^0LDhO(my}CK`VKcd-!wfJ?z0SGYQV~5*)~CuDG80}j-6;&v{&^F4|F`;fb*h^ zhswgj9RYvt%=xx3ea{rW6Q>fiL&M-^WD?7_4b*l5)3HIvhM~S)T+X{0jodHjy4-~FhA((P|G=7>{^Br;@ zXgNz|T`+UL7*B3j-`Evqu^EBl^#u9_w!)43E;)bkpLxU&R#wQWx??d2ncH=Z$?ZfV zt;Eyd8za})<&`2>lAV>}zU45oif4<>3-);GpRnVq&PUX0dNxZwqR@Tj_g2VgI}^$+ z9YMy@kwO=1t8B*V(6)-xgG1!m!-2uvCa&3NE3Lt;{f#9FDsZuBfYRlaSC5;LTK>J5 zv><;9mrhARP4C?iypgwX|B{2%rT)H!v6qr^{Niz=nRX8MJd?5S7?$IrE-uXo*ybHv zO5a3fOww83M{Evc!zqb(uO)w)#@Clx@oEShltqjE@=|l>h;5fKE3ei$ zoi>Wy;>C-l8gZ@pl2JEadf}y$PfN!S9gF_pitQ5@{mNxc7(DIsuf68ND`WR!pK3x+ zwNGDvs_2`(fC12}8bIvGb~oRY_n zAOFZ{N={EMhqqs{5x?Dj{yVwgg_~uX-bUi=+%qrSDwFiK$q%yMppUPOdSq^H_5Lk7 zS6Tar0hinMt7ZN#|3+@Q{6*J0lb1k~_pS9$pS{6_Pw!pZD4dsn?*N_TrWux5{u|Gh zc!yl2%9$;)^i;e%Fu6gd1kEm0$LGoO@@*s04`B4CsI=#kU}zu6wb|P^@RMZw^qE_F4a=d_HUixQtyvTGtwR^p zuiENr9JE~;MZx5;nv2^I0uwN3uHHIeUpcsH(-TryXws|#5psC=WxxC?J+VSxShN0$ z*dok}ThKQx+e6Al=jTBal`=bBT+DV^qFhY|duV*a>GZ*AMde zmy?-kG73-3E7UOmhDsBslhtV=e?X4wNi^%O&!{h(=DLr3nURig@V^P4LQ7AJ9%6qf4#Q6!`bmW+Th|xdcA8e=(L+N>CPG z2%m&!fcfp1xP_8=m6VhJKNkxgWre+YU12qq6B0NR0^?y!6MFxRn?aM@@`=@U_sq%l zN_uJiFu7xLFMV76(zLR6{LEr|{ieyi=k1l{0_JKOWW%W#)t>>F8k zo~2Wm2?f@oT#$3J&%F<)e;QXYM{2<}y(+;q%JcRiuH5DD8~r_SE44eRwy9KZ`y7dd zbq8b>^?X}1G&{oOfdup-yYAaPCriq9U8`!GVh%_l$~@D2?Px|dOv7e^y$71rkuBlt zi2|6&Bx5>o)-ZG*%SYGCl8Jm6xGltu}W8Si-HwRI_`go#E_uh3Pm;fU z^2u|Do_zATC!eHG{_@vu#TPjNZy$%(d0p&U`UpsWyd8|Ki`ub@J3xn(ezz_9IaAvv zQGT#S;52G93ZY3Y_jadgg~x4-W*DdH37Eb`O;@xl;ywsPyicXuhWU&uwLf0HX9@Hg zsdf0Xvcojplx63~!_W~l%Yf*^UK(qRcI4Cb`nT-G^aI}dhP>Sa-T8Qr0k5+C8-127 znRobquFfvpCr!`4i9Eiz_+`!Zj@{wcB#4&D<5yGD_wV$5lO8v1vvkwa6H8al6>mFw zwAG>7D~~b3^renA?5(a6{l+tK5WcR=6zRvq)9g88Y-~igi+M1|I%#8Y z$JD3*qTaKa6U`=9T zd^S`&!!FJ9_fiFsglfTr{Lm{Fy-5+?$>N_K9iR0&OP!i;hGk&Rjv*}HEF}ha-7qY6 z=KR`xVtUfjL1S3(m@~c8!>3H1+T8rBzk13LMsYq3N=2C1z!8B9Y8KO>;Zzpqlex?> zb;}Ws&@@+V$v>$WS2+*x>k;Uk657ykFc4+{UC z=%htPcTOvUjofu-{=1un)11u}`o+W)HD{KWBf< zzQw-Hp3~;FmbRo_qMg)UqPW+MjDrYk#YKSGV+a{gi%2 zKdb*M{R8?Z_0Q;E(!Z*IQ-4PPuKpv=z>aC~1-`^D;V1cv`1Smk`CIut`~m(T|0Mqt z{uTaz@E-^U>W(XFVnu9#eK`_;SBMviUlFeoZxz2O-X-o69~X~`zYtG}zZL(F_(!8+ zbc|)=pmD^w)VR{P!MMeEwed#dF5`EM4;lZ)_>A$V#(yxLG`?y47vtN;_lx{A`=*5mwWQ&)&(w0Dx7AVPMD2bMN@Q#RSR5K&iANB#U$?a;qt9)j77)rC_2Il1N+GYTFUA4dEFLbD+;_3>jumw zgQFP!oW>YJ(H_BBtoY`jj~yda;A7GqCHZ0=bR9+{q86JXrtCC->*^>|_Y9}K2Ti2? zgcmXN1w#VjE+YPPffwXYfie*!a-0sv&@5d2^=KFBF&rzKaR#xAC{`O_hqTr5`Dln3 zzBQ#LBX%#aSA{-(2>-CN)jKMbn_FYtCdMbi)6($(Rp&Sni0cL16=Nq`3R`CixQkBQ zNGCQTX+gA;4y;v;owT75n5}s@>L#jxdV}FOZbSdZ#TdZ|;5&X! zF%qqZ#OI=$QY-IlT+Ga^dANVvAA!OJ)$6C3K!KDYbZ3?#ZB_|B3sm%Y+=n)Hw~Aso zX!m0nP^j1lCm5F7-2~}2#^3`?!K7S~bLeCYW5w*1qYUH)v|MyCi6%~yB6L+d6J6-( z0a!}8V&Bhy)jgclF>b)(HcKnxNIhNXBGuBZ0gM;!7^~5U)s1nxi^HWTXROj%c40Ko zsOlqKserf)DKd?bj=IndV>Lu@YgZu5v1;Z)(uXoq==yFv=&FIjKE~)4+z*CnJ{%}3 z16q}LF_6MI-s<8EM_6QpIqi+(7Vl!mfUY{`qXcY!X5dEgbeKljIM4KjDy~q#>)mV% z>0Pa*1K9zwq-yI(#T2g`07%w)c~r92!wH|b%a4ki@32q z%9}qQ-pYL!uv?i<4AzZW`%5_L>&s6 ztr3t2-^jhIVHUJOmcn=eeW)EPOoNWkfW~A>ok<1O6ROz;S|4wNT}AuYS7{$P29Btr znLcL50}cR0T})ewRQsDMpE#xxN6iA$2ltV4LaAyBcl$tlz$UgpYHcaYe;=FE!byR2 zg$#Cc3*DE7Kp6;@3S^6P9rJFlkM#ki4g+kqdJ5fF4C$SO8df889fr$6WJJHzM5BFA zLI#>3g*?SDsbXqCIfh1Rh>WEWu5mM8Lr}3Cf3ys-@MD@MUe?ih z=q9+8g2JdFJiJBJrqgA(|4+Cw1ZAG-i(z*pDo`6vnK@=#m(XGkU50Vk2kL_}>@VsvL6jSYWY11n>b|0IbWK;Mze2#KZqUx(g$-h(g>*}heKC9w2{=iFH&Pf5i->i)lU~_rRr^9}2_Xue`?9pL*7#WQnrhg^w@BU`-f#h2_O` z3!00FaU(*K08Xd|7O`rYb}b=aB;Q7ajf8q5uhUgiJL{uj*=EA?j zSlXAd?m2>B4sZTh)k_qqmyx`m(Srwv2_Y#s7IZ%$@5-BvRHUA%C?A@26h0iH$~i<= z)n__;Kc%z5Q|SlPP9^pz)Z+656i|hpK@^UM`lnCF6NeXCME)b(`SodOl>8-j2M(+- z;Q%6(kPSkAe~*y&tMgc<>M^JdC)3Jd&I1+rj|oW;&UjiSL-h$dbec#3xfh7)2y~g# z5%wKtsn#P6LQHg;VfwW9q0%NMtJCt(D5y3@FyVxU68^I;;UfO$NQA0V*o};Rn2=8+ z@;|`~i9%$a6Kcj9DSVck{vmcaR{E>t`@pCabjhNke{38#q|wh~3xxuYqYtUZ!BGvm z@@~w;hHcgiEpG$fgoC?9$dgDy@Z5h1UrW>ZqCulnk0Ti?Y(`Dz^pEj*LaOm4RKP@i z&-7`8R0+8gIi8}C6gi=y67(hFO`4-3PA3Wx^tHgu)zqRU?#D=M3_}(`o+LRgADNx)Jh`J*+@>Ghqgj z!@IGuRJXb&;b<|;M~u#sK$I5FYF)Q+ zXiS~eh!11wx*%Bu_F&8+>SMv08bYLUe;Q%*Aqvzg#y1ntDk+zYOQG1S$8z6Ajd+X* z1BEQ6;1DiIer>KqF_8l;Vv+~X0Y*>E#J7PMpig8LL4~w>0~0X#NsN!nkOg5{7I=z? zQzQatysQN>^q^8Oqx(xhqKXo@ZAV4qy;f{XU(H2LQWKt`DNZ10P!kQD!A{X~f0>Ol z!DL3Dd7*?U3zyU@C0jFcau<&0Y7wT=!Racfu&K>FM`*|g(a8)C7{;=2#UczI zW>y!x41{EQ9D`0>AUTFJOi0X7a7osIJ8g7Xr7gwX;AYRe1Vo3X=068@f3w9s6B=m1 z_@WmrbbLwIB(M{Xq{>u^Qw>4-FsxNKm8ONx&%~KW)PB!3=UX@oHjWT#ZJLS92spa{ zBJwD1WNVhNfukZffl8a`hRsYPrkZOA7Z@`<6(x;Y?IxB&sb6^KLe{>{OsnrY%vzBODyn7~bOB1x zCHnPQIH@G&El0govtj62$UKgS@YoGNr3P0TB5I;KJ_zO&OiF`m!U2*jS-?FAb5T#m z6wN$m@i|kIFi3V}1W*9A$}lJnqJ+ShAT*i=m9dN>NHv)0k&W(Gm=cI7cLicPK)M8u zV9q9?M44h7Md&+VeCjrG&*`I;{m6?;lQ8@m*;i_MQCbdut>VBL4^UmNmbGu)SOY_P~Q3IZDFAp zFqCu$j*Hm=;6cElNTX<20Ss_aDFir`q`-uks0J$215{06f9Xn}hk2y4yuM0zM&eUw z+0Y#t4;6F^7K{YPxoH3&m1s5LEC*$b8Y+dAiE`UYJk*vPAQyyzVm7dLUGp&ijXpOQ z0M+Qqv=E?zXhh~loQJa-+6`(N@!?{eQpl_Y${Nf)%wRZe#H=PTH_!^ZHnfT( zx}An|)Fy^)c<4GtP-akzs$h9FSQ_@ct{|e&b`q#>f9j@}&o;wW)=H3c6*MrWfUDojgO>&~Qv8o;S_K&H{~y>B=TU?F|Gl zv<@T{f6om_q&=b*0Mx_LaS`cDrCm}ss1iSPraep4I29JOvUz{;XV2$if&Nj!Kwo0g z4&Zm#jMKrMkEqH{gz@oh<&Tl0vgJt`r`|&2zH-s%jYs7BuQ+upsXuE7ZW~48!mPE_ zdBbAom^6zA8#R%eiiZKHt~NTu2HMEcENA+&tY6qJoGjc}_|?MQxc{~XGUbt}b5{ytGNyWDk{5{>l#Yyr)Q;b zN^xph+!S8L)6riN^whv`6IqNLTiTeve_VI%LAR;t?#5d-uAE>fUK;?7P+$;sUd|2KAyv5%jne@~yh z@W`p-Z(hjo|7E|ikdY@Q|N238$3Cjf%K1HJ=Q*!Q)E3=#(;{uqmCyeEnd8ULkQ*O+ z>`rn7et$xWZ++|J)8z7VU#A;ChutO%r9wl+_6E(Mt&&o+emcfK(Z)sLHhgY(+wi|F z`cKo|Q;X}}{aF=%vW;d{cg*I0f7rLNY;MTq%T0HhraA3))5#OR0zZ$uzOvJLl2n$qX0aZa z!D@$MBq(MJQ9BIr9!73I0SX)nISUN5Yt8iz< z_Y$?$q+kZp&Hb3Yah_uOqp6F1?p&WgsfbJ7d*Hkyl|YI71E>`1e@O?kCkS6l$+$}O zdzg+vgG_sQ;^KOWX;igV1T15yY0jz0uc8_T>XT_1RlQjb9a@s0g|Rr|G3m80U9Tap z*Oy9*=f0M&-#IcYfxakNxhC6waM=;^oO@jYN`n#D>tfvUEzPPSn#}h^XfKO#Cw6J+ zLf@(A#vxZF*E|f8f5=ew6ll@KZQqW_1(x;N5?`wp5lk)yn*eno;Mzv(Kh~19T7cHv zXl}D)pe2EeQe>X(fXNortDyNxRw^5{_T0&>dE?H?@yM%cq5--tF)Yu@#CjukBV`fr zSELR|b$FFC(A+VS@3kd?NwfavX$~-Wi3!Df102U*=?7S9{S}IX$Z|_ zf$u`8$3m}6F4Z-Mg`gDZ&a!3Lz#t;fc664Y@)J6n#{LW#Ww>RVv2MJ;GmD3^oo)$r z$==+04Z46+&tldMgzYSrOy4kD_g`CM-NIJk&4n+Z=Pt%!U?@x5 zoq}8N6%x!N%z2{F-EnKBhtcIh+S8R7E4D#6p%c?I))+TWG5#9k{#uyZ3qwFuWCGlU z>E~2JAKXXUVY_62yD}}_DQ*n|1=>4HHl*C>M$^C$e>nC(Ii;#J?y)u3`tAy7m)5Ga z60Mex)@^3@%9vuXz9Ew;q2EEIO-3dkuj29$dZO}3WvPOjScEI|Ww6ph2L`*t&}_m) zTCA=im?6a|VM5D3DtL!~@X%+`B>3Dz{}y#5_?&BUdx^eFNxlhOxHBYK6_hvBJH;AKzd2 zy~6JoK8#r@FkEDX#5i~Y$13QJ`g@#YhaprVe}ci!{1kuj)fp(*0nBmQZUJj+p;yVe z;%6ACAFB;V1@4X51-(Iz{W}=ve34=bw*EXJaeEjH`#{9~cnF_y%Z;sRruQQ~(X5S9 zuZ)f635On?TeC}{VYCBlBi(S=|1f=8`tcd{bM@6{&ir`t?+CRvtVW0V95@&$M=+*U zf3#A$V{VvnWU>gJ#3F>SM$^o29kh7r7=+WlG5?{DPp$@y*Wba(FIhf#sA+!%ZpPIh zFm!N8>9zwbCmTlao4~8H4gG#L;X9a(htT0FXx|s%o=SW@ix%5h70eBj=#hrGZ7k|H z<}u8hk;B8`9_K);Oh1Y;~mHSGgW{Mg)OlJ5uQh98rf59!? znVY!^k?i+WSW=$4JIO(UMef0l+H*2Xz=3gL$`4XW-P|`USBQHf@@q!E<0UF7cVOTG z-8NDR)?ef&Fb09brO^;VT+}zf9(7I3%_=b-7>vZy7)^UEhA9uGmeHOwLeul4=}3R+ z>VsgT2}8F`<6t9nLQVIW@htFJe{O53uX8g5lg(>vrJ%*O%JZez0fjiO877D$K`p(3 zco`9KrGotG@$8OKT<)y3dUu{~{&o46FaPf3%a=cQdF{3% z&UZnh`=zgt-}#t!{LU{Oe}IdYvLo?L^pR_~o9pY}h%X`UoP6!tb#ncI*0tC6CeK|v z%Cgb5aIo|e^26itOD3=GEq^ULF!|bU4XYlj`d<$+@A;bMd3^Y7uq=-hE-4%@oGx5d zxLV;#6*{vd7gPUS(hu6vKg+_-zu5oBxnTNAGc?6oD)5!7;P`I4f3*%Xb8Fm#!D6Q- zMPV3%{E$my^3!5bKlBSf!<~Qf^EQexgwj8nIt|OC&#H5lE|Z8M8bz9 zr&n<)`MFPWNnbU28@V}Fo-6Q5mB$C!QXkUkVRAH{JXCyVxKL&${IK#u=mvxYD^7}Q zyQ%a40_ba_3wWGkU}Rum04CxCoA;K)^V@u7;AVaS6k)g*@=_X^X1>ha52QF4m_R%L zSbGZ^la`9-f7~K4B+e!}CdelUCnP6AD0(TtIJh}>I-okrI|4hLJg`1GK5#y^KS)2E zLV!aIL%2i$M1n-#MQ%n=Myf{+N18|iNSaABN$yGzEK2fA7E7Q^5KMeps9OeG)?5l) hC|qP*l3dtcP+oRlYG6iShG8~gYGKM^bh9XoC1YiwlWnp9h z0E%b;001rk001^1`hC1;Xk}pl0E(CZ000~S001NhyaiHdZFG150E)B#001oj00M-0 zQvd*LZ)0Hq0E*-Q00Be*00BfE&ro`8VR&!=0E{RA0018V001BYdI}J3VQpmq0E|cg z00ABV00HLSN(vdwaBp*T0050>vHbc2e`IBKFIwNc=b`pgyXLBWs_L9RbB(9_be}^X zy6FkJY3Qb#skIetWDp1>2DAwZibjce2_$-Pc=+(X7!)*Dqmf{)xjaeWYT}T1V`B8` z4F)1N`Xe!NANAh)_O8>7@9BHL*LA9D*B-xNeQW*yYpw6=9L>Q$V&G?TMy{CKf1cZy z%c151>aU@075Nq-O$+%|)a#Ch{Z2ayvsVozi>Tdc&!Ql4d)Yo;aCmi+U>yxd!_KhN zPSA_z-*Nu=cl@sWXl#4U)~&DEcI9B(wt>c&&J~XF?(2G-Q-u{@^(Urldb(xmdD9tg z+a?qy5V8bEN4uB2{*qn~KDubWf4RDQHK{f3XjZ?4F`<+Za`OpIBm6CB6%nC2{#M`B z1U)rG2s2^0oIv$(T1P~da>sHvLj8CkOKKs(XHjzzx09yeHsYP6*=cXS2L1L9)F1Un zYiKlFMco<-dtt8&b?atrU?I4qg8VR$zmlbh1X&Akkqr8y;h9$mPtGT{f6r`YXr5t~ zZDD(AY{G}>sGjZd(D77G2v@dE$4*VlhbHHaYL=rNMMYPNCAF;*l_(XfK+!#+Us4Rk zu?ZGb^#fb6OoFcBd}+bAh)FnCIi;L)fmGG;jM7wlI<}d|%7$im?Q=CD;8|SNIH6o` z@OEAl%n-`fsMr=lUyiGdf2zePCU$6Qx-eo>r2>;2l5L3p2WjMVXu+P2dT!)KBX@*< z-EqLtGP_J7Vz~sk<)U++_|}&H|j-6ClRAwCmKL| zLh}wlu2Nx=t=8*CLE0a_6tXG`d}z?5IU4k$Q7=daBIyKQxM=pGf4S(Au)ec?>r%yzrSP0rC0nx+fkUN7+g~n z$8-FuomZv|uKHZj6t5mSMUm&<`^ZPW_sD}E`sAbz^Y|Zg<=k5CvQ&PWP~1ff(lY2v z(HM+|AOeBwi$t_Ge`NqfDU%%-3hmLbo61Z8wd?qsNBb~H|V|D80nQ%BYEJiJ#S~_MZ$LZl2jOv+Oo19V#H4z6ij6%2nbqSKY7IDib7bazGKNW*5*{ExoV+Z z8WrH1ilD7jpefV#w8;6n8**>UeH>bIG=zbc4m#OxK^J5ofW8)TfJGfY38E$(37}De zLd29_kK9ATxtu)(?xQ4}(??_GEGb z^a&qj{gsZ|b<~$P8usLo-k=AczGx1TfF~S(VOxPZ?dtKXE}Uv0iYNmeWca3FFye@( zBhYBDL0w&?{XP~L)1Y|Zbr{4GQ$~e}1uyDh=+e0$f8VloTy~e2Uq?J&?BBjrSly`* zytJ@$hn;VlPClxv&SETdp>$n`hxuZSKyML^(TdIR>jv$4p(=G7x-W_IP!K2z;kE_} z5pzsD6)BX%CR~&U)zbDTg8@%>^`87ZVo0h^tU7^()oKit$F6P~m_ZM>rVgA}b5-U3 zrJ6Yve-Ux=3ax~xrmOQ$M2;6>>RBCfBU2HlL^GHz3}))WTvTMYqDkLcFy3=08byJM z2I$m1_q=EP?D$z?zUMvfxksvqdva&xz{-_!Q@MFKzcK2Kk`5?_L`2Z}fiGphyN3D; zh&9`N(7QfAvw=S{{@3+W;fY%9M0jd<`3sscf8Y4{W81pbYIpn=uUu}G%jjsa)#^`8 zq0c_JxVW%*<>K>3(@BQRv8&x}z3M&Xb{YO^Q+;_>PRYhO(Q?0*dw1^lb5G~Kfjm@3 z9Vl695EfChEnuWp$*7l&>vhzYlCwYt=?SSx$&6z-ltX`F8me$|6prMsnzW3AQ6FwF ze;7(7B1ibB3zh|hPM!io0S+yo4p^oI0wW;|))3sGhL)tR=%um?@-BD)7Y|bVl3LyV zP)K9dlaGtwdMHf?9t`%%hYLX7+a1|#viYL07j;7@YbOa)<=Rdxs3J(Zw1`lXetQt6 z1OhyYo7@jOP{l~zf3wpj4gs6A<;X1cK{Gj+V2ZoqA(aE)Hh0twU*>KzNKtu@09V;1>c^(WCMdg;zz<4W^YNkT+U@zf*`2~wt z0ubRsh>hRzVg&LICSH-_3alQRHJil(CxT+Y6IgK+Y6#s7EX{Jr5rdNXDX^f#eXAj8FrlroAt#;{eO$S6$X#@RY52-Jg5=&OJF2fcWT$x1HG)+bo~&Amwb>%)wg>Vd+h!y1e1-ZWCIe2jG6%ONC+5p)|Y}F^%lUSreG74Hb^Bl z(fZ5pJ#k`veH|4C)3rtIq|!gM&^^}e9(&#K!bhhE=z%M*M8)yD(6KAmr-w;-ZqJq! zC-$}sH}wntNp3E;KX(w2e@9=ATKOQ6;tc>977lzEF92;vQ92Sf!Cxy8$tW50(sxg! zZ!kXco%o{;?Eg+{Z9W+-9*B1sGJPv=+P`OaVM>}@o6 zCOh}VQuvweW^SWeA_xk~P0xG%`-Xuw3!^0v2aAOjN~ z0Vj|owHZJnQo0~Dc`KzI99jlccU7wOs3-4$UTpP?Tbl7K5FpL=r_VW0IW%*_Ys`Wl zhgzUvK^{0LfB4#obBZ$}LsH@Kg&YCqbj?+#?2v zf)FMPnFA7UiG{;v1~Y`A2$Ar+zgC{_e+z25QG;` zM7&JAdIBU;wZR(B99SscVp)MYy$_Qc5hwxBlSC0g0riuH5hH)t5W)x~I)KX!or|-5 zDKY0DcV6zblE-G<11}$jFSMv^RLKS;{z7RFz-!o+uxx^ax*(cdlJit^W*Q%hs5H-cvE_HSI*$Cew+TUDFuuAr^bZ&0g^oP?p)# zw=}AhjK8;j%{tn7oCe1CTlDYXk5}zS6>npr-)WD^p>h3Zvt5H>%~6^&)K&gx}jAE zqGOQRh{1orAo-<>mfBN|5-F6on)wUfdVZreQaO6^oKeWY{6G=l+2?I5M_Yucu?ybX zYH#Ytuj4-kJ6y{&1P9$OBs5-}$PK6@iTp%Ibnw>^IRG&3Lm%J@b6c@c$!({YV9)8% z!e@>?yzMA@GbVe$F#XQ`jJZjHF?!2u8T}sG8qR-x;-U|ZE;?(g6S6z!!ZVk1>(aY| z06zh~iAGhlh5=5w&=G4`HnD}tFFXdKFKG+&B7)a;-Z1dy{-*k0XRkSRFtOKPJse%J zB|LcD>vxoT=S~f;n0Kc>Q~ZOe<41Q^%>JSIh4YjA&dZJzt9mxx@q;Q>t?Y-qFi8 z@>A{k>pDU7kEpOV{^40Ye;tg|SIIhc+9_$z*i|o6fIv;8&;SF<$d`29wbLV6b9V;) zBy+^@>|zN^79_cc5xj;b9tQyo2wlV!U(tUS{lshP(cJZ?Z`srKMBq8Kf-XH@NKlm( zm~9GL+h8$M2_R+Ub(1Z{a_k4(*Zo3e_UM&Sp&WayVo?WH!omWKsssoMJliPEUa@c~ zqpx0E@ob4N6g|*fP=<&g)!Z9O=B@}sIMX(>+C>RTuni}yYl7JXEDd#-unjoO3=Is( zFS-d}6}X9TKx6!(n{Xg;2F-2)KZyP>^Tz_OIhTH-r+>*6CNNhnuh2MC_5a&*IRmoF z;7WL|Q7!+!JT|=voT(|?`nj7lMOt_%U0LDH;?~VV!RJ}*IR^f+lG_En{QrN8zXVCp zlm4qgG8&xy0Z@9!e6o_#7FX4MGxP$WEzUI17ISxHy0th5w!$)n8KU7_w+nw?7_6=i zwqv?_Vu$avB~2lOt9mj7n&RhGJ%6a-=WVND7p&Ucy@R=xl{vDuHrUu0Y|7~lawD)l z0FoeeE^E0RvWOZ2z4*UAjP`$_eGk8M$tCFcCFI6ey=r{d6HlPGylQ;m{rBHLseg8@ zne$$8b!P-x%!5`Kbq~fFY^vxnQoo7k2%OWy>WkV=WXzB=fREB zr%yj|=n!zG3}5IIo@+z7qx4z8cs;k_GPwO{@|a)r{cYSGPk-bi-~L5^M0@!gc<$zz znVG@ndwP00$1^!04A@#LHw|{+K<=27mJ}LCB6CcoFmxg&seE)~HG2_Qqh2aQy;Lc} zwk4xKJJ2fXRxwzOSu}qN;27?M#Xw}bb?f@>{_go!qY&yEE=I+AYYXf+=Pm6SJRfVb zT09pM$Nrxos4P`zG-N@;S8tfH9a8~WF}FmHu5n5=&BAow+UlC33=UQi4*jHY!G`NI zmK<6&w6z`Q&|2*shr8Xw`&_1K!tf95DHUups_Yd`X{u<88;*YyC117mGw~hh*B5eH zE)RA00lm3^F@P5I)2$)?&If<@!=HZ7fp+WkL+is!j-r=te;aynqk8%FkB&cg_$)Ro zlM>uPwq!2Vq)8J-a^Tkxj2_AJWZrMg+P#NsU`_=4{CyptGYic9I@TjX`z*lm%eF#cf?9 zG=#~h*7W-4v@dwW#h?My*qqx|u|_}DnNu}?^>=Z%xTSw#7PPhfgNqOB*n5u7Vk2 z3s(-E0dV>WACN9mXw5VNF^hN##aT!_LSFlt#i&!iija`ynW1`$Te0G9+jl%)t<98* z`KDWr4Qu>Q zxL^;hiXdE9j9LUth$<1VHBYfrY?NZKK&`UiYFKU&8jn9I(TnF+k|v^vtgP@8O;5H> zO6tk$@!$ReJ#`_--qn&BrA8xtcYeWlOTOEQR3@pH2O1X|vM8?Hnw-U^JMsU_H6`+bVVE++1vwhi zSQJkk{<7i&`AKGj^UBn*!Z|bF+iDs#3IoHSYXeBk)P?* zD*0h=ZRgT3@to<_MG>ae@_7>-H^yHBjc>^~Y9OMZ!^8jta}YiE)B_JZh5e`A|Neic zaQOM-ciwsY^8~)gotJ;^jDGwIIRrgCEj@ahVSJIn>P)D!LPKAYRDE%~E2m8+%lxrZ84)%mHFdFOp+s&l1c|FX(7X6GAd*RVF_ z8zQvha^USZ1wVJCG3S`UmXd9c-@RGY%;_*irl7_wr%Xm#n9HfC(TN5vX3j8XoHmMp4iTA`m0FC%?Y zISf*QocUX18DStT5UH0l&p;6N(*8$x-AHa)4JxO1mOBP<~52~cS zBS#gIql%1z778K}d>g5E-hJ{UnCKtfeK+=y_Kv&W@eX91eBw&jy!#z@pVbHRWQRn5 zK$!$!s!?ZzUOf4&54L~5^riNLe@(VOS$p7HS6%h32Wp$P4Zlc^!#I{c_OkS;bYy}+ zz&xoJJ!#ryLwLjk2#0s=*=UNq82|Lkf33P?_kU-muIudkU;gr?*cAAZjkjN*>tFj< z^ya3<&G8NIA{baFc?Wv)`0aR$NsP0;f?p+G?*7~-a(|S2Cij1h)Qc;UVFv&rmzubp zh9k4a&)oY_2<4b$Gk}>JWWF3R$`D1Tmx7Aa&Sn!=Z%jG@ZgbCKPAHr2au`Xr_x zi#8-TQ>#aemZ1iEbmD2~>IYEfV>U_Oa(D40|kM5I(0xacUR?kX-J zRm;?IO~&q3O?S%7ER(#cDUFuJ2x75arNKf-l?6bC22v-z{*d@yf_1Gq0@1a7PP`GrP z5>@g`#lY2N8z84ZfzxhLyBB#Lx40UK=79=jWLK)#uc%ucV4U)Gj9v|mrA(Py7Q}u|k^IN4IZbFx z9Cb=g;1&vJ$II8qU1=Us19W%-fX*GZ$z9`{=Nsc|$m4j9IPJ##|M6XXqA`Eg59#7( zz~;7cdvoW*mB|E~)liV8cdVl{4NXEsiE%rFMJ#_~eJ7T!zay}r$Dwz=L* z-FpG6=bZqP0pV~@lE(8CA8z_Wx%`hR5eQE8iuUg_#hA21pKQrplg4-^!&|0@4FPs1 zS==LOr&aDu;AfD*t|;~9%k+rlGzQs8WKc3yY26WEhY7M+!=Oy$saXhR2Z9ISIZ=NQ z>p{sPoat1P#7GyhNBI7IP(@F*ZG!=+1K!0zXBZ1pv14*l3=57^wizNkR<(Me?3il1 zwYND%$*!ArUwFa(H-^6NU$fsZ322I|;7Vt4xMmoN1@NSaDaEEi@_ArTK!Y$b>J6wy zsmep%=t%!jOpwNSp-e$#*%cp}aJzpH*owNlb|2ky>qV9w$2T9m;DQ4;$4s*h_%@j7 z40G6ExADYs`?;cwm$kgaBgwK9Cq{amc2ks4Z&|v3nU_fWgI>J)FRs4&eKkxua(?!{ zHSFL&%6^XjIs5q$bo=;i==NI_hy4iM{tv49@`JDZB~b_1wtpr^0q4ZIPHulWcQ|)4 zcXRG-xt}2gg=m2Gpi9wf&>PUNptqoRp?lE>B+pIzM0TE#gtg;`-CCX>*2AH;p7DS$vMm6fR&MgSO1=0s`HYrX4y` z#wgZE7?7lsCflv2^3<1pR2Y9WlWfG{04^M*!MN0+GD;1R{7!>CK?r)p52LP3e@)RT z6ey9pWiuHx1Geo&oRt%Jx^%b-?xi8Ye#RTBNbb&vgEVeYQ+i_~>7NaF*qw;090yGp z1?_0iUm!ey3;l2eMeKkUwXjGXInp66E1J=*QNQW;;F64bbwkmGW0HT?hEY>i3EE2L z0FC@+zZZm{J^HW*>VdZx6GnY&Ht+%*1=>#C)^(xiZ!G6+p_tPEa@10V7?uHlR~aS@ z3Z7>e#)yI~%j5wAPzI7Clf+C@!wMK&Ca8)@lc``j0HbIeqcSi%hM39F$2jGLVciu? z4b+ln2vxPDQ<$q5G!=i0pTz=Yh2p^@OEpFF+Ice|2C#11VN78vFl8A=BU)7 z3O6~Ylr609TO|YrvO=G8xEGQjS+IP{l6Tpak}BGTDOVA8e!I!RUcfC(tXYO-gEcU9 zMP?RR)I^{XWRVpn^AWfK;~lFE%3qYtV(U$?wjapaLWT2~L|}i{YedD&F}MLJU=dFE zC{S=P%8wNbMc-A0sQX??kQLQ5^8nM9EwhuaGGK@Cf>=`x!!r!E2D+9IlGhj|6m%rd zn*b_=pp-PZs$tOCOqfvUE@uj;2-Cm_N~M9_q1eb1nbCvrxI`FZrlr%$vK1I{ey?Xx zI7b6Bwq6^~8kB#C*oXszF<&WJyr?kEY}MiDmeJleCD@_zk&F|f<^#Ryl%hdGrBzU& zN+y?TKV~JOQbsVgh$wk}-O_CzYI-A^F9#uJ)qKaaP5^)cQ~`)d(PSzI{0vmiIT*ns z4$cazS_%`;(1r;=B!;nNI+fs~`<7Fr`kOOcXWkDu5 zAvoh&OQ~wA6QYTE$+CGfung)%+UHagfzr4P6gr|GB1pmb2kG{o69lhQY1Za(xqZD; zY*I>fZF+xt0X2&AHRBRNiJ?*P5JF02`QWbJvZ5?3U2twUap}8v&P^-&VqyEt{%aL| zZT1|+z7p|4ecj?wVQOlCtJuKUAk*?oCo@FHL?f4h)do2QOJ1ywiqnKAj>5~nFdSvM zy;B1lwszk3b<1c*)9l|+JL&CRt0%(TyLNni4hDbrA0Q$~qp4Wy#YNrmO0tQ?#OF57 ztph?koI8=bJ@=cr`(!i}=z8X^lqemvG3cD2Ce9rJ&bmZPT)C%RCm=>+_8U@QL*M zTA}Nfu0H}-ye7SrAx=-i-7eaD?seClyLbF4q`AJUp`aQ(7F5Hq8sL{zCn!)3IL2_TJhJL^?GyNe}m@gx~thiV8a_8z8RBwBcZ@}uY=y{EQ4JDTQ*89kuSY0 zX_U#I2=^qfHQnD!q>~iP;BuHbprO?>^RBT+x3*!p39o7dgtSD%y2Mfx z!v^dHT3IKxf@zrH;qE0@+z5(}Ryu#33gw&Mg6>$}R@vA+8cc8c46X$(GMzh^yGb&U zG@?4GW9A_qHC|!;)5t0Sip?-|knNStyLm~o(;cSCOslBX>t?e{(iCWDLWvnNt&`px za1Hu_O0=4Qf(p>Sj9nJBTpy#agzXELDbba@V7ARd7~beD6pTRJtz%A9!QFpm*;WBi z5^OqP(Foo>4c6rF%lU&~s5^(ic6hd=oOE^zD0_nmW;mk~LLmJ_1WQ1G;%IQs_Od!{Sq6L7i>uaq(2eMWm_EeK<$2Sj>S3;tVyjg _vWY0fU&a8wxC(TmvRD8EQ> z!wiDuBJ?9i8^AQjPpDx2DXNvc0(%H;m-*1+Cmv!jn#MPK-bI9*@wJj1na_PR_b{|( z=9HhfSb-sR2JJ~`sh@u=PaG~%G}Cl~bY2w5w%jKf*a!$!0{n^xS#p$2BuHtOfc+_e zP4lSIAWNDoAYrgfR+ky=socx>RX4~YDp_=3Gc6QOk;oVnwdmn55)o*orkMb_EXS{< zX<&xP3zgWB9~A?~qdLg6t^>>yh((4)Wm*OSIRtuxfVan@JScz1Jmvtlh(R3-V}PF~ z)3MMDCyoJaI4&+T%bp^i0<%c?U7Jvpn!-$X8*ewsNV$I&3{fEDg$Bq+^2 zO#OISB&-*~;7PB+w}3Tt^aVWu@Y1$5f~omypMW+C>&-%y^LFSmL<6{76Xdg>HN-K@ z88BbUbz{-c6rmcHGSH}HJ_r?#k6dv6Ayn65^`y&)Lx`zrJYI}--=GcjiQstngOjx^ zDh0;piGK)_h<>adSCnV$;Mef z<~;sdlc+8@U3~V9#9D=}gb(t@!pSH)S!i9adHSjSyRRqaf*B-Ed38I`r6(6(JiYh` z{#xn!(uH@POTy!!^wq)_AyfBGrSI`B;#RB&$(ybs`91ksuS8}qxeWi0z2tF(_L7r5 zFD!p2r%%JjnXM}yeQtbk`}2=J`aJrB)#uQge*S2>bw&1>H5S9^8L@!Qq{o_H&+))SH%TrBN^;-Nq5Vcl^|Y z52BR^|MAeF4;?!651@6e@lW0*|80)(7x4cMl4t&0ytXrlUV8kVdmcwGe&N0E{Q~wL zJ$(A~;YZ1%M^2wU^5{fHLi}}T)#=>U+!1NB2hz~;)S)%8t5Gvc`;eMoUC!KZ?qm z`e=!40a@$j_T?^0ZIRSOvl&^bpjRYwNS)LkpynivHcg$E4)jq|PD1DmU_0og)O;2O z|Ddy3S~Ab(8&_;?RJxa)e=OwM?C7Gc3*BG2aHl8d367uIyJP$AJv)Ea_wBhgnZo15B6BHZTytt!ukSg$ z4%lxYF+_act$UNzDb(DyM}Ds2+w;4Y%;D_j73sA{_m3Y#t>&%2_3L}koToOI=*rf; zx9&#om|V4O&yHlGlNQKU;Gb`meFh~RPA1XISJDi!U`UV!NhW^>V0RYZmBycoB*lOd zA8rPDQ;aX;@o5r|48sCK91i3Z)pWM>TDlB^1nZKNPNK4M7nxTX$TJWVPKCyq&^&;L zfVWkuxgxUcqGS3_(ZGaS153$smD+^VOT`)uS-aS*&ee)}Zh-Bk9P_E7mLIfN3{GYb z9dM~83P@LUQ!Rfl2%4y*UlqFWcxPIAVbN`itDffAUW<49W>II{0|Thf=my|Wwb5v< zmqJwluom&D*eD3g0%TE=xoDW^_Ec@zn+4Pk52cP_9y{PMMKdIc&??l-SEsP8P^`rj zV?$#$5D-DA5B1uN*MSYP(viticYjLS(=6PP6qVt??csmN{zOY`GuF1HY+O%gLz=&K=BoJg)~~sp1&Z-Np9I z{z^Ue@ne54T#(cm+ojt1EnQ70K|3<0&hM^!y9tompsA~lH|%t432>U6%*g{8+)b_q zWIfF72EKk}?uOjoqpfH!x)S|5dMA1SJ%*l=T5C1S7$0V{s3i`aB#C9o`H9RTkWM6- z)-xLPWejBzH{~#ttPo5bpGaCiCf~oX@jMCJW)GMwUER) zP11jtu8?*%g0nn~K{giQ&zE-?$t;o)*gIJkuz4N6v@8|cFs*OYl&e>a1|7lM1Ia#y zlMW%>%>`bv0G5r`F+ezcI|4;o2O0!&>te~q;YD3dqZoukxGIc&tZ*b|6*~-h!QzH$ zO6%rS7|siY%J#%|iE(P^KE4Cnu^=M!Y(sxeK<2YVx&PDb%&d$I7Do2CIXuZmRnddT@qs_ zkAX^fMhKjJ{E$VFCeuIQWtui;s*%^B6o|^$0mB3=IYQc&$X%=1uB9?i1IPq~fGB@q zk*&Lp(2MexPoeOEOc`9(T;pz4dcqVskabb?IXN3!5)!7Ua$-6#A0?<%Rf`~|DvSh6 ziHyM@AX1J`Q35n+=Tlqx(2;m{Tqk(2Sv!*DYyr1OVR+i2-aij~V_|-&C$jd7Q64(sSVN&JL zgG4d&;@=b7cMvsRhjjvY2W1&0h^ym|`*05~ex+bLn&4{bvYC}+1#T`%iWL)Ll~l*Y zR8?80tO6{`+Z5Vv7Rqagpzb#MGa4E}_XH-XXvwWNksml?qX2`rz2OO}5TeYG3{ zJ(Qs|1b{K}EC*wQg1Et0jdULs45D&Iyt1KkM+AA9ZbB5*F*RkrvN9E`F4R+Tj4~J_ zC!n&a2#u~$W6wnxhjNy$M4ygH)0yv7dNAFn!qxl>(yvVN$y6(ZLdhO{2iKw5YfzSL zP&`_)VDD$ph^ufMz~S0upyGd}ykNS3kxXw_O19x5^lwNmXkY~Se3-A+qrk29c5Ls7 zNv!02{5QG3%>7mF`?-J0{d4Zc+{-d+e^XVZQ>=r{T;#9^x-hhGrs_a331C&A=&~^@ z)rg;lgXNaw^rK# zzN1ijC1gZ-Ac6J()GAz+CQpD-8g%5mN5D?YlQgZfiPTa%4xz6GQO^&2nS7B*RWpKu ztfL6ZnhaJ^0QG1~63ZpA10$KQmzc~ek5Ost|#WI-v@Oj#3dq+x$$sHw&;B1T?CDu|&_ zxf|L=08fCCDBvj}xPcaC=JA|ix+-(2X)C5?2^hqJnP!n5RgdRA*U8KI@x%i4W*1DM zTdraopi>9)OS4j!*+|WUPO*I>B1~6I-?EraxI*wHLNx_QFqLb^$dMrA*t7+MrmK%X zj_|o~L2Syo;aGnR?js7c|C2(%Gch5>W#Qeq@$cI!`UVP4Bt7 zjM3qhUTlV*OaySOYE`NX+4`XwUo8gM84z+!Y=j=6n@4|%9~g0W1>^u!Ffa^T57fl- zT(PvU8pqtQ6>jFWHtbLwzoq9*!`4|GubybOl109#CaTvwF^Ib+(BhWwD8lvHTHfT& zQh}^4ETzW--9F1X5dIfnbFuV1d48JB)nAa4HrXqGbYA)6*~ZGoN+bP1?X%nWy<+zp z8VK{pQ_g$_=I@%_jojH&Ss!#V-0j$|L9H@1Xqn1^LF!?`L1*Z=vb&cgJJg zocL*;AXnt>&V4!eO?WPF%Op+q3FV}kEcSI~-5h_=af3c^$w3-Ex3XwgXEUc>o`&J1 zHHqrd+!-kW6HEuVCxyq-)14ibplFR|nLR*X+Y%D8cUsN1}G*lOQ7;JZuvl>pygFf zBWkG0bQ+E=u7U=kSdHt&>r8+)(mxv!i>ZWS9e{&|WLOC7DPxpQR}0%@YQgGm245jR z0Culj{ZA;(65f!Wc9P)Zy`7|0O4Mp)L8X7?>G_#182Eg!D`}UZJf;TL6G|zp$TgX{ z%sl2>esE+fJYcq5I@OPTg~y_Js^si+00y>(jUDGTB({ppfYWr^HZ}lYDK-E-MY?Hy zohrF zpiWX~E@ArmX1H3;ZUrNlhGPBRC{s1r9HOWbZn6!Td?-bCw1!h9HKE^WI*4?_p9!ah zUOSPqjkC4NWVoR_81>UfMVt8{BA7Ewp_RGuGIw#J1cAk;d5Sh_PL?ACc?IY`+=04& zP(xMR4L99h8SBSGnNoQ|RD=>~{za1xJ{*5i6PyAc&zh>7_-fdZoW(3OZFZ?R<=F&i zx5G_Jp0nl6^XK)zc7OjV8ZCBRl7z3@{voOzj&WrF|^HSek<7I|iZ9Ry_y zB;MPbU#!WsjpPGWD1;DHm}M?=n&j$pgaN$&ppq!B?F9sRvSbWUK0sGqKUX1O$P`AR zG}M}RaM6Gpv-#z!341lwjKNqlYhby1-S9|A3`6Ly0j4|;wU3LuPDyETA%GjoNj=0c ztCVU`h!sHS3KMa8+HavtrIYVI7Jn#0WGXocEV&Yr3d50)U%esu4v|Kkgep9|7HZ+c zwRo|Ph#>oBj`V( zFQ7k0e~O+#e}(=Q{WtV1`X}@gz?Ltk`~_G8wy+0?Ho^rQ<0`Jv$L5hY#Y5@o{`9z6`$#zZ$;|zaC$UZ^Sp@H{rM7)A)A$8^Folitonn#J`2#i|@w| z;0N&s@k97O;7{OB;z#jk@MrNK;>YnH<0tSJ@qflo;-~R5_`l$pgKcO4 z+ua?gFLQe;sJAVRX#qR!$$y3YMsQ?UlRVf)Ai7EFE=-198CRAI_xagXKA**H*wIUa zaZNvfqwu!{O*Wc5Tt}I!ktYo~I^cIh{%$mF1{k<n2?=@N`UyN-UYN|JXLmy+_jUV`Y*2X( z+!3HpRFMlji9ttJuss6J5Dlfil1d@HA!rcRgHz-JrBLH$e}IC1JL+|sP_C|xM?hfYCSPQms0S z4tQ|vVAKSjEPvG|6ypOJ?(rpQoyW&y{_CfunjCj!E~Qvy(whJ(>A4iQdn%=fl|e&Y zCNDB2vHkInfwt1|k2pPr(;MCezy1?ik+&cJ8O49dZvqx_KwOT|n}F!v3uiE3KpXI= zFER?{TUcp~HxBFu0?l^sCFoIHJ$;LO8bTXn4q%6Qe1H6VP^?EWtxjQdewz1-(LJ(N zLMR<_yJ)LSaD^L6Q=_Cy(MTF`92CgL-xSWbJpbV z-?~FC8B*;r!lXlkRAWF|0!p0K3hqRkrCiVE48z6cRkDpK3e42pD zzo=sIAO@TQ$KP~}lLJF5eD zJm@TR@BuJyQ7PQQ7!_EHge}-SB_}SFUQRZbL z(`}x_bUpRZya-SHz-~+rV+1T7&5Y*`?v=T$;~F7~yH3aqA%<%%4_?YU8J1fLy&)~~wr#`ABy z^QzAfGaeggc-w8`KSwXdPfobwm=x2Q_^u47!)58RX2TJ_`%RaBX8f}^8l!SIXh(}A z8vpr~pG6MZf3CLk_1J1`a?kgZL+R{KF3v3G(_GAm->@^tRyva@(^)#0oTvrd54~jg zP1AE7#jq+GRInHB_pBaZQD>voF(Oy7%pE#I(PhFSTQ$36i?lqy>Zq!oofkQepUH)}Vy>E-AWb7Kn~Ny+>*&DxQY563&%P*lXHWur7Cz&lTt}K=p zKm7FXEq>`+*ItXaPXD;QGXA7rI(UdbQufZyn>!yL&mEF$S$49?E#X;zTe`Mvy6A;$ z(zR@LvM6Zx&t{{iF1q$46w;aG{mCnyCCrv z+#4jTld+A8j3*6Jh?lt8I*e()o7fUa~T6<4ix{a~j zy;${H>+SaX{`FRWYu#?CrlGauJODgE!@rqnMc0*S*Z`e059;(j!cS1n7sLEbFaI6T z1I@A-Bss=YKR%# z)@KBe9EWoI>{|B>KbC9f*5nA66g12I%0f!nicC=|I9y0V45zTkG&;rW+3MIGFxE`RN}Z7D=J zjOI>nNjRe`Bg&cOx$z{A?^)1ScCG}y-%HmyldxTmy{7ExVJ~IsGP5HY^g6$68_+P2 z0}zm|A>oq=K?O(_Jy|6}9#J_{R2S3WPlOk%<{=cm{F$6{-IpRUX+ zIzD=%2Hyrca?|AZ7F{fe^pmJa4S!iE9T>yunoNxWOXLDggI<(=hN6-EPJgi^=$-!N z!|0ZmzdJp1wgThhuvDXvUauzLT_{?)EjLs=aNksPD7?uxpZin z@*)@Pl=F(yRS6^~4gHC`IwG4!ntErt($N@gD%xImuz&`wkzBGkn~s_~rFoRDq zlhsKeEV$WRNJV;s$ULPbHJv&)4va+p=MRpe08CdDmi~_pzMgtkxI%PL2Bw_;rjsE` zCIQ%!NJ=MBcM`_Y2jMvsYh}Y!0YQ1H45cDPlL67#EY(dzv9!DZz5X)#SZu}t@Ed^G z=Cm;G6-W{WhN;QmAD2tl!&}ax*SVvB>Cs)#awc&O|FBG9xl_ zUn(=J>Q>#_Ze`tlskOUr_q|fLT572`Ee&eWhCm=&Sd4@Lo7EDFv1CAu#bRSI9t^`W z1_rR1K}JScgKT-=1AoK7cr1Cq7M}Mb(%v@_u?oe00wYfG4 zw=Uk=I=cCV;qVOn@AbYtOonB6VHNYW(zmiJK=TOhsspM1E(hJ$t59ro2?V`tU^Hv7^6MuHA2xX(9ei6KnCUMz-clLzL)cTWX1 z)3j`9R>M=le1F;Z9J?OS4_T&J3r_isvgeoQgHvJEl=g++s&=wNooqh;ARl}o?VK1M zdCl`)yPaO$diQO|#&c9ePf8<#flYTzu`VhmJgNb@_OioEtrFY4y~C zSw8;E=N&n8>$MkGtj_6`?sKf}c9tE^CSP9M&br%O>woZNmmYdmKa|@g^i)n%ddUf&{Lgp&y<6#<_6WWF!3V%RDvUy_ZxRrqhnq?-;Q7|1I(-xO% zB@38RXn)u4IgwR54D+1eJVl&a{RSuI5oe%I+H>TJYB@q^21B=fso67Ks0e!FYhdgO zopufZ<%JD*P(tu&Ob?AKC1DJ{LLsUTn*lOIjJ3s;TBXkAvQ@!pb(Meb6m>Mmu~WM>X)i(Kt$&u< zn!|0uqys181kVj}kKVTAlTU`N^Z?bG&cSlFO6lSk^e%!~a^{r6(5G4|LS9KJt5+76 zfVIoI1J(*O#*?n8XOo}Waiv_I=X$`1ec_8-eotrg4pS#fAS|?vg~fv>mb|1aXc?u4 zW?F#@lFM#Y;<~`i{}#w7JrS6WNq?j6yJ75JNU7slt#qo>EYrseZ!3JL@P|2ytJ*M1 zXApE#wxD*DklD=OsHcWon#>R^@Wx@DwF857lH7bA;G*_aivS%M`;NAha)Qx8T={^4 z;e(pgPM$CXZOUS*B0t-Bc+`bbX9^15nIL?^SVczwGar#R>y;$p(gc=Za(|#foRTSm z&IQm721R!rMx6Q~P45OJyS%$Tbl}ih-SveEZHJKnNq%IZjT(Z+M=Lu^C&~!HhR$Fb z^Q$PXL8c1}7!!puglPn=RWJ=f?2Gw^Ms?Twbxwf==?wQ#nWjrEbPQ8c$xU)sLpq#k zrWD+iK7)ZU7E(%tj>w11w0~g8?ef|sCoZYkTm*)-yfD`oNFDLxFt(jW(lbHBTHn0X zuysWKuynn)_AJxWiOw}*f@MQTbD%=mfpNyNbrBgZFE>1!$H2RcD66BPtK(7sb{Nc% zVR`{ziO_O`{jzRIsEVA*nSezqO6j7)<%QEKu2lJaD#UmJVnErfihn1eqcTQ2s+32= zHm({W{ydCZr#DYrs^s^cZh=sJ^y-J1_;FlW81c0eN8}^&&}HlEmmQLi;L&m?Kl<>e zKRx+wP~l#^5rN4{p68{OUaZb}bCY)$=jOWADjD8z1G&<+e(Y>re#l;Iw-)8_vY}jT z?H{`I)8CJqHOHK5*?-Or-dwe)Td5b#O;+c+@QAq^ZrIc3?`CJF_=AP088jY+R^=Hg%wIap9)IzbO2w@_z=7Fi;_(Io@fv zErPT+9?hblShhc3kd()>RW&i|q7BTtlY6W8k?X`$zTXdU4u3{`Z`P>^*8L~<)0ahF zoHkNZ7E6^VbPXe3+guyYcec7OPsrT-sFIcqvlzCU7aj8AxE9ACj4^cgr;%Z%%_Iq; zW8EHEs1H{+*NSc!&Uw~F&30HcjdEHU)+_WzjNgvqiiU6(I(`2oB$-cB&kXfrz+;GZ z;VD+BE^iKw9Dh99Uz+@R`;L_@OY{9kb9tdvum0;|tqA`cXm1Pso5%IQ^pm8X9#0ng zXAT`1Y%W*J)WN0Q$p_qOy|u91Z1}!rZLQq#qMx~SCR4kt2pXh`aV_1U9y_EtY<~0G z-y(NSevKZV{2@6_UiHd*f9uER{wBC)Z%ra(7r|H~?tiY%voT_uMF}6Xb&7yoD)1Z( ztIiIgUz>bMSoC({v%g^a`v0Q`#Yn%v`Kv(1=bYRcc%*lpnw(q^R7`FH6@z?BTEGJ) zcgRG3T1tAW-k8$MKZnJuuq|h=bc$)&nf^u!B>uO*O`OLbn|$VrUwp*_5B%w$l5@A* zGPxBF_J4MFNqL(r9VWZmj~(9G-rgp|?T5FqC}Zj;gZQm0g%gD{g_~9U^2_&DJb5d3 z^4*UNPiN5i=xd@Qa*^_wYscyhcsjmin8zs{C!;a%q9hdK7Q*hUs08$e!Mqb=Jdx>p zp=+}*^s~U$inYelGZ!1RV&GVg&UTdmgcry(`|MpKU`dBUKEC-Q4n3! z^natJwYkXN-nOH;5;siKNEQ|wovyuodfQoC$hyJND@Xs`bX%R~%aeM2b$&j{Kc;x5 ze?UJAlvXbsDqLH5R^dH`_Z2=;_;}%u3!g1K3S)4P2oQhDg(Gd{Q4q7F9PLpy&cj}C zJ9V0^CJ%VoAz5e8M@>(;{p46&>HfN_zJH~bR8=kn^x71ON&pcLT~gnJ*+kv}ENF-J z@>pr)LbHVme8VSnvR=Ap3~nAI`#%OpNL(Cl#={Z)!b!^rqClGU1?Amq*4kSO^QNYv zGTVQr%WA6})R^wCo5TVMV-VrHC7;$NRk*wslv`ETc0B5pJf9Q8(5OY_I=Sak6n|{2 z)eKIZq6RuB`s)%6cZB&6HZhjD4)S?z(XrxkY&nZ-7%<8+fjgk+i=-*ky~zg&sfOk9 zLZ$M>EUZ)(%H=AdAAeMLICpe+yVZ8U^cV0ybRxgCeUB!q2|QTm{>Ioji*+F`@I0Hh zuOJ+gaV20x1R=M9ak^l7TlB0u+JE@m=P0w$w~6W=?$l^nuraD@#9QPvkvd51WzVk7 zkoiy2BnOq zSY2svM83D%?8@qDEEo=($%G?g35x_X_{E@Tojv`)86%)JQWoDf7&) zh)OveBkTvv_%TlZZvGv5W*B4E+_c!=>S6y46{<8B%Ck`|_YJzktle!VcpSmPk~;2O zjJiYR4T(MygKV(5LVwibz>*zu_2luigmI30fqs(RcnEw1N`sR6qd~V%|FPO14v%y< z=cH@R1t3oeb3kJj+?jhucBH~Idf`cQDykc%QM4}XI0i)&~OJ)#L^9MmIp z`BM?*VAj5KE-guOzP095ilg=6?t!Y`4r*z+*Xxv@vEmy=xQR?2H=4M**dzM=Hs@6i zrI$a2VId6I0A(S$25J)_nt+JEDJ2WRnvNXO(0m;(g{nLPHH~md#Afo#1Q#GV9AUr1 zA`VprgP3213x63t+HJ-qU{h#BAe!PuxKk~JQfFK>w>Fp$vi^mjhu&LwH%OaD3y&AR zS@>Sz|1JE_!jB6-#a*g+A4*4&$~qm-yaaPc!yNr?8g(<>{8j$ZN?J@Y+`BzoOTt?Q z`MP%=%ZunIG*?x-2vM#KI5dWlF#A*WLfz3BsUW`b9)D(HlIrMzsLaZolHpPM%-c3! zA6F&Kmdy8c7Z8THs|H`9wjw#zI+1k5IO~jol*j65MnA?uNu4V$q=<*?RX1ydXHmIa zq=`T0x6o~l2(eNvm%|hcxL&nUPv<~~qSd|?B}rtL!^S6dP+1%aq{zI6W(})l#}=++ zOuDuS_J16Y-X6*7fqIhoWslqi${-B3ZI_#Fr5t4O$2Z0ES`*yVUD2HLdQ@uX7$ zM(SHdDzwaxrQWUg%%US?*>IW*O~-J6J_&VtRn4ZgEt5fqR2<84%S9h|A4|Q&J`tor z*AFc5j%tswUY$Fh43>Q_lpS4AQqE#CFl1DX%3ec-1qo;6vxqT{>f`z z{NlSm+q|^BvGc;s!3tZuaNm=cNA0NBTYuXkYrSK~ez>|gPWEhy6!d$$u!{4{-A`NI z35vp13Ds~>l`2%nU@+WaFo#&$Ja8=cjBiaoN{EbY!;|xKrkBL1<;b8ISWWuo#(`Gj zz$JL$b(4#yXVE1@U2oRN)lEAL14;Js@z5`U?tdJ!4RrF!J@qNi_o*_KDJ<6qdw)~A zbg1HR6*|;ZmVgK%&7KOBBzxe<$QFhup<{GRqz|40)&v8ZngOEpIx>i)S8_DaeLy>O z5ObCZl^Tb_^r#!nw6bDH4o@swCm>LP^4a9e!f6-Fb}?=iyL0^Tv%e|5RsX_=z_N5p z^H-d$QBDnkt}sxqN;B{*2cOC$K7Ysp8U?$U*LbyB-}M`@>_nk3z?#Ka>+()5^NNx) zeU7t}_GD-A>iT~C!Guoos8-B*n_~qj$4?jWPSkR^LafQR>{T?#=x1`N)7876YKLL^ zTZnZigQG#~-d2>=fkD^07}N$_JqpwLm6fd_h?xoVMj&9y@OsB@Tq+UQ7=KqO!Rna< zQREYYIYYZC40fH=#i0+I>i)o(0E|qpiJ?2o?;+uw=H-d z178$&E$Cnhv^MvSZL47J{C|5(#fi0BLlvs;sV$pq*d3s>&-2fL>Oe8H3iQ<05u##M z+kyjS2zkkED%C|`JaMN}U za-ud}(?iN3VL0e*tCYy=`I7o{?H(87u@}_LQ9;)#$Zee<_`uYO7*iHwCT~nkn&(8p z`_WaVKj=U?LhZ`5Q6a7qsM0V+PtzVYBEybN_VHh4;Ip0C+D|lHF6yN-oCErP#`H*m z7cgEmQJmm1djt~1K!50*GFWUj=C>5m)XL0;3-u7w6H;7S#27YBCF`Z=j-KJJCCsTv z!%$So9UC`ra3=?mpcuNOV%A>GW)}5j!X(3ZdmTeE1qP|Y|3owPD^!e$D^>TvhR~4NJCD&x6D}O~zZ{ema2!V)!W+er;F@KJgfVGJ0s<`8WNyZJX z9PAu~cg3`f#76IYILKW~w=kvvE{k+A`8WR%$$8h4rUzZa5jPwPGc?e;)Sd>SVVT6! zK{^WCSwG4mTle)Uv!kspCpX_o6R<}3Y62^DxXMGRS)lKNa$z&wP~N1N2i_9Y!0=HFa$pIrhjS3TxM{4D zs;R*^z)vupp)<-LtR0D&bF^~8_&kyX>YXye-cuv7Uw@mQ8wU-BLD3ikI~zEa&!H?e zIOqy$tCWybRYAkZj7WlJ05?^iP7zQEY+ZtgvREI2zMrfNmBQ`y2)MaLkt~#FB>WOL zGc&~WES`yhv*-;QFdS5%S&uD&W{0gT)_oQkp0(^kp)im<%*5pD%t(1?f;O>8z!oN^ z4HPDpP=7N=@&iu2m5q(U%^NbATp1s5wa)$13xWu4&E#n&UXpR z^sNu!DbJe9oA1*P6mHIQ7y~cBecRqx@tY#>E!?r4uF_0xSY**{Wz)44Z&B8r!b$VU z6iKa%sRc28y8<*&c|rS0e~Y}n5p(nwcNp;VFn{o3Fl%g4_RGT2Z4-J}NZ)d+i@GE1 zVrby*hoMWqwi|;;hVFKm?L=JHZ3mEj*`id!DN@-$g>M zx_>*OJ-LwoZI5gLefg24gO{W|!IAyb^FrX_20!6c{ z()l2DU1l`G$luQcGAy8zEeMt-MzQvrZk{PtbrbXFxWbUL|ZDSwU0 zt2-}$&#B8_;QE!yOU_>WhC5m!{Cp6H0S4ZGcoi<#c3tu{Hx)~Mc-hraz5a@`SDik2 zdod`TI;h3Xpp<5QsA+raSM+_LlgwkJ>W}aAYZZFbRp{v8PK;P5htadF?8&fUvyS?9!F z$D3||w==Umg7kY}+a!gCT7SK}xNxR$US;4#h%W>rl=Z1`_R(tm!nI;2is1wYks z2^YM&Ro=zxcgwBqT}MXJN#M2X?AsFeFsJalv)z^HI@~^l3veOD+iN7*$5%n^P;HM) zSMhPvDUXm+T`+o@r7@ai-^<~Xa&tuCq>fZj@Kz3PJhSlD3F6I61GIQ9PRM`sT+Oge zVWN72nt&A2^{k*|xqmusxF9+0$gan>1sq?Bo{&Tsx*ZrCOmQJ4%rFTGk_fFhvZkRd znsgejYe5BsZ4m~ST4oT$Iwz9%6sWhsG}F{g&oJ=rHk1ge)}y+lTsqQsxZ(Mx>A7&9 zWe8IPRwm1~35rZfXhe7HM8l%Js&9CpU&m`|Ilg@Td907TSbSfXh)Tj!(JW z1i2q2=9EWC6y?qh*yrd2g=?*U^j6m^v z4E+LI;l^7pJAd_GdBhJ_R>-QlV=)Ms+jWh}9YiCo#M9sxBiGsGl_FS@ot5H&){O6Ur?e!Nby#LJe!HEXC^3wu;k(L*&V$ zfx+A+uGwfSt-)>mjU@>xaItBC(&d#`Pnwci{(YE?Ab$#%&PYK`?=2C$k-NBm+2QI^ z|G>i7OG!C?_PEhZJ4bt-$=J6I%W+W`mu3WP^G+_MZ=y0L>8$S~HV3ldjLH_eA0eiU&y=G;j*L%ggP5sE>m;cgD z5jW6liGQZ?jipw+8UhDp(PF>6)Z95{+hxqQt98z%jbgWW>0+ryTx-5$)Q#s}eEH;K z((yybqTj!2`_v`BbVU;ePy5u%uDkf^*uB)Jn$T12V>g~D`lc^nzEwA?fr61W|qRjrB?|;TjLJvvhzu7D-7y5<63L_48i@Vuy zmx%FbxIxlcj*a-Ad;#MdOmarLopHZT#t|8(w+{}!FAti8{G%WeB5GXKbbkz1~O){V~O z1wiB-YyGq5Z*t+=+t)S<`||INpp)E!l4IXrEuJm$4!KH!Gh1Zosd#r_a)V3>nq8`n z&y%O+(MF;l!01oWX7`h9XeEF0mw{D*aEE_j)PfX`tILDX2?HA}7Ur4`42&aOF-aGdT`CAC#0~@q*(-+r{#t-!|c15MI;mncMYF5u)^^#-V#Ij_& zv)Z0Ne&B(llT~Rw6X9&9)ogcLmybttB_o#UTMnO;lci}g3NOqn)G)7xO8=&l;b|g& zERO3*H0!Rx`Uw-NN}RE0JpjWm9jI?!{lBX9pGa>toT8hH2gt z#6nu?>j6zOBOPJhe;vMsmYx0T3nlX^DJTDbE*3n> z3VZXq!fGnlBXA}J#>1E<^!^(+gC@E4!>jG?xzp>F^z!;qa_8he`uh6iX=Ux?xyAPS zEtC89?Um&M=3p9R!>J;Z%<^bW6K4&T0yMy^8k6s89)ErN5LfPU_>KM^xRu(SRNGW4 zXMK*u!ny;pih91S8JZp8@<0N5kzM!go|7eIyRKC=PBFKm5M`cezIHsL8m3n>!QKPS z>e!a>^+W+oWRfu*IBOWX5tx|b=w*XtCNp{64rnH!11eWq2fJ|j&_$cN?pBLN)qo;> z#>-Zu(*n2Rla6aCe_CGVkr|tQ2s4J;y%XNNH(F;^Ta<0KallMG6XOzAG%(){#tmAP z+}C}rcO64N8WZCosI6Ck2&{6*tK2MWzRs%-*lTG$ke`;SByPiG-5^o1%>!Nn7 z;ttSZrQdCfe$LdkNt7R~5jc$+jY4Qr%e~!cy5MmeqZ!7jdIF|pQPUOeintF#5${uJ zv|&EuO6`wU?_C1DMrs}Yr0g(FH)YxR(J*ub%`zbRu$RUfqaFD~z5aE3F@2Y}z9H}M zKzBabW5BCyfB$BmWlQFrzN@o~4@lGVZy}E^E`DCKy%Tr(H3_0+^60hH^!>Yi-=rr^ z+brF(^w`qXbH&?_A8&Q2_M#I^Fny_`4STDrM8El*DLebQLES=J$O>2Fdlsn*J41#( zjXWC%aWN0(SSM`^?wA@CK-7CSbAlNsru+-nsIw7yfASNZ1A=XIn8PN&x3RsRCFDlw zFw2_!zHPFTpmkd-7Kps1-6kT}38^u^UhhP9!#)A34RhAp+?hO(9n{&OHFERf0WtaR zCn86Z8*S6H51au8r6oW*^^F7_&6$O1>*BSQekr8UZGuVXY3;*^w3E0~_p?EDYQ$g= zQ?!Dqe~S57XM-K8md}Q2XV|5AUS6sol29#}kRN!(qBkkRJ6ZhG@RqV~|ZS1$%1MEHQ ze*^5p?2p)k?9bR=v#+ynv8S|ot)(q#muaW9=V&j|Uaj4&{kryM?IYU9wSTYuvG!-$ z6WTYl@937kuAkA*>F4!-slQAAi2iZ?bNUzcuj${^zoY+JfpHo(3diL1mj#V?5$i`R-@7jG7C6(1B2 zi$52Si*JbkCH~Q<7#(BTIBXm<|>Pbn6tk!0;% z+QYh}=xx#J;^lZxnyYa`+`t{Ee`6`4jg6FDgvlhh7)=T{+*Q8Woec*N4luvN0AN!=va3D-7%>6KE-? z)8}Jq& z(`>4vOx-h__8v5m_7h&j&=(8|h`WgR(*<6TKLyG}kjQa57(=sg_1B|asK;=uY{nVH zE}~d%fF06S%jcsZV))jSnvB@Jz+M%q^b!1zovq$cq1@aW<2Erq5uTQg2dFy7i9lR0 z;I0@u*;3d#Q@~wx;zl|te~LB&W#K)eakm$Xc7KfeCcL`nXf;C9CrbxeUlb9|A(V_uE%U<}oVSAwGk1dPj!JdH8; zBUEc^+%F0wZk3@FZc5vjjAIOZb&Md--L1F{H5o!x`munTjOwHfe~rK_%)?PPQPmp^ z$8j6_H!j8qMgYI@dy0{0JtRIC-IQ8+XX9dKZq38})Xh452%-6lt?c z@L8au$KyVga|7Pnbi8As~rLKmr)ZVh0(aK~7UMyzg( z+g%(kMLA=YuCfcGfkssy=}HB}Wk``}jC9n6ZWyZ}f?K-+VUATZ50gHWkwVvZ<3U#q z6!tMjx8Qy-O!MJDSsBo(yo-Sp#_?7cXE?$lBg|=U9JhEEe>(U^4?Zil@Ug z%EoyHFH~`b0#xs2TS)I}Egi@Xh$U59M=ItRY{(jp9FhfYDybkfG@EdlT6F=m31@OP z#L>i{z_G#!QDi#CJRoC`!Z;|SKF$LSMML)iAWYuQhAC(vST5X*bG3bt?Bv+k8~EfF z5MDP$5~(8$C_-AqjrCF9{P9-qyMWy?8YVj=LvSb2 zIvc5Px|`6s(AF*(7;vPeC_K(hh;*c$ignB|nUkDzMga_y<8w6uBa<0)CIKIlKy(%X zW0O~OZW^ovMeIu84j4gIM-i8$eUyY_0rMjUT|?!6lizeee+CBi(M>`8f{xPbb0`o$ zfMr3)_J%-SDBao!QHO$NYXl_1H*)W4m<4T+r7&JVA8N-6)0^WnpfQIc9@R4378EQmv(PO zzlLXOx~1v*%?LO33q+&3G^C@s=r=(OxXnVZ4{AuRe;}tMN7N||BPPHY)NuKYI2Z;< zbS~R)h3zBs7p8url%cPN+IxnlFm=qJrUNIcRAI$Kxdb;*D292ulmt+cgOF2jiDpqm zG-o-YCB@Xj_zV>Q2sh$}kb$Nd(`Xsj7l;s)#>!PhAx|+(mY5n)j-innB4a6pYuwD& z5L7G&e=S2S{Fvqmm34F;x&>~fpfG9(4{s5*>2w9|{}ZkZL78XpV%Qyt3e<*EW{%m` zCA64Bmth?CA-oKJSnwcx08^lNoVl9{c#G(oI*MK|Jg*x*#Z-G;+Vl#J-N&XU*%bZ_ zpQ9XO}Khr+NADz9<%Up?z# zvP9YMz}IJEuqKSW!t!Fe1q04G!fi&!;HyPlBG67oBQ!hOmcOXVTP#z3hL zW5wX@1Ehmpt{}_QZE6ivjq?=93_FKCLi1B3NB;XV*pcKNlrG{^7RlS;*k`64^(U&% zfAD%eL-Y(qBB~P@bK&DCmiBq9dyXKO!<&CX^%6zuWhC!s^x(l^LP!dZ1>H}`oAYKP z6{%+`%77Of-sc#?vYp zs!!0N(?kl$y+Bk)pv#<&u7_tEJC6eRvktqr$y!}V?e-uMl2OVjX{43K;O~=N;wE6UzOmP&}fZ_dx>GUBA z3qlQY8GVD%XAbOKqEP${L}7IDSY!_wUF@OmQAcA)*YUuZ=p1!j*ERQG_i~0r3>75g|1{P3}rRfV>pE| z94&@4>AGpj;R*dkpjnMsOwQ3+xDu3*=(N#vCeGe;X2{ZdKDv0b^i>vIAX2 z=T{B4YhsohX?l|TF4q}`jB5r$xkzd12GWqk0ys%ERKk?Fvp~PlU7_<5LqY^y%CY^X zZv@0QI+@`C!&nxsScJjDjOl`xfsjm(W6-G!B*$=u35gjBF3UP_r;RSFw57Nk-0XRm zf#}fG{O6!|SBY|Roja8%?bP-zq0u$gJZRC5jC0%L}!qNFiUQflbJ zt2nV+WK&t>F_?=K0bbGN8^)k;{e9qJ)43Zrg0Te*3G7O4?C?PN=2#uyeWh|ozQVnK$ zWTX2PrUYWjU4fVmkS>8En6pVJQKlG25&8}oe~GT-7b1h{BA19Tm~bWV5vKArC zQk66ZHD^>fly^RQTUaOt3?&qTIF;549x+ z$OU1bm<_C5*F4OBqtDF+KsCBDEd;0_8j-mX=i#h|c7vKme7G2=6f$dpvIcVsGZ;=A zF{=s84RnIWh$)aoM9p%p<~7Vfkh88Ze}F20-3wHjpo+Q*N>I3VGJ=MuF_sDk;87G4 zkJ+FVI$W7C=w?N*A;^oUvJxoTMHsxHk|rygP{$tB6%ekk*C*%mVs^GF=b2 z3ic>UN>p$$IU4k<4XxscZl~cKwTWRH9=eVZlo`~bDp+0(mWDmAD~KqxodoKef4XTS zWtI#A%~ufHnh6|2b5Vmu{3yJYE2T++VdIeLD((Y`P+5nV;2hy!QISTOO4Nm**=jZs zzN(l>usd~xCP!PhP8w*T8mN)eTwTi*<(c^~`3C(jTzG#pce z=S_35vp^$ay0XbodjkOstpiELe{%y8X^*G{0QGQmTtxa(X_u4@s>BbSY0nZhPK5=n zY~G*$+w-|tpnq5}(3hCB1Nb*=#_3?sM^t4e!ua^M^2f+g+47`}Q*WVhU%6=X#v}5* z7oNF|)Som2w~eB4an@SuymGN~LYl?HjmYrr%8`qrFxxr0w4t3$6Mbu{jeDz5F~Y0 zvW-sm%4N5bt(+~}ez>F`>144l7OXHV#$K%R)kHHyAWY!eW(UFRUJZn-ht{0VV%L}U zwOj`Q6_s7fbq%HU)ALd|r8qS$ZVIpB>F6&BdTL;}i7ZBrEp5z8f3Caspxe}RcjK;& ztLGP?Lf4&aMW$9--LfOo1Dnx}POi;MO$am0>TMH5usq=za66MpEAfg>klte2E;ef= zvO*5ZfCDO+G-tHsF}DyE<`D&a=1{77QblL5pubBtG0*dWJbCK1S(lPiyGPHQy1SE6 za(egTf5$E`_QCV?e~HrJdT3+g9hdI;rtHv<73@M0N-mJDXwS;SoD6;V*6+d_dH?Rt?wO;j zJG(opN6!-T)u&JUH~42iS*n-F!Ka=gzw!k9P3|GTGP&o58yhyvcqqE#RM3BT>VZ3Noa|h9;3YSnBkcX;k;#Sk zKm5Q0*>r17@3xAof-#IcYfxakNxhC6waK$n5lzT%0N`n#D>tfvU zEzPPSn#^}aXfKO#Cw6J+V&AFg#t~N~*E|Z6f5=ew6ll@KZQqW_MV9rl5?`wp5lk)y zn*eno;Mzv(E45^;7N9jZn%gWHXi4Cr6q#o`V6p}EDrmlvmC8n~J$HI*-nhGRGV-dL zXn?Lu49l}JvEGQ?NLd8@g{cEl-811}RmCPkliXC)$#Rf-7Cc>VdzI&)Y^8iySqqek zeAdU^x`!38zVEvh zjbo9<-681&4q=_{LqCN-pt!3iA0^iie|V!`YyXJM{iyvll59=>iZ&*Hz44QM|Ft#N zEo>EDQ}_&e?qVDUhO)HXDYyk+A;CPtoF@w19k*6`7+oHuJza^hVjF}LIx$USjdAl7 zsei9$Ry*@2r4!X{}l-(Q5g4-DY;Lj41}|8#1X9`fWtoWMuNeDlQM9Cn}FrmMXZ3 zMYuv=1}iOeV6Zz3%_dBw#p;;SUQ&z_CbaCMf_L=$4}Jnof=@p9?@>pB@A>afA-f0z+#sMKJ|$P3x(E9^4H+$p`wTr};T!yI-a^Hm0s zTZVd~v*OZb83b!|CPL-({04J+=?1FO{MCd^whuttYLrx42yO~bX;f7_ay3)GH-HXj z7;9^+R@f|@DBK79@tuX=E&N{Ly_l5(!$np|jDsg|tb*RCzsE^-7(yi?e;EACPx0qp zoq>WKz#OOT7O=J!dX=mzeuk0yvD$D{;NFN`&>Q5~zk_kk7b&J->(3Jsw}-*74@BIL zhwvS@+}N6CdOy??&DtpS%GhY0aOlywHM+>a*z zflzD1YIK;-frF891Y=r7e=C(c=7t$ZCX3)nEJ6rtG|ddxL5ru3K{)N3^FR9N3@jYa*&JcfBQa&$PH{Qhuw|8RKMaQKela4&A=f3x&61*cF&9D0K4 zqi7>EM>`{J6-1?`MNg%&#rT3zFCiPZ-}LO;*i~%x+Cv8}X2iM5j4nUKeU099`ucY@ zH|n&x(WDR2L*oaZfAmGyr%844!QR2676^tjyVqQrHXEf9_K)<3g_nYMmHSGg zW{Mg)OlJ5PsXVsRf8dtx%*|YdNMas${LIzW93)ue9_*++C$j_`7#F7eAeGe3eZz8v zxHlrdV&pqsqLOk41}@NTBc)*dMScQf5GY(44I#uueFN-K*Tmec661lvNGy%fwAW&o z@?dHi?KvYfJx`jB^p~zZ3^tlDbjvgjH$o@WbdMQN0-xo!f0p_>H$yPlyv9}vT5PL4 zUy2=2h~t`Jf;bY?(i@1EVS?Re6&(XCWA5B?EprS|ntRoD3#6_UY8D#Rx-DGY*!4AB zr&HObIcUC5%lmqsRY8BM<#8q}WE74OUVrM`pQ5J-=Hg6fVmMMe0F>KVQ7|o`qk9I; z4sTJK9bF-Bf2N>)n#Vv~h~D!rS-$q|l_jlNu4URh>a0LaTdV{n+8{AP(3L7mTg!kW z^igN)jy=%BQZZ-G0pZ4rp}0@CEYQAJ9(T{kcPMf6-EQEWU+4bp3X7ef_KPW#mnh zzr22(+<2&U{q?=cQ`e8OY;-*wEIo((;AH%q$xC|6f0-Sc{N-*9s~)TR-v~1A>6+#~ zKKwRVmd6U06;2k;7Op8=t8k?XomrBLsedl%2kq#eWnud-_WyA%n7+~sO|g~=eB~-Q zzT0lCf5Xh&8uwtZ*qKRD7=|D};L@1>REAUE{#|PO`U()Geay*_qSbS5s zP-Z6lvGPLb280AFPKs;0sq?=9mByKNc${NkWME(bVkP5+RkPyxZN4&aGrs_eFx+RE zvjmxDzRcVYq&OIuKs*33n+iCSnu_Ot$RZphx+W$jv?lZ?5GO7uW+}cckS)F~_%0GI zGA@2D)Gtym=rB+)vM}s1Br#Gls51OBjx=sHHZ{C9!Z$iMR5%zoGB|8Fq&Z?bj5@YD z?mLJ)oIWN#Tt1>dG(U(!Y(n@$q(kgPZbZsOT1GrZmPYzVhDYv5hDjhv+DZH@O5RHX wON>kWOlVq^TJl@MTlQQOTu@woT*O{HUSeNXU@~BGVIpBxVYXsmvn-4#1+x-0F#rGn diff --git a/extensions/theme-seti/icons/vs-seti-icon-theme.json b/extensions/theme-seti/icons/vs-seti-icon-theme.json index 9c9ac36bfe..99ec649e9e 100644 --- a/extensions/theme-seti/icons/vs-seti-icon-theme.json +++ b/extensions/theme-seti/icons/vs-seti-icon-theme.json @@ -750,14 +750,6 @@ "fontCharacter": "\\E050", "fontColor": "#cc3e44" }, - "_java_1_light": { - "fontCharacter": "\\E050", - "fontColor": "#498ba7" - }, - "_java_1": { - "fontCharacter": "\\E050", - "fontColor": "#519aba" - }, "_javascript_light": { "fontCharacter": "\\E051", "fontColor": "#b7b73b" @@ -1656,7 +1648,7 @@ "hxp": "_haxe_2", "hxml": "_haxe_3", "jade": "_jade", - "class": "_java_1", + "class": "_java", "classpath": "_java", "js.map": "_javascript", "spec.js": "_javascript_1", @@ -1728,7 +1720,6 @@ "tf": "_terraform", "tf.json": "_terraform", "tfvars": "_terraform", - "tfvars.json": "_terraform", "dtx": "_tex_2", "ins": "_tex_3", "toml": "_config", @@ -1919,7 +1910,6 @@ "clojure": "_clojure", "coffeescript": "_coffee", "jsonc": "_json", - "json": "_json", "c": "_c", "cpp": "_cpp", "cuda-cpp": "_cu", @@ -1929,7 +1919,6 @@ "dockerfile": "_docker", "ignore": "_git", "fsharp": "_f-sharp", - "git-commit": "_git", "go": "_go2", "groovy": "_grails", "handlebars": "_mustache", @@ -1938,6 +1927,7 @@ "java": "_java", "javascriptreact": "_react", "javascript": "_javascript", + "json": "_json", "julia": "_julia", "tex": "_tex_1", "latex": "_tex", @@ -1993,8 +1983,7 @@ "vala": "_vala", "vue": "_vue", "postcss": "_css", - "django-html": "_html_3", - "blade": "_php" + "django-html": "_html_3" }, "light": { "file": "_default_light", @@ -2073,7 +2062,7 @@ "hxp": "_haxe_2_light", "hxml": "_haxe_3_light", "jade": "_jade_light", - "class": "_java_1_light", + "class": "_java_light", "classpath": "_java_light", "js.map": "_javascript_light", "spec.js": "_javascript_1_light", @@ -2145,7 +2134,6 @@ "tf": "_terraform_light", "tf.json": "_terraform_light", "tfvars": "_terraform_light", - "tfvars.json": "_terraform_light", "dtx": "_tex_2_light", "ins": "_tex_3_light", "toml": "_config_light", @@ -2244,7 +2232,6 @@ "clojure": "_clojure_light", "coffeescript": "_coffee_light", "jsonc": "_json_light", - "json": "_json_light", "c": "_c_light", "cpp": "_cpp_light", "cuda-cpp": "_cu_light", @@ -2254,7 +2241,6 @@ "dockerfile": "_docker_light", "ignore": "_git_light", "fsharp": "_f-sharp_light", - "git-commit": "_git_light", "go": "_go2_light", "groovy": "_grails_light", "handlebars": "_mustache_light", @@ -2263,6 +2249,7 @@ "java": "_java_light", "javascriptreact": "_react_light", "javascript": "_javascript_light", + "json": "_json_light", "julia": "_julia_light", "tex": "_tex_1_light", "latex": "_tex_light", @@ -2317,8 +2304,7 @@ "scmp": "scmp", "vue": "_vue_light", "postcss": "_css_light", - "django-html": "_html_3_light", - "blade": "_php_light" + "django-html": "_html_3_light" }, "fileNames": { "mix": "_hex_light", @@ -2403,5 +2389,5 @@ "Schema Compare": "scmp" } }, - "version": "https://github.com/jesseweed/seti-ui/commit/2d10473b7575ec00c47eda751ea9caeec6b0b606" + "version": "https://github.com/jesseweed/seti-ui/commit/8dba1bc311dad1b9bc23c4779149f3bf9baa8cb0" } diff --git a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json index d13c42c0bb..85cdac449d 100644 --- a/extensions/theme-solarized-light/themes/solarized-light-color-theme.json +++ b/extensions/theme-solarized-light/themes/solarized-light-color-theme.json @@ -488,9 +488,6 @@ "terminal.ansiBrightMagenta": "#6c71c4", "terminal.ansiBrightCyan": "#93a1a1", "terminal.ansiBrightWhite": "#fdf6e3", - // Set terminal background explicitly, otherwise selection becomes invisible when the - // terminal is in the side bar - "terminal.background": "#FDF6E3", // Interactive Playground "walkThrough.embeddedEditorBackground": "#00000014" }, diff --git a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json index b37fd6b008..70b57d594f 100644 --- a/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json +++ b/extensions/theme-tomorrow-night-blue/themes/tomorrow-night-blue-color-theme.json @@ -65,7 +65,7 @@ } }, { - "scope": ["meta.embedded", "source.groovy.embedded", "meta.jsx.children"], + "scope": ["meta.embedded", "source.groovy.embedded"], "settings": { //"background": "#002451", "foreground": "#FFFFFF" diff --git a/extensions/typescript-language-features/src/experimentationService.ts b/extensions/typescript-language-features/src/experimentationService.ts deleted file mode 100644 index a0693a56b7..0000000000 --- a/extensions/typescript-language-features/src/experimentationService.ts +++ /dev/null @@ -1,93 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as vscode from 'vscode'; -import VsCodeTelemetryReporter from '@vscode/extension-telemetry'; -import * as tas from 'vscode-tas-client'; - -interface ExperimentTypes { - // None for now. -} - -export class ExperimentationService implements vscode.Disposable { - private _experimentationServicePromise: Promise; - private _telemetryReporter: ExperimentTelemetryReporter; - - constructor(private readonly _extensionContext: vscode.ExtensionContext) { - this._telemetryReporter = new ExperimentTelemetryReporter(_extensionContext); - this._experimentationServicePromise = this.createExperimentationService(); - } - - public async getTreatmentVariable(name: K, defaultValue: ExperimentTypes[K]): Promise { - const experimentationService = await this._experimentationServicePromise; - try { - const treatmentVariable = experimentationService.getTreatmentVariableAsync('vscode', name, /*checkCache*/ true) as ExperimentTypes[K]; - return treatmentVariable; - } catch { - return defaultValue; - } - } - - private async createExperimentationService(): Promise { - let targetPopulation: tas.TargetPopulation; - switch (vscode.env.uriScheme) { - case 'vscode': - targetPopulation = tas.TargetPopulation.Public; - case 'vscode-insiders': - targetPopulation = tas.TargetPopulation.Insiders; - case 'vscode-exploration': - targetPopulation = tas.TargetPopulation.Internal; - case 'code-oss': - targetPopulation = tas.TargetPopulation.Team; - default: - targetPopulation = tas.TargetPopulation.Public; - } - - const id = this._extensionContext.extension.id; - const version = this._extensionContext.extension.packageJSON.version || ''; - const experimentationService = tas.getExperimentationService(id, version, targetPopulation, this._telemetryReporter, this._extensionContext.globalState); - await experimentationService.initialFetch; - return experimentationService; - } - - - /** - * @inheritdoc - */ - public dispose() { - this._telemetryReporter.dispose(); - } -} - -export class ExperimentTelemetryReporter - implements tas.IExperimentationTelemetry, vscode.Disposable { - private _sharedProperties: Record = {}; - private _reporter: VsCodeTelemetryReporter; - constructor(ctxt: vscode.ExtensionContext) { - const extension = ctxt.extension; - const packageJSON = extension.packageJSON; - this._reporter = new VsCodeTelemetryReporter( - extension.id, - packageJSON.version || '', - packageJSON.aiKey || ''); - - } - - setSharedProperty(name: string, value: string): void { - this._sharedProperties[name] = value; - } - - postEvent(eventName: string, props: Map): void { - const propsObject = { - ...this._sharedProperties, - ...Object.fromEntries(props), - }; - this._reporter.sendTelemetryEvent(eventName, propsObject); - } - - dispose() { - this._reporter.dispose(); - } -} diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts deleted file mode 100644 index 2b9effc8ff..0000000000 --- a/extensions/vscode-api-tests/src/singlefolder-tests/interactiveWindow.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import 'mocha'; -import * as vscode from 'vscode'; -import { disposeAll } from '../utils'; -import { Kernel, saveAllFilesAndCloseAll } from './notebook.test'; - -export type INativeInteractiveWindow = { notebookUri: vscode.Uri; inputUri: vscode.Uri; notebookEditor: vscode.NotebookEditor }; - -async function createInteractiveWindow(kernel: Kernel) { - const { notebookEditor } = (await vscode.commands.executeCommand( - 'interactive.open', - // Keep focus on the owning file if there is one - { viewColumn: vscode.ViewColumn.Beside, preserveFocus: false }, - undefined, - `vscode.vscode-api-tests/${kernel.controller.id}`, - undefined - )) as unknown as INativeInteractiveWindow; - - return notebookEditor; -} - -async function addCell(code: string, notebook: vscode.NotebookDocument) { - const cell = new vscode.NotebookCellData(vscode.NotebookCellKind.Code, code, 'typescript'); - const edit = vscode.NotebookEdit.insertCells(notebook.cellCount, [cell]); - const workspaceEdit = new vscode.WorkspaceEdit(); - workspaceEdit.set(notebook.uri, [edit]); - await vscode.workspace.applyEdit(workspaceEdit); - return notebook.cellAt(notebook.cellCount - 1); -} - -async function addCellAndRun(code: string, notebook: vscode.NotebookDocument, i: number) { - const cell = await addCell(code, notebook); - await vscode.commands.executeCommand('notebook.cell.execute', { start: i, end: i + 1 }); - assert.strictEqual(cell.outputs.length, 1, 'execute failed'); - return cell; -} - - -(vscode.env.uiKind === vscode.UIKind.Web ? suite.skip : suite)('Interactive Window', function () { - - const testDisposables: vscode.Disposable[] = []; - let defaultKernel: Kernel; - let secondKernel: Kernel; - - setup(async function () { - defaultKernel = new Kernel('mainKernel', 'Notebook Default Kernel', 'interactive'); - secondKernel = new Kernel('secondKernel', 'Notebook Secondary Kernel', 'interactive'); - testDisposables.push(defaultKernel.controller); - testDisposables.push(secondKernel.controller); - await saveAllFilesAndCloseAll(); - }); - - teardown(async function () { - disposeAll(testDisposables); - testDisposables.length = 0; - await saveAllFilesAndCloseAll(); - }); - - test('Can open an interactive window', async () => { - assert.ok(vscode.workspace.workspaceFolders); - const notebookEditor = await createInteractiveWindow(defaultKernel); - assert.ok(notebookEditor); - - // Try adding a cell and running it. - await addCell('print foo', notebookEditor.notebook); - - assert.strictEqual(notebookEditor.notebook.cellCount, 1); - assert.strictEqual(notebookEditor.notebook.cellAt(0).kind, vscode.NotebookCellKind.Code); - }); - - test('Interactive window scrolls after execute', async () => { - assert.ok(vscode.workspace.workspaceFolders); - const notebookEditor = await createInteractiveWindow(defaultKernel); - assert.ok(notebookEditor); - - // Run and add a bunch of cells - for (let i = 0; i < 10; i++) { - await addCellAndRun(`print ${i}`, notebookEditor.notebook, i); - } - - // Verify visible range has the last cell - assert.strictEqual(notebookEditor.visibleRanges[notebookEditor.visibleRanges.length - 1].end, notebookEditor.notebook.cellCount, `Last cell is not visible`); - - }); - - test('Interactive window has the correct kernel', async () => { - assert.ok(vscode.workspace.workspaceFolders); - const notebookEditor = await createInteractiveWindow(defaultKernel); - assert.ok(notebookEditor); - - await vscode.commands.executeCommand('workbench.action.closeActiveEditor'); - - // Create a new interactive window with a different kernel - const notebookEditor2 = await createInteractiveWindow(secondKernel); - assert.ok(notebookEditor2); - - // Verify the kernel is the secondary one - await addCellAndRun(`print`, notebookEditor2.notebook, 0); - - assert.strictEqual(secondKernel.associatedNotebooks.has(notebookEditor2.notebook.uri.toString()), true, `Secondary kernel was not set as the kernel for the interactive window`); - - }); -}); diff --git a/extensions/vscode-test-resolver/src/extension.ts b/extensions/vscode-test-resolver/src/extension.ts index fd6f483a48..84a9d6ba89 100644 --- a/extensions/vscode-test-resolver/src/extension.ts +++ b/extensions/vscode-test-resolver/src/extension.ts @@ -25,7 +25,7 @@ let outputChannel: vscode.OutputChannel; export function activate(context: vscode.ExtensionContext) { let connectionPaused = false; - const connectionPausedEvent = new vscode.EventEmitter(); + let connectionPausedEvent = new vscode.EventEmitter(); function doResolve(_authority: string, progress: vscode.Progress<{ message?: string; increment?: number }>): Promise { if (connectionPaused) { @@ -159,7 +159,7 @@ export function activate(context: vscode.ExtensionContext) { let isDisconnected = false; const handleConnectionPause = () => { - const newIsDisconnected = connectionPaused; + let newIsDisconnected = connectionPaused; if (isDisconnected !== newIsDisconnected) { outputChannel.appendLine(`Connection state: ${newIsDisconnected ? 'open' : 'paused'}`); isDisconnected = newIsDisconnected; diff --git a/extensions/xml-language-features/tsconfig.json b/extensions/xml-language-features/tsconfig.json index ac03ca408b..662cf2ddf2 100644 --- a/extensions/xml-language-features/tsconfig.json +++ b/extensions/xml-language-features/tsconfig.json @@ -10,6 +10,7 @@ "include": [ "src/**/*", "../../src/vscode-dts/vscode.d.ts", - "../../src/vscode-dts/vscode.proposed.notebookWorkspaceEdit.d.ts" + "../../src/vscode-dts/vscode.proposed.d.ts", + "../../src/vscode-dts/vscode.proposed.notebookEditorEdit.d.ts" ] } diff --git a/extensions/xml/xml.language-configuration.json b/extensions/xml/xml.language-configuration.json index 4706ceec5f..d04db08380 100644 --- a/extensions/xml/xml.language-configuration.json +++ b/extensions/xml/xml.language-configuration.json @@ -34,6 +34,7 @@ } }, "wordPattern": { - "pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)" + "pattern": "[:A-Z_a-z\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2FF}\\u{370}-\\u{37D}\\u{37F}-\\u{1FFF}\\u{200C}-\\u{200D}\\u{2070}-\\u{218F}\\u{2C00}-\\u{2FEF}\\u{3001}-\\u{D7FF}\\u{F900}-\\u{FDCF}\\u{FDF0}-\\u{FFFD}\\u{10000}-\\u{EFFFF}][-:A-Z_a-z\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2FF}\\u{370}-\\u{37D}\\u{37F}-\\u{1FFF}\\u{200C}-\\u{200D}\\u{2070}-\\u{218F}\\u{2C00}-\\u{2FEF}\\u{3001}-\\u{D7FF}\\u{F900}-\\u{FDCF}\\u{FDF0}-\\u{FFFD}\\u{10000}-\\u{EFFFF}.0-9\\u{B7}\\u{0300}-\\u{036F}\\u{203F}-\\u{2040}]*", + "flags": "u" } } diff --git a/extensions/xml/xsl.language-configuration.json b/extensions/xml/xsl.language-configuration.json index 63c5c75d5c..5abe96006b 100644 --- a/extensions/xml/xsl.language-configuration.json +++ b/extensions/xml/xsl.language-configuration.json @@ -11,7 +11,8 @@ ["[", "]"] ], "wordPattern": { - "pattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)" + "pattern": "[:A-Z_a-z\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2FF}\\u{370}-\\u{37D}\\u{37F}-\\u{1FFF}\\u{200C}-\\u{200D}\\u{2070}-\\u{218F}\\u{2C00}-\\u{2FEF}\\u{3001}-\\u{D7FF}\\u{F900}-\\u{FDCF}\\u{FDF0}-\\u{FFFD}\\u{10000}-\\u{EFFFF}][-:A-Z_a-z\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2FF}\\u{370}-\\u{37D}\\u{37F}-\\u{1FFF}\\u{200C}-\\u{200D}\\u{2070}-\\u{218F}\\u{2C00}-\\u{2FEF}\\u{3001}-\\u{D7FF}\\u{F900}-\\u{FDCF}\\u{FDF0}-\\u{FFFD}\\u{10000}-\\u{EFFFF}.0-9\\u{B7}\\u{0300}-\\u{036F}\\u{203F}-\\u{2040}]*", + "flags": "u" } // enhancedBrackets: [{ diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 7b4407130a..13a2f75ef0 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -10,17 +10,17 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -coffeescript@1.12.7: +coffee-script@^1.10.0: version "1.12.7" - resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27" - integrity sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA== + resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53" + integrity sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw== -cson-parser@^4.0.9: - version "4.0.9" - resolved "https://registry.yarnpkg.com/cson-parser/-/cson-parser-4.0.9.tgz#eef0cf77edd057f97861ef800300c8239224eedb" - integrity sha512-I79SAcCYquWnEfXYj8hBqOOWKj6eH6zX1hhX3yqmS4K3bYp7jME3UFpHPzu3rUew0oyfc0s8T6IlWGXRAheHag== +cson-parser@^1.3.3: + version "1.3.5" + resolved "https://registry.yarnpkg.com/cson-parser/-/cson-parser-1.3.5.tgz#7ec675e039145533bf2a6a856073f1599d9c2d24" + integrity sha1-fsZ14DkUVTO/KmqFYHPxWZ2cLSQ= dependencies: - coffeescript "1.12.7" + coffee-script "^1.10.0" esbuild@^0.11.12: version "0.11.23" @@ -47,10 +47,10 @@ typescript@^4.8.0-dev.20220614: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.0-dev.20220714.tgz#9c1be002c44c3566e789aa404b2f94b0b96468cc" integrity sha512-wKK9FMpdvwI68PZiQdNTNmX4rpVXJBDOG9aylV9O6nJUO5YX8yv3bQNcyLc5tbI7J3+u7AU48LVY9SF9lYwy5g== -vscode-grammar-updater@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vscode-grammar-updater/-/vscode-grammar-updater-1.1.0.tgz#030eacd8b8ba8f3f2fe43c9032601f839ba811c4" - integrity sha512-rWcJXyEFK27Mh9bxfBTLaul0KiGQk0GMXj2qTDH9cy3UZVx5MrF035B03os1w4oIXwl/QDhdLnsBK0j2SNiL1A== +vscode-grammar-updater@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vscode-grammar-updater/-/vscode-grammar-updater-1.0.4.tgz#f0b8bd106a499a15f3e6b199055908ed8e860984" + integrity sha512-WjmpFo+jlnxOfHNeSrO3nJx8S2u3f926UL0AHJhDMQghCwEfkMvf37aafF83xvtLW2G9ywhifLbq4caxDQm+wQ== dependencies: - cson-parser "^4.0.9" + cson-parser "^1.3.3" fast-plist "0.1.2" diff --git a/package.json b/package.json index 23e1b5d64f..9224aa94bf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "azuredatastudio", "version": "1.44.0", - "distro": "5bd81cccd1b758c671648c7770966b250e3edbc2", + "distro": "2cd50bd144845cd70df1cb0ed301c64d3e585ded", "author": { "name": "Microsoft Corporation" }, @@ -41,7 +41,7 @@ "strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization", "tsec-compile-check": "node node_modules/tsec/bin/tsec -p src/tsconfig.tsec.json", "vscode-dts-compile-check": "tsc -p src/tsconfig.vscode-dts.json && tsc -p src/tsconfig.vscode-proposed-dts.json", - "valid-layers-check": "node --max_old_space_size=8192 build/lib/layersChecker.js", + "valid-layers-check": "node build/lib/layersChecker.js", "update-distro": "node build/npm/update-distro.mjs", "web": "echo 'yarn web' is replaced by './scripts/code-server' or './scripts/code-web'", "compile-web": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js compile-web", @@ -57,8 +57,7 @@ "core-ci": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js core-ci", "extensions-ci": "node --max_old_space_size=4095 ./node_modules/gulp/bin/gulp.js extensions-ci", "sqllint": "node --max_old_space_size=4095 ./node_modules/eslint/bin/eslint.js --no-eslintrc -c .eslintrc.sql.ts.json --rulesdir ./build/lib/eslint --ext .ts ./src/sql", - "extensions-lint": "node --max_old_space_size=4095 ./node_modules/eslint/bin/eslint.js --rulesdir ./build/lib/eslint --ext .ts ./extensions", - "webview-generate-csp-hash": "npx github:apaatsio/csp-hash-from-html csp-hash ./src/vs/workbench/contrib/webview/browser/pre/index.html" + "extensions-lint": "node --max_old_space_size=4095 ./node_modules/eslint/bin/eslint.js --rulesdir ./build/lib/eslint --ext .ts ./extensions" }, "dependencies": { "@angular/animations": "~4.1.3", @@ -71,6 +70,7 @@ "@angular/router": "~4.1.3", "@microsoft/1ds-core-js": "^3.2.2", "@microsoft/1ds-post-js": "^3.2.2", + "@microsoft/applicationinsights-web": "^2.8.4", "@parcel/watcher": "2.0.5", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/ripgrep": "^1.14.2", @@ -105,20 +105,19 @@ "semver-umd": "^5.5.7", "slickgrid": "github:Microsoft/SlickGrid.ADS#2.3.43", "spdlog": "^0.13.0", - "tas-client-umd": "0.1.6", + "tas-client-umd": "0.1.4", "turndown": "^7.0.0", "turndown-plugin-gfm": "^1.0.2", "v8-inspect-profiler": "^0.0.22", "vscode-oniguruma": "1.6.1", - "vscode-policy-watcher": "^1.1.1", "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", - "xterm": "4.20.0-beta.20", - "xterm-addon-search": "0.10.0-beta.3", - "xterm-addon-serialize": "0.8.0-beta.3", + "xterm": "4.19.0-beta.25", + "xterm-addon-search": "0.9.0-beta.25", + "xterm-addon-serialize": "0.7.0-beta.12", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.13.0-beta.9", + "xterm-addon-webgl": "0.12.0-beta.29", "xterm-headless": "4.19.0-beta.25", "yauzl": "^2.9.2", "yazl": "^2.4.3", @@ -148,7 +147,7 @@ "@types/sinon": "^10.0.2", "@types/sinon-test": "^2.4.2", "@types/trusted-types": "^1.0.6", - "@types/vscode-notebook-renderer": "1.60.0", + "@types/vscode-notebook-renderer": "^1.60.0", "@types/webpack": "^4.41.25", "@types/wicg-file-system-access": "^2020.9.5", "@types/windows-foreground-love": "^0.3.0", @@ -160,7 +159,7 @@ "@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/parser": "^5.10.0", "@vscode/telemetry-extractor": "^1.9.6", - "@vscode/test-web": "^0.0.29", + "@vscode/test-web": "^0.0.22", "ansi-colors": "^3.2.3", "asar": "^3.0.3", "chromium-pickle-js": "^0.2.0", @@ -168,18 +167,18 @@ "cookie": "^0.4.0", "copy-webpack-plugin": "^6.0.3", "cson-parser": "^1.3.3", - "css-loader": "^3.6.0", + "css-loader": "^3.2.0", "cssnano": "^4.1.11", "debounce": "^1.0.0", "deemon": "^1.8.0", "electron": "19.1.8", "eslint": "8.7.0", "eslint-plugin-header": "3.1.1", - "eslint-plugin-jsdoc": "^39.3.2", + "eslint-plugin-jsdoc": "^19.1.0", "event-stream": "3.3.4", "fancy-log": "^1.3.3", "fast-plist": "0.1.2", - "file-loader": "^5.1.0", + "file-loader": "^4.2.0", "glob": "^5.0.13", "gulp": "^4.0.0", "gulp-atom-electron": "^1.33.0", @@ -201,6 +200,7 @@ "gulp-shell": "^0.6.5", "gulp-sourcemaps": "^3.0.0", "gulp-svgmin": "^4.1.0", + "gulp-tsb": "4.0.6", "gulp-untar": "^0.0.7", "gulp-vinyl-zip": "^2.1.2", "husky": "^0.13.1", @@ -231,7 +231,7 @@ "request": "^2.85.0", "rimraf": "^2.2.8", "sinon": "^11.1.1", - "sinon-test": "^3.1.3", + "sinon-test": "^3.1.0", "source-map": "0.6.1", "source-map-support": "^0.3.2", "style-loader": "^1.0.0", @@ -239,7 +239,7 @@ "ts-loader": "^9.2.7", "tsec": "0.1.4", "typemoq": "^0.3.2", - "typescript": "^4.8.0-dev.20220518", + "typescript": "^4.7.0-dev.20220502", "typescript-formatter": "7.1.0", "underscore": "^1.12.1", "util": "^0.12.4", diff --git a/remote/.yarnrc b/remote/.yarnrc index 3a3fbdc335..290849a6e6 100644 --- a/remote/.yarnrc +++ b/remote/.yarnrc @@ -1,4 +1,4 @@ disturl "http://nodejs.org/dist" -target "16.14.2" +target "16.13.2" runtime "node" build_from_source "true" diff --git a/remote/package.json b/remote/package.json index 51d4337d86..5c75e805c5 100755 --- a/remote/package.json +++ b/remote/package.json @@ -13,6 +13,7 @@ "@angular/router": "~4.1.3", "@microsoft/1ds-core-js": "^3.2.2", "@microsoft/1ds-post-js": "^3.2.2", + "@microsoft/applicationinsights-web": "^2.8.4", "@parcel/watcher": "2.0.5", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/ripgrep": "^1.14.2", @@ -45,16 +46,16 @@ "slickgrid": "github:Microsoft/SlickGrid.ADS#2.3.43", "turndown": "^7.0.0", "turndown-plugin-gfm": "^1.0.2", - "tas-client-umd": "0.1.6", + "tas-client-umd": "0.1.4", "vscode-oniguruma": "1.6.1", "vscode-proxy-agent": "^0.12.0", "vscode-regexpp": "^3.1.0", "vscode-textmate": "7.0.1", - "xterm": "4.20.0-beta.20", - "xterm-addon-search": "0.10.0-beta.3", - "xterm-addon-serialize": "0.8.0-beta.3", + "xterm": "4.19.0-beta.25", + "xterm-addon-search": "0.9.0-beta.25", + "xterm-addon-serialize": "0.7.0-beta.12", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.13.0-beta.9", + "xterm-addon-webgl": "0.12.0-beta.29", "xterm-headless": "4.19.0-beta.25", "yauzl": "^2.9.2", "yazl": "^2.4.3", diff --git a/remote/web/package.json b/remote/web/package.json index f1b07fbf72..e63da3f37f 100755 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -13,6 +13,7 @@ "@angular/router": "~4.1.3", "@microsoft/1ds-core-js": "^3.2.2", "@microsoft/1ds-post-js": "^3.2.2", + "@microsoft/applicationinsights-web": "^2.8.4", "@vscode/iconv-lite-umd": "0.7.0", "@vscode/vscode-languagedetection": "1.0.21", "angular2-grid": "2.0.6", @@ -33,12 +34,12 @@ "slickgrid": "github:Microsoft/SlickGrid.ADS#2.3.43", "turndown": "^7.0.0", "turndown-plugin-gfm": "^1.0.2", - "tas-client-umd": "0.1.6", + "tas-client-umd": "0.1.4", "vscode-oniguruma": "1.6.1", "vscode-textmate": "7.0.1", - "xterm": "4.20.0-beta.20", - "xterm-addon-search": "0.10.0-beta.3", + "xterm": "4.19.0-beta.25", + "xterm-addon-search": "0.9.0-beta.25", "xterm-addon-unicode11": "0.4.0-beta.3", - "xterm-addon-webgl": "0.13.0-beta.9" + "xterm-addon-webgl": "0.12.0-beta.29" } } diff --git a/remote/web/yarn.lock b/remote/web/yarn.lock index 804792c54d..ce1a2f713b 100644 --- a/remote/web/yarn.lock +++ b/remote/web/yarn.lock @@ -42,41 +42,112 @@ resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.1.3.tgz#ddafd46ae7ccc8b1f74904ffb45f394e44625216" integrity sha512-i+1GMIvfM3OC6XX2kZf+tL36Nc4jhcMNOY6bOrmwlN8APl59I9KqdvywC5HnutkDctb8expiWTIuSKZQAc4AIA== -"@microsoft/1ds-core-js@3.2.9", "@microsoft/1ds-core-js@^3.2.2": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.9.tgz#8a26935966e4871d1f1e40d992828bdd52bba84e" - integrity sha512-3pCfM2TzHn3gU9pxHztduKcVRdb/nzruvPFfHPZD0IM0mb0h6TGo2isELF3CTMahTx50RAC51ojNIw2/7VRkOg== +"@microsoft/1ds-core-js@3.2.6", "@microsoft/1ds-core-js@^3.2.2": + version "3.2.6" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.6.tgz#8a77909f89f991aa2f0b4ae8825c75042962e68e" + integrity sha512-6OpppYCEA+rXjcs2w0KnWji3Y6ZDx0wykY7ZL3QF68NS323C45GHSpkDpVRT/lDU6Xbau/PvQm2zTYAzLcperA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.10" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "2.8.6" + "@microsoft/applicationinsights-shims" "^2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" "@microsoft/1ds-post-js@^3.2.2": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.9.tgz#07030f7455cb4ac8993e9b0bfa6c78ebfe25b499" - integrity sha512-D/RtqkQ2Nr4cuoGqmhi5QTmi3cBlxehIThJ1u3BaH9H/YkLNTKEcHZRWTXy14bXheCefNHciLuadg37G2Kekcg== + version "3.2.6" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.6.tgz#cdfa74acfc3205c0a5b79925284d6d166aa43901" + integrity sha512-Zdyl3FU6kU/a7TlVVSTBZg+hSECTT65iI99FsjMOx88HudyVyk9M/0lVbA+FVXvGaxzmtBW6Lw0qRHYp4tBMSA== dependencies: - "@microsoft/1ds-core-js" "3.2.9" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/1ds-core-js" "3.2.6" + "@microsoft/applicationinsights-shims" "^2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" -"@microsoft/applicationinsights-core-js@2.8.10": - version "2.8.10" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.10.tgz#beb96a97a046ddb031d6adecf0d3143b635edf42" - integrity sha512-jQrufDW0+sV8fBhRvzIPNGiCC6dELH+Ug0DM5CfN9757TBqZJz8CSWyDjex39as8+jD0F/8HRU9QdmrVgq5vFg== +"@microsoft/applicationinsights-analytics-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.8.7.tgz#dea44f5bbfb150e12f256b0c45ba6756276df9b6" + integrity sha512-WEsbh3yOzjo1DnH6NyVS/W9uXEWJkb0mgOHTnq3An2nvyT7HPzd56hqRfyJsWR2KAU6hvZ09l7OK85AjkfEqJA== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" -"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" - integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== +"@microsoft/applicationinsights-channel-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.7.tgz#365b29842229ba615badc5f9c3f3ebc5c6ce7ef1" + integrity sha512-Ee2zp6Ij/Btnc9P8bVBXUIa4/X8HH1hNYpL2ALGfhwbWOUxoR+1+0FZpj+/H9vf2PP/8eS5r28MCoksbGUH+8A== + dependencies: + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" -"@microsoft/dynamicproto-js@^1.1.7": - version "1.1.7" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" - integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== +"@microsoft/applicationinsights-common@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.7.tgz#8ac4d63450e8108ac1ce96750d32e286935388f7" + integrity sha512-bODgacISioOVZIYho1QUADVZh4jjFRQhfVokHbFUgDsJ1NgfpDdNlv+idxH9oriBEuf9odWnOM9jfr3OMcVicA== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-core-js@2.8.6": + version "2.8.6" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.6.tgz#4f0f9ad809aacfc96cb882139b69b3625519c51a" + integrity sha512-rL+ceda1Y6HaHBe1vIbNT/f5JGuHiD5Ydq+DoAfu56o13wyJu4sao3QKaabgaIM59pPO+3BMeGsK8NNUGYaT3w== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-core-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.7.tgz#3c43517bc6fdf2da59aa90708cefcf936db75488" + integrity sha512-y7USumU+a/kbDeORr/dnDFAxcS5+KOFJSM5oUkS8tBu7CYcX1QAGF4X11gdH2NjrGgHjgxhERhYRa/YhwY1NOQ== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-dependencies-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.8.7.tgz#fe7e52ec0a3f18d66cb6c43af529c05858e0cbde" + integrity sha512-lLRZPCi4Aq+sJThiO6QeFfZguuvZkH8VbceMz3jNF8S1KvPC0174eVcihMPDrjErPXGcquH1fKvJn3PionhZuw== + dependencies: + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-properties-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.8.7.tgz#6ec96789c3add4e93a1511bfcd946859622355f3" + integrity sha512-wEa2XJ3PAymFLcOajl7KwhLS2JGFW3SbF2lYsGeP/efIJewTRbB1l+6QgbNWiOCvPd4cpiq2jRdrgKaQpJN37Q== + dependencies: + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" + integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== + +"@microsoft/applicationinsights-web@^2.8.4": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.8.7.tgz#23f5891768b6da6e4cdcc1a8d0cdf1b7b1376b1e" + integrity sha512-m0GufymksDAOarHnUzQ72d0RIAS2faY9xNnwAb7J08qOuDRqgnKamDH5U6af6Tjla4N1Ql2nOGLqQYg88/QjrQ== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.8.7" + "@microsoft/applicationinsights-channel-js" "2.8.7" + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-dependencies-js" "2.8.7" + "@microsoft/applicationinsights-properties-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/dynamicproto-js@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" + integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== "@vscode/iconv-lite-umd@0.7.0": version "0.7.0" @@ -227,9 +298,9 @@ has-flag@^3.0.0: integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== html-to-image@^1.6.2: - version "1.11.11" - resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-1.11.11.tgz#c0f8a34dc9e4b97b93ff7ea286eb8562642ebbea" - integrity sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-1.9.0.tgz#cb49bf9f4b37376771c85cfdd65863ae9420b268" + integrity sha512-9gaDCIYg62Ek07F2pBk76AHgYZ2gxq2YALU7rK3gNCqXuhu6cWzsOQqM7qGbjZiOzxGzrU1deDqZpAod2NEwbA== htmlparser2@^3.9.0: version "3.10.1" @@ -320,9 +391,9 @@ postcss@^6.0.14: supports-color "^5.4.0" readable-stream@^3.1.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.1.tgz#f9f9b5f536920253b3d26e7660e7da4ccff9bb62" - integrity sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ== + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -402,10 +473,10 @@ symbol-observable@^1.0.1: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -tas-client-umd@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.6.tgz#a0cf70a68f50d406773457630666224f0eb545a6" - integrity sha512-eOz5IK4cuNmSZI9QlqlT0FdvgfnnHDB6rjqleFaYAbzYE4RdJzYNiM28zFIXgmOVEgESvfabMFxG8WX5M4z3HA== +tas-client-umd@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.4.tgz#49db4130dd63a8342fabf77185a740fc6a7bea80" + integrity sha512-1hFqJeLD3ryNikniIaO7TItlXhS5vx7bJ+wbPDf8o+IifgwwOWK2ARisdEM9SnJd0ccfcwNPG6Po+RiKn5L2hg== turndown-plugin-gfm@^1.0.2: version "1.0.2" @@ -439,22 +510,22 @@ xtend@^4.0.0: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -xterm-addon-search@0.10.0-beta.3: - version "0.10.0-beta.3" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a" - integrity sha512-UeGm/ymnp7HUYJJtsP0D+bljOWbdk3MctcLJ+0jv8AmU6YlAzJFtouvYSQrD5SAMyht5CRsvjzFgqic9X02JYg== +xterm-addon-search@0.9.0-beta.25: + version "0.9.0-beta.25" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.25.tgz#c0923197f64793821ae8b4dfd30e19b411c8e7a7" + integrity sha512-Z6Gd6JN1jcUyQ1iB9yBtPBzNsnPv6DXAxNnJXqFvIznfx0FmXx85FL5SunsH0/uoXre5UwqI+SWc/ON3CkKeUQ== xterm-addon-unicode11@0.4.0-beta.3: version "0.4.0-beta.3" resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa" integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q== -xterm-addon-webgl@0.13.0-beta.9: - version "0.13.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb" - integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g== +xterm-addon-webgl@0.12.0-beta.29: + version "0.12.0-beta.29" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0-beta.29.tgz#7a508595c4521d14d7ed4315a121f9e3f230a0f0" + integrity sha512-NcZBsD0ar3ZpQX070hDIsyEBl/StRMNu6U+9crNpiD2rQVfkM1vcWkOv31Zlj3eu6/f8z5aStyZLRMCGFwiRbA== -xterm@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed" - integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ== +xterm@4.19.0-beta.25: + version "4.19.0-beta.25" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0-beta.25.tgz#38f92d0fef1cfdb290ef8994449a04fa1a8c90a7" + integrity sha512-pDiMWKN1Cj4+X/K9Xegp0SA0ZDEGVqiq7RPSy8oZO2wo2rze1BF20PAZb3/RSp30eY5WyOKilKnck4yNOsPzHw== diff --git a/remote/yarn.lock b/remote/yarn.lock index ab7aed8c7a..314ec16f45 100644 --- a/remote/yarn.lock +++ b/remote/yarn.lock @@ -42,41 +42,112 @@ resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.1.3.tgz#ddafd46ae7ccc8b1f74904ffb45f394e44625216" integrity sha512-i+1GMIvfM3OC6XX2kZf+tL36Nc4jhcMNOY6bOrmwlN8APl59I9KqdvywC5HnutkDctb8expiWTIuSKZQAc4AIA== -"@microsoft/1ds-core-js@3.2.9", "@microsoft/1ds-core-js@^3.2.2": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.9.tgz#8a26935966e4871d1f1e40d992828bdd52bba84e" - integrity sha512-3pCfM2TzHn3gU9pxHztduKcVRdb/nzruvPFfHPZD0IM0mb0h6TGo2isELF3CTMahTx50RAC51ojNIw2/7VRkOg== +"@microsoft/1ds-core-js@3.2.6", "@microsoft/1ds-core-js@^3.2.2": + version "3.2.6" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.6.tgz#8a77909f89f991aa2f0b4ae8825c75042962e68e" + integrity sha512-6OpppYCEA+rXjcs2w0KnWji3Y6ZDx0wykY7ZL3QF68NS323C45GHSpkDpVRT/lDU6Xbau/PvQm2zTYAzLcperA== dependencies: - "@microsoft/applicationinsights-core-js" "2.8.10" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-core-js" "2.8.6" + "@microsoft/applicationinsights-shims" "^2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" "@microsoft/1ds-post-js@^3.2.2": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.9.tgz#07030f7455cb4ac8993e9b0bfa6c78ebfe25b499" - integrity sha512-D/RtqkQ2Nr4cuoGqmhi5QTmi3cBlxehIThJ1u3BaH9H/YkLNTKEcHZRWTXy14bXheCefNHciLuadg37G2Kekcg== + version "3.2.6" + resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.6.tgz#cdfa74acfc3205c0a5b79925284d6d166aa43901" + integrity sha512-Zdyl3FU6kU/a7TlVVSTBZg+hSECTT65iI99FsjMOx88HudyVyk9M/0lVbA+FVXvGaxzmtBW6Lw0qRHYp4tBMSA== dependencies: - "@microsoft/1ds-core-js" "3.2.9" - "@microsoft/applicationinsights-shims" "^2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/1ds-core-js" "3.2.6" + "@microsoft/applicationinsights-shims" "^2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" -"@microsoft/applicationinsights-core-js@2.8.10": - version "2.8.10" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.10.tgz#beb96a97a046ddb031d6adecf0d3143b635edf42" - integrity sha512-jQrufDW0+sV8fBhRvzIPNGiCC6dELH+Ug0DM5CfN9757TBqZJz8CSWyDjex39as8+jD0F/8HRU9QdmrVgq5vFg== +"@microsoft/applicationinsights-analytics-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-2.8.7.tgz#dea44f5bbfb150e12f256b0c45ba6756276df9b6" + integrity sha512-WEsbh3yOzjo1DnH6NyVS/W9uXEWJkb0mgOHTnq3An2nvyT7HPzd56hqRfyJsWR2KAU6hvZ09l7OK85AjkfEqJA== dependencies: - "@microsoft/applicationinsights-shims" "2.0.2" - "@microsoft/dynamicproto-js" "^1.1.7" + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" -"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085" - integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg== +"@microsoft/applicationinsights-channel-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.7.tgz#365b29842229ba615badc5f9c3f3ebc5c6ce7ef1" + integrity sha512-Ee2zp6Ij/Btnc9P8bVBXUIa4/X8HH1hNYpL2ALGfhwbWOUxoR+1+0FZpj+/H9vf2PP/8eS5r28MCoksbGUH+8A== + dependencies: + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" -"@microsoft/dynamicproto-js@^1.1.7": - version "1.1.7" - resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.7.tgz#ede48dd3f85af14ee369c805e5ed5b84222b9fe2" - integrity sha512-SK3D3aVt+5vOOccKPnGaJWB5gQ8FuKfjboUJHedMP7gu54HqSCXX5iFXhktGD8nfJb0Go30eDvs/UDoTnR2kOA== +"@microsoft/applicationinsights-common@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.7.tgz#8ac4d63450e8108ac1ce96750d32e286935388f7" + integrity sha512-bODgacISioOVZIYho1QUADVZh4jjFRQhfVokHbFUgDsJ1NgfpDdNlv+idxH9oriBEuf9odWnOM9jfr3OMcVicA== + dependencies: + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-core-js@2.8.6": + version "2.8.6" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.6.tgz#4f0f9ad809aacfc96cb882139b69b3625519c51a" + integrity sha512-rL+ceda1Y6HaHBe1vIbNT/f5JGuHiD5Ydq+DoAfu56o13wyJu4sao3QKaabgaIM59pPO+3BMeGsK8NNUGYaT3w== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-core-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.7.tgz#3c43517bc6fdf2da59aa90708cefcf936db75488" + integrity sha512-y7USumU+a/kbDeORr/dnDFAxcS5+KOFJSM5oUkS8tBu7CYcX1QAGF4X11gdH2NjrGgHjgxhERhYRa/YhwY1NOQ== + dependencies: + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-dependencies-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-2.8.7.tgz#fe7e52ec0a3f18d66cb6c43af529c05858e0cbde" + integrity sha512-lLRZPCi4Aq+sJThiO6QeFfZguuvZkH8VbceMz3jNF8S1KvPC0174eVcihMPDrjErPXGcquH1fKvJn3PionhZuw== + dependencies: + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-properties-js@2.8.7": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-2.8.7.tgz#6ec96789c3add4e93a1511bfcd946859622355f3" + integrity sha512-wEa2XJ3PAymFLcOajl7KwhLS2JGFW3SbF2lYsGeP/efIJewTRbB1l+6QgbNWiOCvPd4cpiq2jRdrgKaQpJN37Q== + dependencies: + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd" + integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ== + +"@microsoft/applicationinsights-web@^2.8.4": + version "2.8.7" + resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web/-/applicationinsights-web-2.8.7.tgz#23f5891768b6da6e4cdcc1a8d0cdf1b7b1376b1e" + integrity sha512-m0GufymksDAOarHnUzQ72d0RIAS2faY9xNnwAb7J08qOuDRqgnKamDH5U6af6Tjla4N1Ql2nOGLqQYg88/QjrQ== + dependencies: + "@microsoft/applicationinsights-analytics-js" "2.8.7" + "@microsoft/applicationinsights-channel-js" "2.8.7" + "@microsoft/applicationinsights-common" "2.8.7" + "@microsoft/applicationinsights-core-js" "2.8.7" + "@microsoft/applicationinsights-dependencies-js" "2.8.7" + "@microsoft/applicationinsights-properties-js" "2.8.7" + "@microsoft/applicationinsights-shims" "2.0.1" + "@microsoft/dynamicproto-js" "^1.1.6" + +"@microsoft/dynamicproto-js@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc" + integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg== "@parcel/watcher@2.0.5": version "2.0.5" @@ -433,9 +504,9 @@ has-flag@^3.0.0: integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== html-to-image@^1.6.2: - version "1.11.11" - resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-1.11.11.tgz#c0f8a34dc9e4b97b93ff7ea286eb8562642ebbea" - integrity sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-1.9.0.tgz#cb49bf9f4b37376771c85cfdd65863ae9420b268" + integrity sha512-9gaDCIYg62Ek07F2pBk76AHgYZ2gxq2YALU7rK3gNCqXuhu6cWzsOQqM7qGbjZiOzxGzrU1deDqZpAod2NEwbA== htmlparser2@^3.9.0: version "3.10.1" @@ -490,10 +561,10 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== +ip@^1.1.5: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" + integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== jquery@3.5.0: version "3.5.0" @@ -556,9 +627,9 @@ mimic-response@^3.1.0: integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" @@ -582,10 +653,10 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -nan@^2.13.2, nan@^2.14.0, nan@^2.17.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== +nan@^2.13.2, nan@^2.14.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== napi-build-utils@^1.0.1: version "1.0.2" @@ -605,9 +676,9 @@ ng2-charts@^1.6.0: chart.js "^2.6.0" node-abi@^3.3.0: - version "3.33.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f" - integrity sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog== + version "3.22.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.22.0.tgz#00b8250e86a0816576258227edbce7bbe0039362" + integrity sha512-u4uAs/4Zzmp/jjsD9cyFYDXeISfUWaAVWshPmDZOFOv4Xl4SbzTXm53I04C2uRueYJ+0t5PEtLH/owbn2Npf/w== dependencies: semver "^7.3.5" @@ -622,9 +693,9 @@ node-addon-api@^4.3.0: integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + version "4.5.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" + integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== node-pty@0.11.0-beta11: version "0.11.0-beta11" @@ -706,9 +777,9 @@ rc@^1.2.7: strip-json-comments "~2.0.1" readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.1.tgz#f9f9b5f536920253b3d26e7660e7da4ccff9bb62" - integrity sha512-+rQmrWMYGA90yenhTYsLWAsLsqVC8osOw6PKE1HDYiO0gdPeKe/xDHNzIAIn4C91YQ6oenEhfYqqc1883qHbjQ== + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: inherits "^2.0.3" string_decoder "^1.1.1" @@ -758,9 +829,9 @@ semver@^5.3.0, semver@^5.4.1: integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== semver@^7.3.5: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" @@ -802,11 +873,11 @@ socks-proxy-agent@^5.0.0: socks "^2.3.3" socks@^2.3.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + version "2.6.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" + integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== dependencies: - ip "^2.0.0" + ip "^1.1.5" smart-buffer "^4.2.0" source-map@^0.6.1: @@ -815,13 +886,13 @@ source-map@^0.6.1: integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== spdlog@^0.13.0: - version "0.13.7" - resolved "https://registry.yarnpkg.com/spdlog/-/spdlog-0.13.7.tgz#719a972be103e473770202e37dca1c9d80502180" - integrity sha512-DiWxvyHuDJKfNuanSnizY2pmqZGaSHej3xpOD4LQ+kkT3oLWpCXI6VRFDnziyXBQKCl8kmyaYnOu9QBhf1WEXQ== + version "0.13.6" + resolved "https://registry.yarnpkg.com/spdlog/-/spdlog-0.13.6.tgz#26b2e13d46cbf8f2334c12ba2a8cc82de5a28f02" + integrity sha512-iGqDoA88G3Rv3lkbVQglTulp3nv12FzND6LDC7cOZ+OoFvWnXVb3+Ebhed60oZ6+IWWGwDtjXK6ympwr7C1XmQ== dependencies: bindings "^1.5.0" mkdirp "^0.5.5" - nan "^2.17.0" + nan "^2.14.0" srcset@^1.0.0: version "1.0.0" @@ -834,7 +905,7 @@ srcset@^1.0.0: stack-chain@^1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" - integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU= + integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug== string_decoder@^1.1.1: version "1.3.0" @@ -881,15 +952,15 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -tas-client-umd@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.6.tgz#a0cf70a68f50d406773457630666224f0eb545a6" - integrity sha512-eOz5IK4cuNmSZI9QlqlT0FdvgfnnHDB6rjqleFaYAbzYE4RdJzYNiM28zFIXgmOVEgESvfabMFxG8WX5M4z3HA== +tas-client-umd@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/tas-client-umd/-/tas-client-umd-0.1.4.tgz#49db4130dd63a8342fabf77185a740fc6a7bea80" + integrity sha512-1hFqJeLD3ryNikniIaO7TItlXhS5vx7bJ+wbPDf8o+IifgwwOWK2ARisdEM9SnJd0ccfcwNPG6Po+RiKn5L2hg== tslib@^2.3.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tunnel-agent@^0.6.0: version "0.6.0" @@ -968,35 +1039,35 @@ xtend@^4.0.0: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -xterm-addon-search@0.10.0-beta.3: - version "0.10.0-beta.3" - resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.10.0-beta.3.tgz#5194434d86105637c71f6f20139a9d0b5c1a956a" - integrity sha512-UeGm/ymnp7HUYJJtsP0D+bljOWbdk3MctcLJ+0jv8AmU6YlAzJFtouvYSQrD5SAMyht5CRsvjzFgqic9X02JYg== +xterm-addon-search@0.9.0-beta.25: + version "0.9.0-beta.25" + resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.9.0-beta.25.tgz#c0923197f64793821ae8b4dfd30e19b411c8e7a7" + integrity sha512-Z6Gd6JN1jcUyQ1iB9yBtPBzNsnPv6DXAxNnJXqFvIznfx0FmXx85FL5SunsH0/uoXre5UwqI+SWc/ON3CkKeUQ== -xterm-addon-serialize@0.8.0-beta.3: - version "0.8.0-beta.3" - resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.8.0-beta.3.tgz#47ade3fedacbb75bd26e63cfe0120586623e0e4f" - integrity sha512-gvfempZCYuAhLqN4O6fA2TuoavPjOxFKlh8hLcOzPackiLUhwKr1jQpDXcnq8VgqUiGgb+XNZpPEbI0Q7EhTgA== +xterm-addon-serialize@0.7.0-beta.12: + version "0.7.0-beta.12" + resolved "https://registry.yarnpkg.com/xterm-addon-serialize/-/xterm-addon-serialize-0.7.0-beta.12.tgz#4f845d8b1a9f9b7ae3f910455ce8c58b041babc7" + integrity sha512-b4Ug0B/RSJMux+KAcp+PXVqubVyXjN1yCQw1FOkgVYTpmd9AH/X+EcxKml5Lz8DsKmsXqfD9AlV3WpEeT+OtMw== xterm-addon-unicode11@0.4.0-beta.3: version "0.4.0-beta.3" resolved "https://registry.yarnpkg.com/xterm-addon-unicode11/-/xterm-addon-unicode11-0.4.0-beta.3.tgz#f350184155fafd5ad0d6fbf31d13e6ca7dea1efa" integrity sha512-FryZAVwbUjKTmwXnm1trch/2XO60F5JsDvOkZhzobV1hm10sFLVuZpFyHXiUx7TFeeFsvNP+S77LAtWoeT5z+Q== -xterm-addon-webgl@0.13.0-beta.9: - version "0.13.0-beta.9" - resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.13.0-beta.9.tgz#66a9ac142ae347d0548abbf4e66bb2f35f415adb" - integrity sha512-x1o1tpCqIsICvhcRsZs+BLcwUIdizYS2G4TIH0KBnUDiSN+oSqpVBQNG8qKg56xbK8WtpdbQ9dLB7JR2W5cX0g== +xterm-addon-webgl@0.12.0-beta.29: + version "0.12.0-beta.29" + resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.12.0-beta.29.tgz#7a508595c4521d14d7ed4315a121f9e3f230a0f0" + integrity sha512-NcZBsD0ar3ZpQX070hDIsyEBl/StRMNu6U+9crNpiD2rQVfkM1vcWkOv31Zlj3eu6/f8z5aStyZLRMCGFwiRbA== xterm-headless@4.19.0-beta.25: version "4.19.0-beta.25" resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-4.19.0-beta.25.tgz#a0a1b59f386c44458f06b8ced64e3567371cc983" integrity sha512-UswSgymk3g9i6XTpFAasnqqIvWhi+AEWT+iO3kkjII6ll+dYEQgeZAv92EnCmeRHp11u5TP+IBAo8jy+aTYbtA== -xterm@4.20.0-beta.20: - version "4.20.0-beta.20" - resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.20.0-beta.20.tgz#2979a31839f7b8ee3ffe4f063b40c02facdb0fed" - integrity sha512-ltDtTquH+33tXQPFSDqenbgz6LkvIob6l6Rac85L4aX5Ve7P3ubVLrq+lTFJGQn3iiwGqNmnE1t1EUuGhxsXcQ== +xterm@4.19.0-beta.25: + version "4.19.0-beta.25" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.19.0-beta.25.tgz#38f92d0fef1cfdb290ef8994449a04fa1a8c90a7" + integrity sha512-pDiMWKN1Cj4+X/K9Xegp0SA0ZDEGVqiq7RPSy8oZO2wo2rze1BF20PAZb3/RSp30eY5WyOKilKnck4yNOsPzHw== yallist@^4.0.0: version "4.0.0" @@ -1019,8 +1090,8 @@ yazl@^2.4.3: buffer-crc32 "~0.2.3" zone.js@^0.11.4: - version "0.11.8" - resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.8.tgz#40dea9adc1ad007b5effb2bfed17f350f1f46a21" - integrity sha512-82bctBg2hKcEJ21humWIkXRlLBBmrc3nN7DFh5LGGhcyycO2S7FN8NmdvlcKaGFDNVL4/9kFLmwmInTavdJERA== + version "0.11.6" + resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.6.tgz#c7cacfc298fe24bb585329ca04a44d9e2e840e74" + integrity sha512-umJqFtKyZlPli669gB1gOrRE9hxUUGkZr7mo878z+NEBJZZixJkKeVYfnoLa7g25SseUDc92OZrMKKHySyJrFg== dependencies: tslib "^2.3.0" diff --git a/resources/darwin/bin/code.sh b/resources/darwin/bin/code.sh index 7fc9d3917a..e439786a19 100755 --- a/resources/darwin/bin/code.sh +++ b/resources/darwin/bin/code.sh @@ -3,15 +3,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the Source EULA. See License.txt in the project root for license information. -# when run in remote terminal, use the remote cli -if [ -n "$VSCODE_IPC_HOOK_CLI" ]; then - REMOTE_CLI="$(which -a '@@APPNAME@@' | grep /remote-cli/)" - if [ -n "$REMOTE_CLI" ]; then - "$REMOTE_CLI" "$@" - exit $? - fi -fi - function app_realpath() { SOURCE=$1 while [ -h "$SOURCE" ]; do diff --git a/resources/linux/bin/code.sh b/resources/linux/bin/code.sh index 5ac0698cca..a9641ca948 100755 --- a/resources/linux/bin/code.sh +++ b/resources/linux/bin/code.sh @@ -3,18 +3,9 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the Source EULA. See License.txt in the project root for license information. -# when run in remote terminal, use the remote cli -if [ -n "$VSCODE_IPC_HOOK_CLI" ]; then - REMOTE_CLI="$(which -a '@@APPNAME@@' | grep /remote-cli/)" - if [ -n "$REMOTE_CLI" ]; then - "$REMOTE_CLI" "$@" - exit $? - fi -fi - # test that VSCode wasn't installed inside WSL if grep -qi Microsoft /proc/version && [ -z "$DONT_PROMPT_WSL_INSTALL" ]; then - echo "To use @@PRODNAME@@ with the Windows Subsystem for Linux, please install @@PRODNAME@@ in Windows and uninstall the Linux version in WSL. You can then use the \`@@APPNAME@@\` command in a WSL terminal just as you would in a normal command prompt." 1>&2 + echo "To use @@PRODNAME@@ with the Windows Subsystem for Linux, please install @@PRODNAME@@ in Windows and uninstall the Linux version in WSL. You can then use the \`@@NAME@@\` command in a WSL terminal just as you would in a normal command prompt." 1>&2 printf "Do you want to continue anyway? [y/N] " 1>&2 read -r YN YN=$(printf '%s' "$YN" | tr '[:upper:]' '[:lower:]') @@ -53,11 +44,11 @@ else VSCODE_PATH="$(dirname "$(readlink -f "$0")")/.." else # else use the standard install location - VSCODE_PATH="/usr/share/@@APPNAME@@" + VSCODE_PATH="/usr/share/@@NAME@@" fi fi -ELECTRON="$VSCODE_PATH/@@APPNAME@@" +ELECTRON="$VSCODE_PATH/@@NAME@@" CLI="$VSCODE_PATH/resources/app/out/cli.js" ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node "$@" exit $? diff --git a/resources/linux/debian/control.template b/resources/linux/debian/control.template index 96d269162a..642b5fe439 100644 --- a/resources/linux/debian/control.template +++ b/resources/linux/debian/control.template @@ -1,8 +1,7 @@ Package: @@NAME@@ Version: @@VERSION@@ Section: devel -Depends: @@DEPENDS@@ -Recommends: @@RECOMMENDS@@ +Depends: libnss3 (>= 2:3.26), gnupg, apt, libxkbfile1, libsecret-1-0, libgtk-3-0 (>= 3.10.0), libxss1, libgbm1 Priority: optional Architecture: @@ARCHITECTURE@@ Maintainer: Microsoft Corporation diff --git a/resources/linux/rpm/code.spec.template b/resources/linux/rpm/code.spec.template index 00ddb6fdf0..5b7eadb8c9 100644 --- a/resources/linux/rpm/code.spec.template +++ b/resources/linux/rpm/code.spec.template @@ -11,8 +11,6 @@ Icon: @@NAME@@.xpm Requires: @@DEPENDENCIES@@ AutoReq: 0 -%global __provides_exclude_from ^%{_datadir}/@@NAME@@/.*\\.so.*$ - %description Visual Studio Code is a new choice of tool that combines the simplicity of a code editor with what developers need for the core edit-build-debug cycle. See https://code.visualstudio.com/docs/setup/linux for installation instructions and FAQ. @@ -21,7 +19,6 @@ Visual Studio Code is a new choice of tool that combines the simplicity of a cod %define _build_id_links none %install -mkdir -p %{buildroot}/usr/bin mkdir -p %{buildroot}/usr/share/@@NAME@@ mkdir -p %{buildroot}/usr/share/applications mkdir -p %{buildroot}/usr/share/pixmaps @@ -35,7 +32,6 @@ cp -r usr/share/mime/packages/@@NAME@@-workspace.xml %{buildroot}/usr/share/mime cp -r usr/share/pixmaps/@@ICON@@.png %{buildroot}/usr/share/pixmaps cp usr/share/bash-completion/completions/@@NAME@@ %{buildroot}/usr/share/bash-completion/completions/@@NAME@@ cp usr/share/zsh/site-functions/_@@NAME@@ %{buildroot}/usr/share/zsh/site-functions/_@@NAME@@ -ln -s ../share/@@NAME@@/bin/@@NAME@@ %{buildroot}/usr/bin/@@NAME@@ %post # Remove the legacy bin command if this is the stable build @@ -43,6 +39,9 @@ if [ "@@NAME@@" = "code" ]; then rm -f /usr/local/bin/code fi +# Symlink bin command to /usr/bin +ln -sf /usr/share/@@NAME@@/bin/@@NAME@@ %{_bindir}/@@NAME@@ + # Register yum repository # TODO: #229: Enable once the yum repository is signed #if [ "@@NAME@@" != "code-oss" ]; then @@ -57,6 +56,10 @@ fi update-mime-database /usr/share/mime &> /dev/null || : %postun +if [ $1 = 0 ]; then + rm -f /usr/bin/@@NAME@@ +fi + # Update mimetype database for removed workspace mimetype update-mime-database /usr/share/mime &> /dev/null || : @@ -64,7 +67,6 @@ update-mime-database /usr/share/mime &> /dev/null || : %defattr(-,root,root) %attr(4755, root, root) /usr/share/@@NAME@@/chrome-sandbox -/usr/bin/@@NAME@@ /usr/share/@@NAME@@/ /usr/share/applications/@@NAME@@.desktop /usr/share/applications/@@NAME@@-url-handler.desktop diff --git a/resources/linux/snap/snapcraft.yaml b/resources/linux/snap/snapcraft.yaml index fc775b6554..8bbad497ac 100644 --- a/resources/linux/snap/snapcraft.yaml +++ b/resources/linux/snap/snapcraft.yaml @@ -58,9 +58,11 @@ apps: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --no-sandbox common-id: @@NAME@@.desktop environment: + DISABLE_WAYLAND: 1 GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas url-handler: command: electron-launch $SNAP/usr/share/@@NAME@@/bin/@@NAME@@ --open-url --no-sandbox environment: + DISABLE_WAYLAND: 1 GSETTINGS_SCHEMA_DIR: $SNAP/usr/share/glib-2.0/schemas diff --git a/resources/win32/policies/Code.admx b/resources/win32/policies/Code.admx new file mode 100644 index 0000000000..916f503b78 --- /dev/null +++ b/resources/win32/policies/Code.admx @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + none + + + + + manual + + + + + start + + + + + default + + + + + + + diff --git a/resources/win32/policies/en-US/Code.adml b/resources/win32/policies/en-US/Code.adml new file mode 100644 index 0000000000..f79b1778ec --- /dev/null +++ b/resources/win32/policies/en-US/Code.adml @@ -0,0 +1,23 @@ + + + + + + + Code - OSS 1.67 or later + Code - OSS + Update + Update Mode + Configure whether you receive automatic updates. Requires a restart after change. The updates are fetched from a Microsoft online service. + Disable updates. + Disable automatic background update checks. Updates will be available if you manually check for updates. + Check for updates only on startup. Disable automatic background update checks. + Enable automatic update checks. Code will check for updates automatically and periodically. + + + + + + + + diff --git a/scripts/test-remote-integration.bat b/scripts/test-remote-integration.bat index a7d0719205..1c04b2e392 100644 --- a/scripts/test-remote-integration.bat +++ b/scripts/test-remote-integration.bat @@ -53,10 +53,10 @@ if "%INTEGRATION_TEST_ELECTRON_PATH%"=="" ( :: Run from a built: need to compile all test extensions :: because we run extension tests from their source folders :: and the build bundles extensions into .build webpacked - :: call yarn gulp compile-extension:vscode-api-tests^ - :: compile-extension:microsoft-authentication^ - :: compile-extension:github-authentication^ - :: compile-extension:vscode-test-resolver + call yarn gulp compile-extension:vscode-api-tests^ + compile-extension:microsoft-authentication^ + compile-extension:github-authentication^ + compile-extension:vscode-test-resolver :: Configuration for more verbose output set VSCODE_CLI=1 diff --git a/scripts/test-remote-integration.sh b/scripts/test-remote-integration.sh index 6d883f5321..e2212317d3 100755 --- a/scripts/test-remote-integration.sh +++ b/scripts/test-remote-integration.sh @@ -47,17 +47,16 @@ else # Run from a built: need to compile all test extensions # because we run extension tests from their source folders # and the build bundles extensions into .build webpacked - # yarn gulp compile-extension:vscode-api-tests \ - # compile-extension:vscode-test-resolver \ - # compile-extension:markdown-language-features \ - # compile-extension:typescript-language-features \ - # compile-extension:emmet \ - # compile-extension:git \ - # compile-extension:ipynb \ - # compile-extension:configuration-editing \ - # compile-extension:microsoft-authentication \ - # compile-extension:github-authentication \ - # compile-extension-media + yarn gulp compile-extension:vscode-api-tests \ + compile-extension:vscode-test-resolver \ + compile-extension:markdown-language-features \ + compile-extension:typescript-language-features \ + compile-extension:emmet \ + compile-extension:git \ + compile-extension:ipynb \ + compile-extension:microsoft-authentication \ + compile-extension:github-authentication \ + compile-extension-media # Configuration for more verbose output export VSCODE_CLI=1 @@ -133,11 +132,6 @@ echo "$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS --folder-uri=$AUTHORITY$(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$REMOTE_VSCODE/ipynb --extensionTestsPath=$REMOTE_VSCODE/ipynb/out/test $API_TESTS_EXTRA_ARGS $EXTRA_INTEGRATION_TEST_ARGUMENTS kill_app -echo -echo "### Configuration editing tests" -echo -"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS --folder-uri=$AUTHORITY$(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$REMOTE_VSCODE/configuration-editing --extensionTestsPath=$REMOTE_VSCODE/configuration-editing/out/test $API_TESTS_EXTRA_ARGS $EXTRA_INTEGRATION_TEST_ARGUMENTS -kill_app # Cleanup diff --git a/scripts/test-web-integration.bat b/scripts/test-web-integration.bat index 7be27c00b3..99bb16b7d5 100644 --- a/scripts/test-web-integration.bat +++ b/scripts/test-web-integration.bat @@ -25,13 +25,12 @@ if "%VSCODE_REMOTE_SERVER_PATH%"=="" ( :: Run from a built: need to compile all test extensions :: because we run extension tests from their source folders :: and the build bundles extensions into .build webpacked - :: call yarn gulp compile-extension:vscode-api-tests^ - :: compile-extension:markdown-language-features^ - :: compile-extension:typescript-language-features^ - :: compile-extension:emmet^ - :: compile-extension:configuration-editing^ - :: compile-extension:git^ - :: compile-extension-media + call yarn gulp compile-extension:vscode-api-tests^ + compile-extension:markdown-language-features^ + compile-extension:typescript-language-features^ + compile-extension:emmet^ + compile-extension:git^ + compile-extension-media ) if not exist ".\test\integration\browser\out\index.js" ( @@ -71,10 +70,3 @@ set GITWORKSPACE=%TEMPDIR%\git-%RANDOM% mkdir %GITWORKSPACE% call node .\test\integration\browser\out\index.js --workspacePath=%GITWORKSPACE% --extensionDevelopmentPath=.\extensions\git --extensionTestsPath=.\extensions\git\out\test %* if %errorlevel% neq 0 exit /b %errorlevel% - -echo. -echo ### Configuration editing tests -set CFWORKSPACE=%TEMPDIR%\git-%RANDOM% -mkdir %CFWORKSPACE% -call node .\test\integration\browser\out\index.js --workspacePath=%CFWORKSPACE% --extensionDevelopmentPath=.\extensions\configuration-editing --extensionTestsPath=.\extensions\configuration-editing\out\test %* -if %errorlevel% neq 0 exit /b %errorlevel% diff --git a/scripts/test-web-integration.sh b/scripts/test-web-integration.sh index 95278eec0e..8f05929fdc 100755 --- a/scripts/test-web-integration.sh +++ b/scripts/test-web-integration.sh @@ -19,14 +19,13 @@ else # Run from a built: need to compile all test extensions # because we run extension tests from their source folders # and the build bundles extensions into .build webpacked - # yarn gulp compile-extension:vscode-api-tests \ - # compile-extension:markdown-language-features \ - # compile-extension:typescript-language-features \ - # compile-extension:emmet \ - # compile-extension:git \ - # compile-extension:ipynb \ - # compile-extension:configuration-editing \ - # compile-extension-media + yarn gulp compile-extension:vscode-api-tests \ + compile-extension:markdown-language-features \ + compile-extension:typescript-language-features \ + compile-extension:emmet \ + compile-extension:git \ + compile-extension:ipynb \ + compile-extension-media fi if [ ! -e 'test/integration/browser/out/index.js' ];then @@ -71,8 +70,3 @@ echo "### Ipynb tests" echo node test/integration/browser/out/index.js --workspacePath $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/ipynb --extensionTestsPath=$ROOT/extensions/ipynb/out/test "$@" -echo -echo "### Configuration editing tests" -echo -node test/integration/browser/out/index.js --workspacePath $(mktemp -d 2>/dev/null) --extensionDevelopmentPath=$ROOT/extensions/configuration-editing --extensionTestsPath=$ROOT/extensions/configuration-editing/out/test "$@" - diff --git a/src/bootstrap-fork.js b/src/bootstrap-fork.js index 2844cde913..6d083053df 100644 --- a/src/bootstrap-fork.js +++ b/src/bootstrap-fork.js @@ -88,6 +88,15 @@ function pipeLoggingToParent() { } } + // Add the stack trace as payload if we are told so. We remove the message and the 2 top frames + // to start the stacktrace where the console message was being written + if (process.env['VSCODE_LOG_STACK'] === 'true') { + const stack = new Error().stack; + if (stack) { + argsArray.push({ __$stack: stack.split('\n').slice(3).join('\n') }); + } + } + try { const res = JSON.stringify(argsArray, function (key, value) { @@ -146,8 +155,13 @@ function pipeLoggingToParent() { safeSend({ type: '__$console', severity, arguments: args }); } + let isMakingConsoleCall = false; + /** - * Wraps a console message so that it is transmitted to the renderer. + * Wraps a console message so that it is transmitted to the renderer. If + * native logging is turned on, the original console message will be written + * as well. This is needed since the console methods are "magic" in V8 and + * are the only methods that allow later introspection of logged variables. * * The wrapped property is not defined with `writable: false` to avoid * throwing errors, but rather a no-op setting. See https://github.com/microsoft/vscode-extension-telemetry/issues/88 @@ -156,10 +170,26 @@ function pipeLoggingToParent() { * @param {'log' | 'warn' | 'error'} severity */ function wrapConsoleMethod(method, severity) { - Object.defineProperty(console, method, { - set: () => { }, - get: () => function () { safeSendConsoleMessage(severity, safeToArray(arguments)); }, - }); + if (process.env['VSCODE_LOG_NATIVE'] === 'true') { + const original = console[method]; + const stream = method === 'error' || method === 'warn' ? process.stderr : process.stdout; + Object.defineProperty(console, method, { + set: () => { }, + get: () => function () { + safeSendConsoleMessage(severity, safeToArray(arguments)); + isMakingConsoleCall = true; + stream.write('\nSTART_NATIVE_LOG\n'); + original.apply(console, arguments); + stream.write('\nEND_NATIVE_LOG\n'); + isMakingConsoleCall = false; + }, + }); + } else { + Object.defineProperty(console, method, { + set: () => { }, + get: () => function () { safeSendConsoleMessage(severity, safeToArray(arguments)); }, + }); + } } /** @@ -181,11 +211,13 @@ function pipeLoggingToParent() { Object.defineProperty(stream, 'write', { set: () => { }, get: () => (chunk, encoding, callback) => { - buf += chunk.toString(encoding); - const eol = buf.length > MAX_STREAM_BUFFER_LENGTH ? buf.length : buf.lastIndexOf('\n'); - if (eol !== -1) { - console[severity](buf.slice(0, eol)); - buf = buf.slice(eol + 1); + if (!isMakingConsoleCall) { + buf += chunk.toString(encoding); + const eol = buf.length > MAX_STREAM_BUFFER_LENGTH ? buf.length : buf.lastIndexOf('\n'); + if (eol !== -1) { + console[severity](buf.slice(0, eol)); + buf = buf.slice(eol + 1); + } } original.call(stream, chunk, encoding, callback); @@ -199,7 +231,7 @@ function pipeLoggingToParent() { wrapConsoleMethod('log', 'log'); wrapConsoleMethod('warn', 'warn'); wrapConsoleMethod('error', 'error'); - } else { + } else if (process.env['VSCODE_LOG_NATIVE'] !== 'true') { console.log = function () { /* ignore */ }; console.warn = function () { /* ignore */ }; console.info = function () { /* ignore */ }; @@ -241,13 +273,17 @@ function listenForMessagePort() { // We need to listen for the 'port' event as soon as possible, // otherwise we might miss the event. But we should also be // prepared in case the event arrives late. - process.on('port', (e) => { - if (global.vscodePortsCallback) { - global.vscodePortsCallback(e.ports); - } else { - global.vscodePorts = e.ports; - } - }); + // @ts-ignore + if (process.parentPort) { + // @ts-ignore + process.parentPort.on('message', (e) => { + if (global.vscodePortsCallback) { + global.vscodePortsCallback(e.ports); + } else { + global.vscodePorts = e.ports; + } + }); + } } //#endregion diff --git a/src/bootstrap.js b/src/bootstrap.js index 31ff7e5b8d..215994c403 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -205,7 +205,7 @@ } /** - * @returns {import('./vs/base/parts/sandbox/electron-sandbox/globals').ISandboxNodeProcess | NodeJS.Process | undefined} + * @returns {import('./vs/base/parts/sandbox/electron-sandbox/globals').ISandboxNodeProcess | NodeJS.Process} */ function safeProcess() { const sandboxGlobals = safeSandboxGlobals(); diff --git a/src/buildfile.js b/src/buildfile.js index e444470d78..d0ee3c0464 100644 --- a/src/buildfile.js +++ b/src/buildfile.js @@ -32,17 +32,16 @@ exports.base = [ { name: 'vs/editor/common/services/editorSimpleWorker', include: ['vs/base/common/worker/simpleWorker'], - exclude: ['vs/nls'], - prepend: [ - { path: 'vs/loader.js' }, - { path: 'vs/nls.js', amdModuleId: 'vs/nls' }, - { path: 'vs/base/worker/workerMain.js' } - ], + prepend: ['vs/loader.js', 'vs/nls.js'], + append: ['vs/base/worker/workerMain'], dest: 'vs/base/worker/workerMain.js' }, { name: 'vs/base/common/worker/simpleWorker', - exclude: ['vs/nls'], + }, + { + name: 'vs/platform/extensions/node/extensionHostStarterWorker', + exclude: ['vs/base/common/worker/simpleWorker'] } ]; diff --git a/src/main.js b/src/main.js index b5647f8ad4..9877718224 100644 --- a/src/main.js +++ b/src/main.js @@ -160,6 +160,9 @@ function configureCommandlineSwitchesSync(cliArgs) { // alias from us for --disable-gpu 'disable-hardware-acceleration', + // provided by Electron + 'disable-color-correct-rendering', + // override for the color profile to use 'force-color-profile' ]; @@ -251,7 +254,9 @@ function readArgvConfigSync() { // Fallback to default if (!argvConfig) { - argvConfig = {}; + argvConfig = { + 'disable-color-correct-rendering': true // Force pre-Chrome-60 color profile handling (for https://github.com/microsoft/vscode/issues/51791) + }; } return argvConfig; @@ -281,7 +286,11 @@ function createDefaultArgvConfigSync(argvConfigPath) { '{', ' // Use software rendering instead of hardware accelerated rendering.', ' // This can help in cases where you see rendering issues in VS Code.', - ' // "disable-hardware-acceleration": true', + ' // "disable-hardware-acceleration": true,', + '', + ' // Enabled by default by VS Code to resolve color issues in the renderer', + ' // See https://github.com/microsoft/vscode/issues/51791 for details', + ' "disable-color-correct-rendering": true', '}' ]; @@ -320,7 +329,7 @@ function configureCrashReporter() { if (!fs.existsSync(crashReporterDirectory)) { try { - fs.mkdirSync(crashReporterDirectory, { recursive: true }); + fs.mkdirSync(crashReporterDirectory); } catch (error) { console.error(`The path '${crashReporterDirectory}' specified for --crash-reporter-directory does not seem to exist or cannot be created.`); app.exit(1); diff --git a/src/server-main.js b/src/server-main.js index 91abf7114c..6f6f66e7b9 100644 --- a/src/server-main.js +++ b/src/server-main.js @@ -55,7 +55,7 @@ async function start() { * @typedef { import('./vs/server/node/remoteExtensionHostAgentServer').IServerAPI } IServerAPI */ /** @type {IServerAPI | null} */ - const _remoteExtensionHostAgentServer = null; + let _remoteExtensionHostAgentServer = null; /** @type {Promise | null} */ let _remoteExtensionHostAgentServerPromise = null; /** @returns {Promise} */ diff --git a/src/sql/azdata.d.ts b/src/sql/azdata.d.ts index 93cdde60cf..cc5d58384c 100644 --- a/src/sql/azdata.d.ts +++ b/src/sql/azdata.d.ts @@ -4761,7 +4761,6 @@ declare module 'azdata' { * @deprecated please use the method createModelViewDialog(title: string, dialogName?: string, width?: DialogWidth) instead. * Create a dialog with the given title * @param title The title of the dialog, displayed at the top - * @param dialogName Name of the dialog. * @param isWide Indicates whether the dialog is wide or normal */ export function createModelViewDialog(title: string, dialogName?: string, isWide?: boolean): Dialog; @@ -5392,7 +5391,6 @@ declare module 'azdata' { */ export function getQueryDocument(fileUri: string): Thenable; - /* eslint-disable */ /** * Opens an untitled text document. The editor will prompt the user for a file * path when the document is to be saved. The `options` parameter allows to @@ -5403,7 +5401,6 @@ declare module 'azdata' { * @return A promise that resolves to a {@link QueryDocument}. */ export function openQueryDocument(options?: { content?: string; }, providerId?: string): Thenable; - /* eslint-enable */ } /** @@ -5658,7 +5655,6 @@ declare module 'azdata' { */ export const onDidChangeActiveNotebookEditor: vscode.Event; - /* eslint-disable */ /** * Show the given document in a notebook editor. A {@link vscode.ViewColumn} can be provided * to control where the editor is being shown. Might change the {@link nb.activeNotebookEditor}. @@ -5678,7 +5674,6 @@ declare module 'azdata' { * @return A promise that resolves to a {@link NotebookEditor}. */ export function showNotebookDocument(uri: vscode.Uri, showOptions?: NotebookShowOptions): Thenable; - /* eslint-enable */ export interface NotebookDocument { /** diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index 5a2c26b7d1..182e1b0abd 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -679,13 +679,13 @@ declare module 'azdata' { /** * Enters the workspace with the provided path - * @param workspaceFile + * @param workspacefile */ export function enterWorkspace(workspaceFile: vscode.Uri): Promise; /** * Saves and enters the workspace with the provided path - * @param workspaceFile + * @param workspacefile */ export function saveAndEnterWorkspace(workspaceFile: vscode.Uri): Promise; } @@ -848,7 +848,7 @@ declare module 'azdata' { * Open a table designer window. * @param providerId The table designer provider Id. * @param tableInfo The table information. The object will be passed back to the table designer provider as the unique identifier for the table. - * @param telemetryInfo Optional Key-value pair containing any extra information that needs to be sent via telemetry + * @param telemetryInfo: Optional Key-value pair containing any extra information that needs to be sent via telemetry */ export function openTableDesigner(providerId: string, tableInfo: TableInfo, telemetryInfo?: { [key: string]: string }): Thenable; diff --git a/src/sql/base/browser/globalPointerMoveMonitor.ts b/src/sql/base/browser/globalPointerMoveMonitor.ts deleted file mode 100644 index 95e6f3d16a..0000000000 --- a/src/sql/base/browser/globalPointerMoveMonitor.ts +++ /dev/null @@ -1,126 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as dom from 'vs/base/browser/dom'; -import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; - -export interface IPointerMoveEventData { - leftButton: boolean; - buttons: number; - pageX: number; - pageY: number; -} - -export interface IEventMerger { - (lastEvent: R | null, currentEvent: PointerEvent): R; -} - -export interface IPointerMoveCallback { - (pointerMoveData: R): void; -} - -export interface IOnStopCallback { - (browserEvent?: PointerEvent | KeyboardEvent): void; -} - -export function standardPointerMoveMerger(lastEvent: IPointerMoveEventData | null, currentEvent: PointerEvent): IPointerMoveEventData { - currentEvent.preventDefault(); - return { - leftButton: (currentEvent.button === 0), - buttons: currentEvent.buttons, - pageX: currentEvent.pageX, - pageY: currentEvent.pageY - }; -} - -export class GlobalPointerMoveMonitor implements IDisposable { - - private readonly _hooks = new DisposableStore(); - private _pointerMoveEventMerger: IEventMerger | null = null; - private _pointerMoveCallback: IPointerMoveCallback | null = null; - private _onStopCallback: IOnStopCallback | null = null; - - public dispose(): void { - this.stopMonitoring(false); - this._hooks.dispose(); - } - - public stopMonitoring(invokeStopCallback: boolean, browserEvent?: PointerEvent | KeyboardEvent): void { - if (!this.isMonitoring()) { - // Not monitoring - return; - } - - // Unhook - this._hooks.clear(); - this._pointerMoveEventMerger = null; - this._pointerMoveCallback = null; - const onStopCallback = this._onStopCallback; - this._onStopCallback = null; - - if (invokeStopCallback && onStopCallback) { - onStopCallback(browserEvent); - } - } - - public isMonitoring(): boolean { - return !!this._pointerMoveEventMerger; - } - - public startMonitoring( - initialElement: Element, - pointerId: number, - initialButtons: number, - pointerMoveEventMerger: IEventMerger, - pointerMoveCallback: IPointerMoveCallback, - onStopCallback: IOnStopCallback - ): void { - if (this.isMonitoring()) { - this.stopMonitoring(false); - } - this._pointerMoveEventMerger = pointerMoveEventMerger; - this._pointerMoveCallback = pointerMoveCallback; - this._onStopCallback = onStopCallback; - - let eventSource: Element | Window = initialElement; - - try { - initialElement.setPointerCapture(pointerId); - this._hooks.add(toDisposable(() => { - initialElement.releasePointerCapture(pointerId); - })); - } catch (err) { - // See https://github.com/microsoft/vscode/issues/144584 - // See https://github.com/microsoft/vscode/issues/146947 - // `setPointerCapture` sometimes fails when being invoked - // from a `mousedown` listener on macOS and Windows - // and it always fails on Linux with the exception: - // DOMException: Failed to execute 'setPointerCapture' on 'Element': - // No active pointer with the given id is found. - // In case of failure, we bind the listeners on the window - eventSource = window; - } - - this._hooks.add(dom.addDisposableThrottledListener( - eventSource, - dom.EventType.POINTER_MOVE, - (data: R) => { - if (data.buttons !== initialButtons) { - // Buttons state has changed in the meantime - this.stopMonitoring(true); - return; - } - this._pointerMoveCallback!(data); - }, - (lastEvent: R | null, currentEvent) => this._pointerMoveEventMerger!(lastEvent, currentEvent) - )); - - this._hooks.add(dom.addDisposableListener( - eventSource, - dom.EventType.POINTER_UP, - (e: PointerEvent) => this.stopMonitoring(true) - )); - } -} diff --git a/src/sql/base/browser/ui/panel/panel.component.ts b/src/sql/base/browser/ui/panel/panel.component.ts index db0bc65cce..9534820890 100644 --- a/src/sql/base/browser/ui/panel/panel.component.ts +++ b/src/sql/base/browser/ui/panel/panel.component.ts @@ -261,7 +261,6 @@ export class PanelComponent extends Disposable implements IThemable { this.selectTab(nextTabIndex); } - /* eslint-disable */ /** * Updates the specified tab with new config values * @param tabId The id of the tab to update @@ -286,7 +285,6 @@ export class PanelComponent extends Disposable implements IThemable { tabHeader?.refresh(); } } - /* eslint-enable */ private findAndRemoveTabFromMRU(tab: TabComponent): void { let mruIndex = this._mru.findIndex(i => i === tab); diff --git a/src/sql/platform/actions/browser/menuEntryActionViewItem.ts b/src/sql/platform/actions/browser/menuEntryActionViewItem.ts index 2b6bfc71db..67a3c22c95 100644 --- a/src/sql/platform/actions/browser/menuEntryActionViewItem.ts +++ b/src/sql/platform/actions/browser/menuEntryActionViewItem.ts @@ -10,10 +10,9 @@ import { MenuItemAction } from 'vs/platform/actions/common/actions'; import { ICommandAction } from 'vs/platform/action/common/action'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService'; +import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { MenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; const ids = new IdGenerator('menu-item-action-item-icon-'); @@ -33,10 +32,8 @@ export class LabeledMenuItemActionItem extends MenuEntryActionViewItem { @IKeybindingService labeledkeybindingService: IKeybindingService, @INotificationService _notificationService: INotificationService, @IContextKeyService _contextKeyService: IContextKeyService, - @IThemeService _themeService: IThemeService, - @IContextMenuService _contextMenuService: IContextMenuService ) { - super(_action, undefined, labeledkeybindingService, _notificationService, _contextKeyService, _themeService, _contextMenuService); + super(_action, undefined, labeledkeybindingService, _notificationService, _contextKeyService); } override updateLabel(): void { @@ -107,11 +104,9 @@ export class MaskedLabeledMenuItemActionItem extends MenuEntryActionViewItem { action: MenuItemAction, @IKeybindingService keybindingService: IKeybindingService, @INotificationService notificationService: INotificationService, - @IContextKeyService contextKeyService: IContextKeyService, - @IThemeService _themeService: IThemeService, - @IContextMenuService _contextMenuService: IContextMenuService + @IContextKeyService contextKeyService: IContextKeyService ) { - super(action, undefined, keybindingService, notificationService, contextKeyService, _themeService, _contextMenuService); + super(action, undefined, keybindingService, notificationService, contextKeyService); } override updateLabel(): void { diff --git a/src/sql/platform/connection/common/connectionStore.ts b/src/sql/platform/connection/common/connectionStore.ts index 28ff48ed85..09c4ee7cbc 100644 --- a/src/sql/platform/connection/common/connectionStore.ts +++ b/src/sql/platform/connection/common/connectionStore.ts @@ -42,14 +42,14 @@ export class ConnectionStore { @ICapabilitiesService private capabilitiesService: ICapabilitiesService ) { try { - const configRaw = this.storageService.get(RECENT_CONNECTIONS_STATE_KEY, StorageScope.APPLICATION, '[]'); + const configRaw = this.storageService.get(RECENT_CONNECTIONS_STATE_KEY, StorageScope.GLOBAL, '[]'); this.mru = JSON.parse(configRaw); } catch (e) { this.mru = []; } this.storageService.onWillSaveState(() => - this.storageService.store(RECENT_CONNECTIONS_STATE_KEY, JSON.stringify(this.mru), StorageScope.APPLICATION, StorageTarget.MACHINE)); + this.storageService.store(RECENT_CONNECTIONS_STATE_KEY, JSON.stringify(this.mru), StorageScope.GLOBAL, StorageTarget.MACHINE)); } /** diff --git a/src/sql/workbench/api/common/extHostModelViewTree.ts b/src/sql/workbench/api/common/extHostModelViewTree.ts index 5aea9d8f91..7568e0c8b9 100644 --- a/src/sql/workbench/api/common/extHostModelViewTree.ts +++ b/src/sql/workbench/api/common/extHostModelViewTree.ts @@ -15,7 +15,8 @@ import * as vsTreeExt from 'vs/workbench/api/common/extHostTreeViews'; import { Emitter } from 'vs/base/common/event'; import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'; import { ILogService } from 'vs/platform/log/common/log'; -import { SqlMainContext, DataTransferDTO } from 'vs/workbench/api/common/extHost.protocol'; +import { DataTransferDTO } from 'vs/workbench/api/common/shared/dataTransfer'; +import { SqlMainContext } from 'vs/workbench/api/common/extHost.protocol'; export class ExtHostModelViewTreeViews implements ExtHostModelViewTreeViewsShape { private _proxy: MainThreadModelViewShape; @@ -85,7 +86,7 @@ export class ExtHostModelViewTreeViews implements ExtHostModelViewTreeViewsShape return Promise.resolve(undefined); } - $handleDrop(destinationViewId: string, requestId: number, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: vscode.CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise { + $handleDrop(destinationViewId: string, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: vscode.CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise { return Promise.resolve(undefined); } diff --git a/src/sql/workbench/api/common/sqlExtHost.protocol.ts b/src/sql/workbench/api/common/sqlExtHost.protocol.ts index c501aaab89..f55206e1f7 100644 --- a/src/sql/workbench/api/common/sqlExtHost.protocol.ts +++ b/src/sql/workbench/api/common/sqlExtHost.protocol.ts @@ -26,7 +26,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions' import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor'; import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry'; import { IQueryEvent } from 'sql/workbench/services/query/common/queryModel'; -import { DataTransferDTO } from 'vs/workbench/api/common/extHost.protocol'; +import { DataTransferDTO } from 'vs/workbench/api/common/shared/dataTransfer'; export abstract class ExtHostAzureBlobShape { public $createSas(connectionUri: string, blobContainerUri: string, blobStorageKey: string, storageAccountName: string, expirationDate: string): Thenable { throw ni(); } @@ -794,7 +794,7 @@ export interface ExtHostModelViewShape { export interface ExtHostModelViewTreeViewsShape { $getChildren(treeViewId: string, treeItemHandle?: string): Promise; - $handleDrop(destinationViewId: string, requestId: number, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: vscode.CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise; + $handleDrop(destinationViewId: string, treeDataTransfer: DataTransferDTO, targetHandle: string | undefined, token: vscode.CancellationToken, operationUuid?: string, sourceViewId?: string, sourceTreeItemHandles?: string[]): Promise; $handleDrag(sourceViewId: string, sourceTreeItemHandles: string[], operationUuid: string, token: vscode.CancellationToken): Promise; $createTreeView(handle: number, componentId: string, options: { treeDataProvider: vscode.TreeDataProvider }, extension: IExtensionDescription): azdata.TreeComponentView; diff --git a/src/sql/workbench/browser/designer/designerScriptEditor.ts b/src/sql/workbench/browser/designer/designerScriptEditor.ts index 14ad8b4997..affff83ed3 100644 --- a/src/sql/workbench/browser/designer/designerScriptEditor.ts +++ b/src/sql/workbench/browser/designer/designerScriptEditor.ts @@ -16,7 +16,7 @@ import * as nls from 'vs/nls'; import * as DOM from 'vs/base/browser/dom'; import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { AbstractTextCodeEditor } from 'vs/workbench/browser/parts/editor/textCodeEditor'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IStorageService } from 'vs/platform/storage/common/storage'; @@ -30,14 +30,13 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IModelService } from 'vs/editor/common/services/model'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; -import { IFileService } from 'vs/platform/files/common/files'; class DesignerCodeEditor extends CodeEditorWidget { } let DesignerScriptEditorInstanceId = 0; -export class DesignerScriptEditor extends AbstractTextCodeEditor implements DesignerTextEditor { +export class DesignerScriptEditor extends BaseTextEditor implements DesignerTextEditor { private _content: string; private _contentChangeEventEmitter: Emitter = new Emitter(); readonly onDidContentChange: Event = this._contentChangeEventEmitter.event; @@ -56,10 +55,9 @@ export class DesignerScriptEditor extends AbstractTextCodeEditor { +export class QueryTextEditor extends BaseTextEditor { public static ID = 'modelview.editors.textEditor'; private _dimension: DOM.Dimension; @@ -49,18 +47,15 @@ export class QueryTextEditor extends AbstractTextCodeEditor { - storageService.store(storageKey, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + storageService.store(storageKey, true, StorageScope.GLOBAL, StorageTarget.MACHINE); } }]); } diff --git a/src/sql/workbench/contrib/configuration/common/configurationUpgrader.ts b/src/sql/workbench/contrib/configuration/common/configurationUpgrader.ts index c927667db9..cccd4d57dd 100644 --- a/src/sql/workbench/contrib/configuration/common/configurationUpgrader.ts +++ b/src/sql/workbench/contrib/configuration/common/configurationUpgrader.ts @@ -31,7 +31,7 @@ const settingsToMove: { [key: string]: string } = deepFreeze({ export class ConfigurationUpgraderContribution implements IWorkbenchContribution { private static readonly STORAGE_KEY = 'configurationUpgrader'; - private readonly globalStorage: { [key: string]: boolean } = JSON.parse(this.storageService.get(ConfigurationUpgraderContribution.STORAGE_KEY, StorageScope.APPLICATION, '{}')); + private readonly globalStorage: { [key: string]: boolean } = JSON.parse(this.storageService.get(ConfigurationUpgraderContribution.STORAGE_KEY, StorageScope.GLOBAL, '{}')); private readonly workspaceStorage: { [key: string]: boolean } = JSON.parse(this.storageService.get(ConfigurationUpgraderContribution.STORAGE_KEY, StorageScope.WORKSPACE, '{}')); public readonly processingPromise: Promise; @@ -43,7 +43,7 @@ export class ConfigurationUpgraderContribution implements IWorkbenchContribution ) { this.processingPromise = (async () => { await this.processSettings(); - this.storageService.store(ConfigurationUpgraderContribution.STORAGE_KEY, JSON.stringify(this.globalStorage), StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(ConfigurationUpgraderContribution.STORAGE_KEY, JSON.stringify(this.globalStorage), StorageScope.GLOBAL, StorageTarget.MACHINE); this.storageService.store(ConfigurationUpgraderContribution.STORAGE_KEY, JSON.stringify(this.workspaceStorage), StorageScope.WORKSPACE, StorageTarget.MACHINE); })(); } diff --git a/src/sql/workbench/contrib/dashboard/browser/contents/webviewContent.component.ts b/src/sql/workbench/contrib/dashboard/browser/contents/webviewContent.component.ts index 1fbec76f09..4dd48edc5f 100644 --- a/src/sql/workbench/contrib/dashboard/browser/contents/webviewContent.component.ts +++ b/src/sql/workbench/contrib/dashboard/browser/contents/webviewContent.component.ts @@ -98,14 +98,11 @@ export class WebviewContent extends AngularDisposable implements OnInit, IDashbo this._onMessageDisposable.dispose(); } - this._webview = this.webviewService.createWebviewElement({ - id: this.id, - contentOptions: { - allowScripts: true, - }, - options: {}, - extension: undefined - }); + this._webview = this.webviewService.createWebviewElement(this.id, + {}, + { + allowScripts: true + }, undefined); this._webview.mountTo(this._el.nativeElement); diff --git a/src/sql/workbench/contrib/dashboard/browser/widgets/insights/insightsWidget.component.ts b/src/sql/workbench/contrib/dashboard/browser/widgets/insights/insightsWidget.component.ts index aec22b57d8..1cb2d45136 100644 --- a/src/sql/workbench/contrib/dashboard/browser/widgets/insights/insightsWidget.component.ts +++ b/src/sql/workbench/contrib/dashboard/browser/widgets/insights/insightsWidget.component.ts @@ -190,14 +190,14 @@ export class InsightsWidget extends DashboardWidget implements IDashboardWidget, }; this.lastUpdated = nls.localize('insights.lastUpdated', "Last Updated: {0} {1}", currentTime.toLocaleTimeString(), currentTime.toLocaleDateString()); this._changeRef.detectChanges(); - this.storageService.store(this._getStorageKey(), JSON.stringify(store), StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(this._getStorageKey(), JSON.stringify(store), StorageScope.GLOBAL, StorageTarget.MACHINE); } return result; } private _checkStorage(): boolean { if (this.insightConfig.cacheId) { - const storage = this.storageService.get(this._getStorageKey(), StorageScope.APPLICATION); + const storage = this.storageService.get(this._getStorageKey(), StorageScope.GLOBAL); if (storage) { const storedResult: IStorageResult = JSON.parse(storage); const date = new Date(storedResult.date); diff --git a/src/sql/workbench/contrib/dashboard/browser/widgets/webview/webviewWidget.component.ts b/src/sql/workbench/contrib/dashboard/browser/widgets/webview/webviewWidget.component.ts index d70e62c6c4..b965ec65e3 100644 --- a/src/sql/workbench/contrib/dashboard/browser/widgets/webview/webviewWidget.component.ts +++ b/src/sql/workbench/contrib/dashboard/browser/widgets/webview/webviewWidget.component.ts @@ -99,14 +99,11 @@ export class WebviewWidget extends DashboardWidget implements IDashboardWidget, this._onMessageDisposable.dispose(); } - this._webview = this.webviewService.createWebviewElement({ - id: this.id, - contentOptions: { + this._webview = this.webviewService.createWebviewElement(this.id, + {}, + { allowScripts: true, - }, - options: {}, - extension: undefined - }); + }, undefined); this._webview.mountTo(this._el.nativeElement); this._onMessageDisposable = this._webview.onMessage(e => { diff --git a/src/sql/workbench/contrib/editData/browser/editDataEditor.ts b/src/sql/workbench/contrib/editData/browser/editDataEditor.ts index da9b30aade..e88789ce73 100644 --- a/src/sql/workbench/contrib/editData/browser/editDataEditor.ts +++ b/src/sql/workbench/contrib/editData/browser/editDataEditor.ts @@ -41,7 +41,6 @@ import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { DisposableStore } from 'vs/base/common/lifecycle'; -import { ICodeEditorViewState } from 'vs/editor/common/editorCommon'; /** * Editor that hosts an action bar and a resultSetInput for an edit data session @@ -584,7 +583,7 @@ export class EditDataEditor extends EditorPane { newInput.results.onRestoreViewStateEmitter.fire(); } if (newInput.savedViewState) { - this._sqlEditor.getControl().restoreViewState(newInput.savedViewState); + this._sqlEditor.getControl().restoreViewState(newInput.savedViewState); } }); } diff --git a/src/sql/workbench/contrib/executionPlan/browser/executionPlanComparisonEditorView.ts b/src/sql/workbench/contrib/executionPlan/browser/executionPlanComparisonEditorView.ts index 53080c6591..72fca50162 100644 --- a/src/sql/workbench/contrib/executionPlan/browser/executionPlanComparisonEditorView.ts +++ b/src/sql/workbench/contrib/executionPlan/browser/executionPlanComparisonEditorView.ts @@ -798,10 +798,11 @@ class SearchNodeAction extends Action { public static LABEL_FOR_ADDED_PLAN = localize('epCompare.searchNodeActionAddedPlan', 'Find Node - Added Plan'); constructor(private readonly _planIdentifier: PlanIdentifier, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IAdsTelemetryService private readonly _telemetryService: IAdsTelemetryService) { - super(SearchNodeAction.ID, undefined, searchIconClassNames, true, () => { + const getLabelForAction = () => { return _planIdentifier === PlanIdentifier.Added ? SearchNodeAction.LABEL_FOR_ADDED_PLAN : SearchNodeAction.LABEL; - }); + }; + super(SearchNodeAction.ID, getLabelForAction(), searchIconClassNames); this.enabled = false; } diff --git a/src/sql/workbench/contrib/executionPlan/browser/executionPlanContribution.ts b/src/sql/workbench/contrib/executionPlan/browser/executionPlanContribution.ts index 9963299476..ca5de09e5c 100644 --- a/src/sql/workbench/contrib/executionPlan/browser/executionPlanContribution.ts +++ b/src/sql/workbench/contrib/executionPlan/browser/executionPlanContribution.ts @@ -70,16 +70,14 @@ export class ExecutionPlanEditorOverrideContribution extends Disposable implemen priority: RegisteredEditorPriority.builtin }, {}, - { - createEditorInput: (editorInput, group) => { - const executionPlanGraphInfo = { - graphFileContent: undefined, - graphFileType: undefined - }; - const executionPlanInput = this._register(this._instantiationService.createInstance(ExecutionPlanInput, editorInput.resource, executionPlanGraphInfo)); + (editorInput, group) => { + const executionPlanGraphInfo = { + graphFileContent: undefined, + graphFileType: undefined + }; + const executionPlanInput = this._register(this._instantiationService.createInstance(ExecutionPlanInput, editorInput.resource, executionPlanGraphInfo)); - return { editor: executionPlanInput, options: editorInput.options, group: group }; - } + return { editor: executionPlanInput, options: editorInput.options, group: group }; } )); } diff --git a/src/sql/workbench/contrib/executionPlan/browser/executionPlanView.ts b/src/sql/workbench/contrib/executionPlan/browser/executionPlanView.ts index 2ed39bab53..d3721b9f78 100644 --- a/src/sql/workbench/contrib/executionPlan/browser/executionPlanView.ts +++ b/src/sql/workbench/contrib/executionPlan/browser/executionPlanView.ts @@ -449,7 +449,7 @@ export class SavePlanFile extends Action { const fileExtension = 'sqlplan'; //TODO: Get this extension from provider let defaultUri: URI; - const lastUsedSavePath = this.storageService.get(SavePlanFile.LAST_USED_EXECUTION_PLAN_SAVE_PATH_STORAGE_KEY, StorageScope.APPLICATION); + const lastUsedSavePath = this.storageService.get(SavePlanFile.LAST_USED_EXECUTION_PLAN_SAVE_PATH_STORAGE_KEY, StorageScope.GLOBAL); if (lastUsedSavePath) { defaultUri = joinPath(URI.file(lastUsedSavePath), `${defaultFileName}.${fileExtension}`); @@ -479,7 +479,7 @@ export class SavePlanFile extends Action { if (destination) { // Remember as last used save folder - this.storageService.store(SavePlanFile.LAST_USED_EXECUTION_PLAN_SAVE_PATH_STORAGE_KEY, dirname(destination).fsPath, StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(SavePlanFile.LAST_USED_EXECUTION_PLAN_SAVE_PATH_STORAGE_KEY, dirname(destination).fsPath, StorageScope.GLOBAL, StorageTarget.MACHINE); // Perform save await context.fileService.writeFile(destination, VSBuffer.fromString(context.model.graphFile.graphFileContent)); diff --git a/src/sql/workbench/contrib/executionPlan/browser/widgets/highlightExpensiveNodeWidget.ts b/src/sql/workbench/contrib/executionPlan/browser/widgets/highlightExpensiveNodeWidget.ts index e4f1c5596d..135d8d6be9 100644 --- a/src/sql/workbench/contrib/executionPlan/browser/widgets/highlightExpensiveNodeWidget.ts +++ b/src/sql/workbench/contrib/executionPlan/browser/widgets/highlightExpensiveNodeWidget.ts @@ -181,7 +181,7 @@ export class HighlightExpensiveOperationWidget extends ExecutionPlanWidgetBase { public showStoreDefaultMetricPrompt(): void { const currentDefaultExpensiveOperationMetric = this.getDefaultExpensiveOperationMetric(); - if (this._selectedExpensiveOperationType === currentDefaultExpensiveOperationMetric || !this._storageService.getBoolean('qp.expensiveOperationMetric.showChangeDefaultExpensiveMetricPrompt', StorageScope.APPLICATION, true)) { + if (this._selectedExpensiveOperationType === currentDefaultExpensiveOperationMetric || !this._storageService.getBoolean('qp.expensiveOperationMetric.showChangeDefaultExpensiveMetricPrompt', StorageScope.GLOBAL, true)) { return; } @@ -197,7 +197,7 @@ export class HighlightExpensiveOperationWidget extends ExecutionPlanWidgetBase { }, { label: localize('qp.expensiveOperationMetric.dontShowAgain', "Don't Show Again"), - run: () => this._storageService.store('qp.expensiveOperationMetric.showChangeDefaultExpensiveMetricPrompt', false, StorageScope.APPLICATION, StorageTarget.USER) + run: () => this._storageService.store('qp.expensiveOperationMetric.showChangeDefaultExpensiveMetricPrompt', false, StorageScope.GLOBAL, StorageTarget.USER) } ]; diff --git a/src/sql/workbench/contrib/extensions/browser/scenarioRecommendations.ts b/src/sql/workbench/contrib/extensions/browser/scenarioRecommendations.ts index 31a31198cf..5354326773 100644 --- a/src/sql/workbench/contrib/extensions/browser/scenarioRecommendations.ts +++ b/src/sql/workbench/contrib/extensions/browser/scenarioRecommendations.ts @@ -52,7 +52,7 @@ export class ScenarioRecommendations extends ExtensionRecommendations { promptRecommendedExtensionsByScenario(scenarioType: string): void { const storageKey = 'extensionAssistant/RecommendationsIgnore/' + scenarioType; - if (this.storageService.getBoolean(storageKey, StorageScope.APPLICATION, false) || this.ignoreRecommendations()) { + if (this.storageService.getBoolean(storageKey, StorageScope.GLOBAL, false) || this.ignoreRecommendations()) { return; } @@ -104,7 +104,7 @@ export class ScenarioRecommendations extends ExtensionRecommendations { 'NeverShowAgainButton', visualizerExtensionNotificationService ); - this.storageService.store(storageKey, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(storageKey, true, StorageScope.GLOBAL, StorageTarget.MACHINE); } }], { diff --git a/src/sql/workbench/contrib/modelView/browser/webview.component.ts b/src/sql/workbench/contrib/modelView/browser/webview.component.ts index f380f45c98..89c8acd0f5 100644 --- a/src/sql/workbench/contrib/modelView/browser/webview.component.ts +++ b/src/sql/workbench/contrib/modelView/browser/webview.component.ts @@ -73,14 +73,11 @@ export default class WebViewComponent extends ComponentBase i } private _createWebview(): void { - this._webview = this.webviewService.createWebviewElement({ - id: this.id, - contentOptions: { - allowScripts: true, - }, - options: {}, - extension: undefined - }); + this._webview = this.webviewService.createWebviewElement(this.id, + {}, + { + allowScripts: true + }, undefined); this._webview.mountTo(this._el.nativeElement); diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/interfaces.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/interfaces.ts index b93827804e..e39c2f7648 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/interfaces.ts +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/interfaces.ts @@ -10,7 +10,7 @@ import { AngularDisposable } from 'sql/base/browser/lifecycle'; import { ICellEditorProvider, INotebookService, NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService'; import { MarkdownRenderOptions } from 'vs/base/browser/markdownRenderer'; import { IMarkdownString } from 'vs/base/common/htmlContent'; -import { AbstractTextCodeEditor } from 'vs/workbench/browser/parts/editor/textCodeEditor'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { nb } from 'azdata'; import { NotebookModel } from 'sql/workbench/services/notebook/browser/models/notebookModel'; import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput'; @@ -34,7 +34,7 @@ export abstract class CellView extends AngularDisposable implements OnDestroy, I public abstract layout(): void; - public getEditor(): AbstractTextCodeEditor | undefined { + public getEditor(): BaseTextEditor | undefined { return undefined; } diff --git a/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts index f6e74cd77e..82aa3e3a53 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -803,19 +803,18 @@ export class NotebookEditorOverrideContribution extends Disposable implements IW priority: RegisteredEditorPriority.builtin }, {}, - { - createEditorInput: async (editorInput, group) => { - const fileInput = await this._editorService.createEditorInput(editorInput) as FileEditorInput; - // Try to convert the input, falling back to just a plain file input if we're unable to - const newInput = this.convertInput(fileInput); - return { editor: newInput, options: editorInput.options, group: group }; - }, - createDiffEditorInput: async (diffEditorInput, group) => { - const diffEditorInputImpl = await this._editorService.createEditorInput(diffEditorInput) as DiffEditorInput; - // Try to convert the input, falling back to the original input if we're unable to - const newInput = this.convertInput(diffEditorInputImpl); - return { editor: newInput, options: diffEditorInput.options, group: group }; - } + async (editorInput, group) => { + const fileInput = await this._editorService.createEditorInput(editorInput) as FileEditorInput; + // Try to convert the input, falling back to just a plain file input if we're unable to + const newInput = this.convertInput(fileInput); + return { editor: newInput, options: editorInput.options, group: group }; + }, + undefined, + async (diffEditorInput, group) => { + const diffEditorInputImpl = await this._editorService.createEditorInput(diffEditorInput) as DiffEditorInput; + // Try to convert the input, falling back to the original input if we're unable to + const newInput = this.convertInput(diffEditorInputImpl); + return { editor: newInput, options: diffEditorInput.options, group: group }; } )); } diff --git a/src/sql/workbench/contrib/notebook/browser/notebookEditor.ts b/src/sql/workbench/contrib/notebook/browser/notebookEditor.ts index f827803d73..38d6274408 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebookEditor.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebookEditor.ts @@ -32,7 +32,7 @@ import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { IModelDecorationsChangeAccessor, IModelDeltaDecoration } from 'vs/editor/common/model'; import { NotebookFindDecorations } from 'sql/workbench/contrib/notebook/browser/find/notebookFindDecorations'; import { TimeoutTimer } from 'vs/base/common/async'; -import { AbstractTextCodeEditor } from 'vs/workbench/browser/parts/editor/textCodeEditor'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { onUnexpectedError } from 'vs/base/common/errors'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/browser/findState'; @@ -94,7 +94,7 @@ export class NotebookEditor extends EditorPane implements IFindNotebookControlle public getLastPosition(): NotebookRange { return this._previousMatch; } - public getCellEditor(cellGuid: string): AbstractTextCodeEditor | undefined { + public getCellEditor(cellGuid: string): BaseTextEditor | undefined { let editorImpl = this._notebookService.findNotebookEditor(this.notebookInput.notebookUri); if (editorImpl) { let cellEditorProvider = editorImpl.cellEditors.filter(c => c.cellGuid() === cellGuid)[0]; diff --git a/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts b/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts index 1d1f88254c..3763dd88cb 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts @@ -33,7 +33,7 @@ import { NotebookEditorStub } from 'sql/workbench/contrib/notebook/test/testComm import { Range } from 'vs/editor/common/core/range'; import { IProductService } from 'vs/platform/product/common/productService'; import { TestAccessibilityService } from 'vs/platform/accessibility/test/common/testAccessibilityService'; -import { LanguageId } from 'vs/editor/common/encodedTokenAttributes'; +import { LanguageId } from 'vs/editor/common/languages'; suite.skip('MarkdownTextTransformer', () => { let markdownTextTransformer: MarkdownTextTransformer; diff --git a/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts b/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts index 82876639c8..f7c084b485 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts @@ -730,8 +730,7 @@ function setupServices(arg: { workbenchThemeService?: WorkbenchThemeService, ins instantiationService.get(ITextResourceConfigurationService), instantiationService.get(IThemeService), instantiationService.get(IEditorGroupsService), - instantiationService.get(IEditorService), - instantiationService.get(IFileService) + instantiationService.get(IEditorService) ); const notebookEditorStub = new NotebookEditorStub({ cellGuid: cellTextEditorGuid, editor: queryTextEditor, model: new NotebookModelStub(), notebookParams: { notebookUri: untitledNotebookInput.notebookUri } }); notebookService.addNotebookEditor(notebookEditorStub); diff --git a/src/sql/workbench/contrib/notebook/test/testCommon.ts b/src/sql/workbench/contrib/notebook/test/testCommon.ts index 837f9080e4..4c4256c814 100644 --- a/src/sql/workbench/contrib/notebook/test/testCommon.ts +++ b/src/sql/workbench/contrib/notebook/test/testCommon.ts @@ -11,7 +11,7 @@ import * as dom from 'vs/base/browser/dom'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService'; -import { TestEditorGroupsService, TestEditorService, TestFileService, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestEditorGroupsService, TestEditorService, TestTextResourceConfigurationService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; import { NotebookViewsExtension } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViewsExtension'; @@ -48,8 +48,7 @@ class CellEditorProviderStub extends stubs.CellEditorProviderStub { new TestTextResourceConfigurationService(), new TestThemeService(), new TestEditorGroupsService(), - new TestEditorService(), - new TestFileService() + new TestEditorService() ); } if (this._editor) { diff --git a/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts b/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts index 78749649af..eca0a98c41 100644 --- a/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts +++ b/src/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.ts @@ -44,7 +44,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IConnectionProfile } from 'sql/platform/connection/common/interfaces'; -import { workbenchTreeDataPreamble } from 'vs/platform/list/browser/listService'; suite('SQL Connection Tree Action tests', () => { let errorMessageService: TypeMoq.Mock; @@ -707,16 +706,7 @@ suite('SQL Connection Tree Action tests', () => { }); }); - /* - TypeError: instantiationService.invokeFunction is not a function - at new WorkbenchAsyncDataTree (file:///C:/Users/lewissanchez/GitProjects/azuredatastudio-merge/out/vs/platform/list/browser/listService.js:643:102) - at new AsyncServerTree (file:///C:/Users/lewissanchez/GitProjects/azuredatastudio-merge/out/sql/workbench/services/objectExplorer/browser/asyncServerTree.js:9:5) - at Utils.conthunktor (C:\Users\lewissanchez\GitProjects\azuredatastudio-merge\node_modules\typemoq\typemoq.js:227:23) - at Mock.ofType2 (C:\Users\lewissanchez\GitProjects\azuredatastudio-merge\node_modules\typemoq\typemoq.js:1248:48) - at Mock.ofType (C:\Users\lewissanchez\GitProjects\azuredatastudio-merge\node_modules\typemoq\typemoq.js:1243:29) - at Context. (file:///C:/Users/lewissanchez/GitProjects/azuredatastudio-merge/out/sql/workbench/contrib/objectExplorer/test/browser/connectionTreeActions.test.js:612: - */ - test.skip('RefreshConnectionAction - AsyncServerTree - refresh should not be called if connection status is not connect', (done) => { // {{SQL CARBON TODO}} 3/17/23 Not sure why this is failing after mokcing the instantiation service's invoke function. + test('RefreshConnectionAction - AsyncServerTree - refresh should not be called if connection status is not connect', () => { let isConnectedReturnValue: boolean = false; let sqlProvider = { providerId: mssqlProviderName, @@ -780,24 +770,6 @@ suite('SQL Connection Tree Action tests', () => { objectExplorerService.callBase = true; objectExplorerService.setup(x => x.getObjectExplorerNode(TypeMoq.It.isAny())).returns(() => tablesNode); objectExplorerService.setup(x => x.refreshTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve([table1Node, table2Node])); - - let testDisposable = { - dispose() { - // - } - }; - let testInstantiationService = TypeMoq.Mock.ofType(InstantiationService, TypeMoq.MockBehavior.Loose); - testInstantiationService.setup(x => x.invokeFunction(workbenchTreeDataPreamble, TypeMoq.It.isAny())).returns((): any => { - return { - getTypeNavigationMode: undefined, - disposable: testDisposable, - treeOptions: {} - }; - }); - - let mockContextKeyService = new MockContextKeyService(); - let testListService = new TestListService(); - let testConfigurationService = new TestConfigurationService(); let tree = TypeMoq.Mock.ofType(AsyncServerTree, TypeMoq.MockBehavior.Loose, 'ConnectionTreeActionsTest', // user $('div'), // container @@ -805,11 +777,12 @@ suite('SQL Connection Tree Action tests', () => { [], // renderers {}, // data source {}, // options - testInstantiationService.object, - mockContextKeyService, // IContextKeyService - testListService, // IListService, + new MockContextKeyService(), // IContextKeyService + new TestListService(), // IListService, undefined, // IThemeService, - testConfigurationService); // IConfigurationService, + new TestConfigurationService(), // IConfigurationService, + undefined, // IKeybindingService, + new TestAccessibilityService()); // IAccessibilityService tree.callBase = true; tree.setup(x => x.updateChildren(TypeMoq.It.isAny())).returns(() => Promise.resolve()); @@ -829,7 +802,6 @@ suite('SQL Connection Tree Action tests', () => { objectExplorerService.verify(x => x.refreshTreeNode(TypeMoq.It.isAny(), TypeMoq.It.isAny()), TypeMoq.Times.exactly(0)); tree.verify(x => x.updateChildren(TypeMoq.It.isAny()), TypeMoq.Times.exactly(0)); tree.verify(x => x.expand(TypeMoq.It.isAny()), TypeMoq.Times.exactly(0)); - done(); }); }); diff --git a/src/sql/workbench/contrib/profiler/browser/profilerResourceEditor.ts b/src/sql/workbench/contrib/profiler/browser/profilerResourceEditor.ts index 4b3c1b3d5b..9450b7c4f0 100644 --- a/src/sql/workbench/contrib/profiler/browser/profilerResourceEditor.ts +++ b/src/sql/workbench/contrib/profiler/browser/profilerResourceEditor.ts @@ -9,7 +9,7 @@ import * as DOM from 'vs/base/browser/dom'; import { TextResourceEditorModel } from 'vs/workbench/common/editor/textResourceEditorModel'; import * as editorCommon from 'vs/editor/common/editorCommon'; -import { AbstractTextCodeEditor } from 'vs/workbench/browser/parts/editor/textCodeEditor'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; @@ -23,7 +23,6 @@ import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget'; import { ITextEditorOptions } from 'vs/platform/editor/common/editor'; import { EditorInput } from 'vs/workbench/common/editor/editorInput'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfiguration'; -import { IFileService } from 'vs/platform/files/common/files'; class ProfilerResourceCodeEditor extends CodeEditorWidget { @@ -39,7 +38,7 @@ class ProfilerResourceCodeEditor extends CodeEditorWidget { /** * Extension of TextResourceEditor that is always readonly rather than only with non UntitledInputs */ -export class ProfilerResourceEditor extends AbstractTextCodeEditor { +export class ProfilerResourceEditor extends BaseTextEditor { public static ID = 'profiler.editors.textEditor'; constructor( @@ -49,16 +48,14 @@ export class ProfilerResourceEditor extends AbstractTextCodeEditor false + canHandleDiff: () => false }, - { - createEditorInput: async (editorInput, group) => { - const fileInput = await this._editorService.createEditorInput(editorInput) as FileEditorInput; - const langAssociation = languageAssociationRegistry.getAssociationForLanguage(lang); - const queryEditorInput = langAssociation?.syncConvertInput?.(fileInput); - if (!queryEditorInput) { - this._logService.warn('Unable to create input for resolving editor ', editorInput.resource); - return undefined; - } - return { editor: queryEditorInput, options: editorInput.options, group: group }; + async (editorInput, group) => { + const fileInput = await this._editorService.createEditorInput(editorInput) as FileEditorInput; + const langAssociation = languageAssociationRegistry.getAssociationForLanguage(lang); + const queryEditorInput = langAssociation?.syncConvertInput?.(fileInput); + if (!queryEditorInput) { + this._logService.warn('Unable to create input for resolving editor ', editorInput.resource); + return undefined; } + return { editor: queryEditorInput, options: editorInput.options, group: group }; } )); }); diff --git a/src/sql/workbench/contrib/query/browser/queryEditor.ts b/src/sql/workbench/contrib/query/browser/queryEditor.ts index ea5da92e97..6659c1ca15 100644 --- a/src/sql/workbench/contrib/query/browser/queryEditor.ts +++ b/src/sql/workbench/contrib/query/browser/queryEditor.ts @@ -27,7 +27,7 @@ import { Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IAction } from 'vs/base/common/actions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { AbstractTextCodeEditor } from 'vs/workbench/browser/parts/editor/textCodeEditor'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/fileEditorInput'; import { URI } from 'vs/base/common/uri'; import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files'; @@ -71,7 +71,7 @@ export class QueryEditor extends EditorPane { private textResourceEditor: TextResourceEditor; private textFileEditor: TextFileEditor; - private currentTextEditor: AbstractTextCodeEditor; + private currentTextEditor: BaseTextEditor; private textResourceEditorContainer: HTMLElement; private textFileEditorContainer: HTMLElement; diff --git a/src/sql/workbench/contrib/webview/browser/webViewDialog.ts b/src/sql/workbench/contrib/webview/browser/webViewDialog.ts index e90c993af8..630b790de6 100644 --- a/src/sql/workbench/contrib/webview/browser/webViewDialog.ts +++ b/src/sql/workbench/contrib/webview/browser/webViewDialog.ts @@ -87,14 +87,11 @@ export class WebViewDialog extends Modal { protected renderBody(container: HTMLElement) { this._body = DOM.append(container, DOM.$('div.webview-dialog')); - this._webview = this.webviewService.createWebviewElement({ - id: this.id, - contentOptions: { - allowScripts: true, - }, - options: {}, - extension: undefined - }); + this._webview = this.webviewService.createWebviewElement(this.id, + {}, + { + allowScripts: true + }, undefined); this._webview.mountTo(this._body); diff --git a/src/sql/workbench/contrib/welcome/gettingStarted/browser/abstractEnablePreviewFeatures.ts b/src/sql/workbench/contrib/welcome/gettingStarted/browser/abstractEnablePreviewFeatures.ts index bc992ba145..ae249dd819 100644 --- a/src/sql/workbench/contrib/welcome/gettingStarted/browser/abstractEnablePreviewFeatures.ts +++ b/src/sql/workbench/contrib/welcome/gettingStarted/browser/abstractEnablePreviewFeatures.ts @@ -25,7 +25,7 @@ export abstract class AbstractEnablePreviewFeatures implements IWorkbenchContrib protected handlePreviewFeatures(): void { let previewFeaturesEnabled = this.configurationService.getValue(CONFIG_WORKBENCH_ENABLEPREVIEWFEATURES); - if (previewFeaturesEnabled || this.storageService.get(AbstractEnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, StorageScope.APPLICATION)) { + if (previewFeaturesEnabled || this.storageService.get(AbstractEnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, StorageScope.GLOBAL)) { return; } Promise.all([ @@ -45,7 +45,7 @@ export abstract class AbstractEnablePreviewFeatures implements IWorkbenchContrib label: localize('enablePreviewFeatures.yes', "Yes (recommended)"), run: () => { this.configurationService.updateValue(CONFIG_WORKBENCH_ENABLEPREVIEWFEATURES, true).catch(e => onUnexpectedError(e)); - this.storageService.store(AbstractEnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(AbstractEnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true, StorageScope.GLOBAL, StorageTarget.MACHINE); } }, { label: localize('enablePreviewFeatures.no', "No"), @@ -56,7 +56,7 @@ export abstract class AbstractEnablePreviewFeatures implements IWorkbenchContrib label: localize('enablePreviewFeatures.never', "No, don't show again"), run: () => { this.configurationService.updateValue(CONFIG_WORKBENCH_ENABLEPREVIEWFEATURES, false).catch(e => onUnexpectedError(e)); - this.storageService.store(AbstractEnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + this.storageService.store(AbstractEnablePreviewFeatures.ENABLE_PREVIEW_FEATURES_SHOWN, true, StorageScope.GLOBAL, StorageTarget.MACHINE); }, isSecondary: true }] diff --git a/src/sql/workbench/contrib/welcome/notifyEncryption/notifyEncryptionDialog.ts b/src/sql/workbench/contrib/welcome/notifyEncryption/notifyEncryptionDialog.ts index fde9d9e687..f1e7f75339 100644 --- a/src/sql/workbench/contrib/welcome/notifyEncryption/notifyEncryptionDialog.ts +++ b/src/sql/workbench/contrib/welcome/notifyEncryption/notifyEncryptionDialog.ts @@ -43,11 +43,11 @@ export class NotifyEncryptionDialog extends ErrorMessageDialog { } public override open(): void { - if (this._storageService.get(NotifyEncryptionDialog.NOTIFY_ENCRYPT_SHOWN, StorageScope.APPLICATION)) { + if (this._storageService.get(NotifyEncryptionDialog.NOTIFY_ENCRYPT_SHOWN, StorageScope.GLOBAL)) { return; } - this._storageService.store(NotifyEncryptionDialog.NOTIFY_ENCRYPT_SHOWN, true, StorageScope.APPLICATION, StorageTarget.MACHINE); + this._storageService.store(NotifyEncryptionDialog.NOTIFY_ENCRYPT_SHOWN, true, StorageScope.GLOBAL, StorageTarget.MACHINE); if (!this._connectionManagementService.getConnections()?.some(conn => conn.providerName === mssqlProviderName)) { return; diff --git a/src/sql/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/sql/workbench/contrib/welcome/page/browser/welcomePage.ts index 90ed289be2..a691f74360 100644 --- a/src/sql/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/sql/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -382,7 +382,7 @@ class WelcomePage extends Disposable { newButton.onDidClick(() => { this.contextMenuService.showContextMenu({ getAnchor: () => newButtonHtmlElement, - getActions: () => NewActionItems.map(command => new MenuItemAction(command, undefined, {}, undefined, this.contextKeyService, this.commandService)) + getActions: () => NewActionItems.map(command => new MenuItemAction(command, undefined, {}, this.contextKeyService, this.commandService)) }); }); diff --git a/src/sql/workbench/services/accountManagement/browser/accountManagementService.ts b/src/sql/workbench/services/accountManagement/browser/accountManagementService.ts index cddb288b03..b33afc03dc 100644 --- a/src/sql/workbench/services/accountManagement/browser/accountManagementService.ts +++ b/src/sql/workbench/services/accountManagement/browser/accountManagementService.ts @@ -67,7 +67,7 @@ export class AccountManagementService implements IAccountManagementService { @IAdsTelemetryService private _telemetryService: IAdsTelemetryService ) { this._mementoContext = new Memento(AccountManagementService.ACCOUNT_MEMENTO, this._storageService); - const mementoObj = this._mementoContext.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE); + const mementoObj = this._mementoContext.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE); this._accountStore = this._instantiationService.createInstance(AccountStore, mementoObj); // Setup the event emitters diff --git a/src/sql/workbench/services/connection/browser/connectionManagementService.ts b/src/sql/workbench/services/connection/browser/connectionManagementService.ts index 1f8ecb6e8a..1e7d23224a 100644 --- a/src/sql/workbench/services/connection/browser/connectionManagementService.ts +++ b/src/sql/workbench/services/connection/browser/connectionManagementService.ts @@ -123,7 +123,7 @@ export class ConnectionManagementService extends Disposable implements IConnecti this._connectionStatusManager = _instantiationService.createInstance(ConnectionStatusManager); if (this._storageService) { this._mementoContext = new Memento(ConnectionManagementService.CONNECTION_MEMENTO, this._storageService); - this._mementoObj = this._mementoContext.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE); + this._mementoObj = this._mementoContext.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE); } this.initializeConnectionProvidersMap(); diff --git a/src/sql/workbench/services/insights/common/insightsUtils.ts b/src/sql/workbench/services/insights/common/insightsUtils.ts index d1c3f13924..ccb4abada4 100644 --- a/src/sql/workbench/services/insights/common/insightsUtils.ts +++ b/src/sql/workbench/services/insights/common/insightsUtils.ts @@ -12,7 +12,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; -/* eslint-disable */ /** * Resolves the given file path using the VS ConfigurationResolver service, replacing macros such as * ${workspaceRoot} with their expected values and then testing each path to see if it exists. It will @@ -59,4 +58,3 @@ export async function resolveQueryFilePath(services: ServicesAccessor, filePath? throw Error(localize('insightsDidNotFindResolvedFile', "Could not find query file at any of the following paths :\n {0}", resolvedFileUris.map(uri => uri.fsPath).join('\n'))); } -/* eslint-enable */ diff --git a/src/sql/workbench/services/notebook/browser/notebookService.ts b/src/sql/workbench/services/notebook/browser/notebookService.ts index 41ed71afc3..018bc278e3 100644 --- a/src/sql/workbench/services/notebook/browser/notebookService.ts +++ b/src/sql/workbench/services/notebook/browser/notebookService.ts @@ -15,7 +15,7 @@ import { INotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes import { ICellModel, INotebookModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces'; import { NotebookChangeType, CellType } from 'sql/workbench/services/notebook/common/contracts'; import { IBootstrapParams } from 'sql/workbench/services/bootstrap/common/bootstrapParams'; -import { AbstractTextCodeEditor } from 'vs/workbench/browser/parts/editor/textCodeEditor'; +import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { Range } from 'vs/editor/common/core/range'; import { IEditorPane } from 'vs/workbench/common/editor'; import { INotebookInput } from 'sql/workbench/services/notebook/browser/interface'; @@ -196,7 +196,7 @@ export interface INotebookSection { export interface ICellEditorProvider { isCellOutput: boolean; cellGuid(): string; - getEditor(): AbstractTextCodeEditor | undefined; + getEditor(): BaseTextEditor | undefined; deltaDecorations(newDecorationsRange: NotebookRange | NotebookRange[], oldDecorationsRange: NotebookRange | NotebookRange[]): void; } diff --git a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts index 1e61ef918f..f4c0245d95 100644 --- a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts +++ b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts @@ -866,11 +866,11 @@ export class NotebookService extends Disposable implements INotebookService { } private get providersMemento(): NotebookProvidersMemento { - return this._providersMemento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE) as NotebookProvidersMemento; + return this._providersMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE) as NotebookProvidersMemento; } private get trustedNotebooksMemento(): TrustedNotebooksMemento { - let cache = this._trustedNotebooksMemento.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE) as TrustedNotebooksMemento; + let cache = this._trustedNotebooksMemento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE) as TrustedNotebooksMemento; if (!cache.trustedNotebooksCache) { cache.trustedNotebooksCache = {}; } diff --git a/src/sql/workbench/services/objectExplorer/browser/asyncServerTree.ts b/src/sql/workbench/services/objectExplorer/browser/asyncServerTree.ts index da45e66b8f..b1a91d8a6b 100644 --- a/src/sql/workbench/services/objectExplorer/browser/asyncServerTree.ts +++ b/src/sql/workbench/services/objectExplorer/browser/asyncServerTree.ts @@ -12,11 +12,12 @@ import { IAsyncDataTreeNode, IAsyncDataTreeUpdateChildrenOptions } from 'vs/base import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IAsyncDataSource, ITreeRenderer } from 'vs/base/browser/ui/tree/tree'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { KeyCode } from 'vs/base/common/keyCodes'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; export class AsyncServerTree extends WorkbenchAsyncDataTree { @@ -31,13 +32,14 @@ export class AsyncServerTree extends WorkbenchAsyncDataTree { diff --git a/src/sql/workbench/services/profiler/browser/profilerService.ts b/src/sql/workbench/services/profiler/browser/profilerService.ts index 4482b10a8d..f4ca075a31 100644 --- a/src/sql/workbench/services/profiler/browser/profilerService.ts +++ b/src/sql/workbench/services/profiler/browser/profilerService.ts @@ -72,7 +72,7 @@ export class ProfilerService implements IProfilerService { @IStorageService private _storageService: IStorageService ) { this._context = new Memento('ProfilerEditor', this._storageService); - this._memento = this._context.getMemento(StorageScope.APPLICATION, StorageTarget.MACHINE); + this._memento = this._context.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE); } public registerProvider(providerId: string, provider: azdata.ProfilerProvider): void { diff --git a/src/tsconfig.monaco.json b/src/tsconfig.monaco.json index 057aa8748a..f9f0c874eb 100644 --- a/src/tsconfig.monaco.json +++ b/src/tsconfig.monaco.json @@ -2,10 +2,7 @@ "extends": "./tsconfig.base.json", "compilerOptions": { "noEmit": true, - "types": [ - "trusted-types", - "wicg-file-system-access" - ], + "types": ["trusted-types"], "paths": {}, "module": "amd", "moduleResolution": "classic", @@ -18,8 +15,9 @@ "include": [ "typings/require.d.ts", "typings/thenable.d.ts", - "vs/loader.d.ts", + "vs/css.d.ts", "vs/monaco.d.ts", + "vs/nls.d.ts", "vs/editor/*", "vs/base/common/*", "vs/base/browser/*", @@ -30,7 +28,6 @@ "node_modules/*", "vs/platform/files/browser/htmlFileSystemProvider.ts", "vs/platform/files/browser/webFileSystemAccess.ts", - "vs/platform/telemetry/*", "vs/platform/assignment/*" ] } diff --git a/src/tsconfig.vscode-dts.json b/src/tsconfig.vscode-dts.json index b860765839..4ae9bc7643 100644 --- a/src/tsconfig.vscode-dts.json +++ b/src/tsconfig.vscode-dts.json @@ -14,7 +14,6 @@ "types": [], "lib": [ "es5", - "ES2015.Iterable" ], }, "include": [ diff --git a/src/tsec.exemptions.json b/src/tsec.exemptions.json index c2479eb2c7..7bad0d38d2 100644 --- a/src/tsec.exemptions.json +++ b/src/tsec.exemptions.json @@ -7,7 +7,7 @@ "vs/workbench/api/worker/extHostExtensionService.ts", "vs/base/worker/workerMain", "vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts", - "vs/workbench/services/keybinding/test/node/keyboardMapperTestUtils.ts" + "vs/workbench/services/keybinding/test/electron-browser/keyboardMapperTestUtils.ts" ], "ban-trustedtypes-createpolicy": [ "vs/base/browser/dom.ts", @@ -15,7 +15,6 @@ "vs/base/browser/defaultWorkerFactory.ts", "vs/base/worker/workerMain.ts", "vs/editor/contrib/markdownRenderer/browser/markdownRenderer.ts", - "vs/editor/contrib/stickyScroll/browser/stickyScroll.ts", "vs/editor/browser/view/domLineBreaksComputer.ts", "vs/editor/browser/view/viewLayer.ts", "vs/editor/browser/widget/diffEditorWidget.ts", diff --git a/src/vs/base/browser/broadcast.ts b/src/vs/base/browser/broadcast.ts deleted file mode 100644 index 31b5d06141..0000000000 --- a/src/vs/base/browser/broadcast.ts +++ /dev/null @@ -1,69 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { getErrorMessage } from 'vs/base/common/errors'; -import { Emitter } from 'vs/base/common/event'; -import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; - -export class BroadcastDataChannel extends Disposable { - - private broadcastChannel: BroadcastChannel | undefined; - - private readonly _onDidReceiveData = this._register(new Emitter()); - readonly onDidReceiveData = this._onDidReceiveData.event; - - constructor(private readonly channelName: string) { - super(); - - // Use BroadcastChannel - if ('BroadcastChannel' in window) { - try { - this.broadcastChannel = new BroadcastChannel(channelName); - const listener = (event: MessageEvent) => { - this._onDidReceiveData.fire(event.data); - }; - this.broadcastChannel.addEventListener('message', listener); - this._register(toDisposable(() => { - if (this.broadcastChannel) { - this.broadcastChannel.removeEventListener('message', listener); - this.broadcastChannel.close(); - } - })); - } catch (error) { - console.warn('Error while creating broadcast channel. Falling back to localStorage.', getErrorMessage(error)); - } - } - - // BroadcastChannel is not supported. Use storage. - if (!this.broadcastChannel) { - this.channelName = `BroadcastDataChannel.${channelName}`; - this.createBroadcastChannel(); - } - } - - private createBroadcastChannel(): void { - const listener = (event: StorageEvent) => { - if (event.key === this.channelName && event.newValue) { - this._onDidReceiveData.fire(JSON.parse(event.newValue)); - } - }; - window.addEventListener('storage', listener); - this._register(toDisposable(() => window.removeEventListener('storage', listener))); - } - - /** - * Sends the data to other BroadcastChannel objects set up for this channel. Data can be structured objects, e.g. nested objects and arrays. - * @param data data to broadcast - */ - postData(data: T): void { - if (this.broadcastChannel) { - this.broadcastChannel.postMessage(data); - } else { - // remove previous changes so that event is triggered even if new changes are same as old changes - window.localStorage.removeItem(this.channelName); - window.localStorage.setItem(this.channelName, JSON.stringify(data)); - } - } -} diff --git a/src/vs/base/browser/browser.ts b/src/vs/base/browser/browser.ts index 23ff961ef5..4fc3109271 100644 --- a/src/vs/base/browser/browser.ts +++ b/src/vs/base/browser/browser.ts @@ -71,7 +71,9 @@ class DevicePixelRatioMonitor extends Disposable { } private _handleChange(fireEvent: boolean): void { - this._mediaQueryList?.removeEventListener('change', this._listener); + if (this._mediaQueryList) { + this._mediaQueryList.removeEventListener('change', this._listener); + } this._mediaQueryList = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`); this._mediaQueryList.addEventListener('change', this._listener); diff --git a/src/vs/base/browser/defaultWorkerFactory.ts b/src/vs/base/browser/defaultWorkerFactory.ts index a7e79f1790..5a755f7e3c 100644 --- a/src/vs/base/browser/defaultWorkerFactory.ts +++ b/src/vs/base/browser/defaultWorkerFactory.ts @@ -86,11 +86,15 @@ class WebWorker implements IWorker { } public postMessage(message: any, transfer: Transferable[]): void { - this.worker?.then(w => w.postMessage(message, transfer)); + if (this.worker) { + this.worker.then(w => w.postMessage(message, transfer)); + } } public dispose(): void { - this.worker?.then(w => w.terminate()); + if (this.worker) { + this.worker.then(w => w.terminate()); + } this.worker = null; } } @@ -108,7 +112,7 @@ export class DefaultWorkerFactory implements IWorkerFactory { } public create(moduleId: string, onMessageCallback: IWorkerCallback, onErrorCallback: (err: any) => void): IWorker { - const workerId = (++DefaultWorkerFactory.LAST_WORKER_ID); + let workerId = (++DefaultWorkerFactory.LAST_WORKER_ID); if (this._webWorkerFailedBeforeError) { throw this._webWorkerFailedBeforeError; diff --git a/src/vs/base/browser/deviceAccess.ts b/src/vs/base/browser/deviceAccess.ts deleted file mode 100644 index 4c27962098..0000000000 --- a/src/vs/base/browser/deviceAccess.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -// https://wicg.github.io/webusb/ - -export interface UsbDeviceData { - readonly deviceClass: number; - readonly deviceProtocol: number; - readonly deviceSubclass: number; - readonly deviceVersionMajor: number; - readonly deviceVersionMinor: number; - readonly deviceVersionSubminor: number; - readonly manufacturerName?: string; - readonly productId: number; - readonly productName?: string; - readonly serialNumber?: string; - readonly usbVersionMajor: number; - readonly usbVersionMinor: number; - readonly usbVersionSubminor: number; - readonly vendorId: number; -} - -export async function requestUsbDevice(options?: { filters?: unknown[] }): Promise { - const usb = (navigator as any).usb; - if (!usb) { - return undefined; - } - - const device = await usb.requestDevice({ filters: options?.filters ?? [] }); - if (!device) { - return undefined; - } - - return { - deviceClass: device.deviceClass, - deviceProtocol: device.deviceProtocol, - deviceSubclass: device.deviceSubclass, - deviceVersionMajor: device.deviceVersionMajor, - deviceVersionMinor: device.deviceVersionMinor, - deviceVersionSubminor: device.deviceVersionSubminor, - manufacturerName: device.manufacturerName, - productId: device.productId, - productName: device.productName, - serialNumber: device.serialNumber, - usbVersionMajor: device.usbVersionMajor, - usbVersionMinor: device.usbVersionMinor, - usbVersionSubminor: device.usbVersionSubminor, - vendorId: device.vendorId, - }; -} - -// https://wicg.github.io/serial/ - -export interface SerialPortData { - readonly usbVendorId?: number | undefined; - readonly usbProductId?: number | undefined; -} - -export async function requestSerialPort(options?: { filters?: unknown[] }): Promise { - const serial = (navigator as any).serial; - if (!serial) { - return undefined; - } - - const port = await serial.requestPort({ filters: options?.filters ?? [] }); - if (!port) { - return undefined; - } - - const info = port.getInfo(); - return { - usbVendorId: info.usbVendorId, - usbProductId: info.usbProductId - }; -} - -// https://wicg.github.io/webhid/ - -export interface HidDeviceData { - readonly opened: boolean; - readonly vendorId: number; - readonly productId: number; - readonly productName: string; - readonly collections: []; -} - -export async function requestHidDevice(options?: { filters?: unknown[] }): Promise { - const hid = (navigator as any).hid; - if (!hid) { - return undefined; - } - - const devices = await hid.requestDevice({ filters: options?.filters ?? [] }); - if (!devices.length) { - return undefined; - } - - const device = devices[0]; - return { - opened: device.opened, - vendorId: device.vendorId, - productId: device.productId, - productName: device.productName, - collections: device.collections - }; -} diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index c17d37d6f7..c99a802668 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -88,7 +88,7 @@ function _wrapAsStandardKeyboardEvent(handler: (e: IKeyboardEvent) => void): (e: return handler(new StandardKeyboardEvent(e)); }; } -export const addStandardDisposableListener: IAddStandardDisposableListenerSignature = function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable { +export let addStandardDisposableListener: IAddStandardDisposableListenerSignature = function addStandardDisposableListener(node: HTMLElement, type: string, handler: (event: any) => void, useCapture?: boolean): IDisposable { let wrapHandler = handler; if (type === 'click' || type === 'mousedown') { @@ -100,14 +100,14 @@ export const addStandardDisposableListener: IAddStandardDisposableListenerSignat return addDisposableListener(node, type, wrapHandler, useCapture); }; -export const addStandardDisposableGenericMouseDownListener = function addStandardDisposableListener(node: HTMLElement, handler: (event: any) => void, useCapture?: boolean): IDisposable { - const wrapHandler = _wrapAsStandardMouseEvent(handler); +export let addStandardDisposableGenericMouseDownListener = function addStandardDisposableListener(node: HTMLElement, handler: (event: any) => void, useCapture?: boolean): IDisposable { + let wrapHandler = _wrapAsStandardMouseEvent(handler); return addDisposableGenericMouseDownListener(node, wrapHandler, useCapture); }; -export const addStandardDisposableGenericMouseUpListener = function addStandardDisposableListener(node: HTMLElement, handler: (event: any) => void, useCapture?: boolean): IDisposable { - const wrapHandler = _wrapAsStandardMouseEvent(handler); +export let addStandardDisposableGenericMouseUpListener = function addStandardDisposableListener(node: HTMLElement, handler: (event: any) => void, useCapture?: boolean): IDisposable { + let wrapHandler = _wrapAsStandardMouseEvent(handler); return addDisposableGenericMouseUpListener(node, wrapHandler, useCapture); }; @@ -122,6 +122,35 @@ export function addDisposableGenericMouseMoveListener(node: EventTarget, handler export function addDisposableGenericMouseUpListener(node: EventTarget, handler: (event: any) => void, useCapture?: boolean): IDisposable { return addDisposableListener(node, platform.isIOS && BrowserFeatures.pointerEvents ? EventType.POINTER_UP : EventType.MOUSE_UP, handler, useCapture); } +export function addDisposableNonBubblingMouseOutListener(node: Element, handler: (event: MouseEvent) => void): IDisposable { + return addDisposableListener(node, 'mouseout', (e: MouseEvent) => { + // Mouse out bubbles, so this is an attempt to ignore faux mouse outs coming from children elements + let toElement: Node | null = (e.relatedTarget); + while (toElement && toElement !== node) { + toElement = toElement.parentNode; + } + if (toElement === node) { + return; + } + + handler(e); + }); +} + +export function addDisposableNonBubblingPointerOutListener(node: Element, handler: (event: MouseEvent) => void): IDisposable { + return addDisposableListener(node, 'pointerout', (e: MouseEvent) => { + // Mouse out bubbles, so this is an attempt to ignore faux mouse outs coming from children elements + let toElement: Node | null = (e.relatedTarget); + while (toElement && toElement !== node) { + toElement = toElement.parentNode; + } + if (toElement === node) { + return; + } + + handler(e); + }); +} export function createEventEmitter(target: HTMLElement, type: K, options?: boolean | AddEventListenerOptions): event.Emitter { let domListener: DomListener | null = null; @@ -229,7 +258,7 @@ class AnimationFrameQueueItem implements IDisposable { */ let inAnimationFrameRunner = false; - const animationFrameRunner = () => { + let animationFrameRunner = () => { animFrameRequested = false; CURRENT_QUEUE = NEXT_QUEUE; @@ -238,14 +267,14 @@ class AnimationFrameQueueItem implements IDisposable { inAnimationFrameRunner = true; while (CURRENT_QUEUE.length > 0) { CURRENT_QUEUE.sort(AnimationFrameQueueItem.sort); - const top = CURRENT_QUEUE.shift()!; + let top = CURRENT_QUEUE.shift()!; top.execute(); } inAnimationFrameRunner = false; }; scheduleAtNextAnimationFrame = (runner: () => void, priority: number = 0) => { - const item = new AnimationFrameQueueItem(runner, priority); + let item = new AnimationFrameQueueItem(runner, priority); NEXT_QUEUE.push(item); if (!animFrameRequested) { @@ -258,7 +287,7 @@ class AnimationFrameQueueItem implements IDisposable { runAtThisOrScheduleAtNextAnimationFrame = (runner: () => void, priority?: number) => { if (inAnimationFrameRunner) { - const item = new AnimationFrameQueueItem(runner, priority); + let item = new AnimationFrameQueueItem(runner, priority); CURRENT_QUEUE!.push(item); return item; } else { @@ -294,9 +323,9 @@ class TimeoutThrottledDomListener extends Disposable { let lastEvent: R | null = null; let lastHandlerTime = 0; - const timeout = this._register(new TimeoutTimer()); + let timeout = this._register(new TimeoutTimer()); - const invokeHandler = () => { + let invokeHandler = () => { lastHandlerTime = (new Date()).getTime(); handler(lastEvent); lastEvent = null; @@ -305,7 +334,7 @@ class TimeoutThrottledDomListener extends Disposable { this._register(addDisposableListener(node, type, (e) => { lastEvent = eventMerger(lastEvent, e); - const elapsedTime = (new Date()).getTime() - lastHandlerTime; + let elapsedTime = (new Date()).getTime() - lastHandlerTime; if (elapsedTime >= minimumTimeMs) { timeout.cancel(); @@ -363,7 +392,7 @@ class SizeUtils { } private static getDimension(element: HTMLElement, cssPropertyName: string, jsPropertyName: string): number { - const computedStyle: CSSStyleDeclaration = getComputedStyle(element); + let computedStyle: CSSStyleDeclaration = getComputedStyle(element); let value = '0'; if (computedStyle) { if (computedStyle.getPropertyValue) { @@ -539,7 +568,7 @@ export function position(element: HTMLElement, top: number, right?: number, bott * Returns the position of a dom node relative to the entire page. */ export function getDomNodePagePosition(domNode: HTMLElement): IDomNodePagePosition { - const bb = domNode.getBoundingClientRect(); + let bb = domNode.getBoundingClientRect(); return { left: bb.left + StandardWindow.scrollX, top: bb.top + StandardWindow.scrollY, @@ -548,24 +577,6 @@ export function getDomNodePagePosition(domNode: HTMLElement): IDomNodePagePositi }; } -/** - * Returns the effective zoom on a given element before window zoom level is applied - */ -export function getDomNodeZoomLevel(domNode: HTMLElement): number { - let testElement: HTMLElement | null = domNode; - let zoom = 1.0; - do { - const elementZoomLevel = (getComputedStyle(testElement) as any).zoom; - if (elementZoomLevel !== null && elementZoomLevel !== undefined && elementZoomLevel !== '1') { - zoom *= elementZoomLevel; - } - - testElement = testElement.parentElement; - } while (testElement !== null && testElement !== document.documentElement); - - return zoom; -} - export interface IStandardWindow { readonly scrollX: number; readonly scrollY: number; @@ -594,33 +605,33 @@ export const StandardWindow: IStandardWindow = new class implements IStandardWin // Adapted from WinJS // Gets the width of the element, including margins. export function getTotalWidth(element: HTMLElement): number { - const margin = SizeUtils.getMarginLeft(element) + SizeUtils.getMarginRight(element); + let margin = SizeUtils.getMarginLeft(element) + SizeUtils.getMarginRight(element); return element.offsetWidth + margin; } export function getContentWidth(element: HTMLElement): number { - const border = SizeUtils.getBorderLeftWidth(element) + SizeUtils.getBorderRightWidth(element); - const padding = SizeUtils.getPaddingLeft(element) + SizeUtils.getPaddingRight(element); + let border = SizeUtils.getBorderLeftWidth(element) + SizeUtils.getBorderRightWidth(element); + let padding = SizeUtils.getPaddingLeft(element) + SizeUtils.getPaddingRight(element); return element.offsetWidth - border - padding; } export function getTotalScrollWidth(element: HTMLElement): number { - const margin = SizeUtils.getMarginLeft(element) + SizeUtils.getMarginRight(element); + let margin = SizeUtils.getMarginLeft(element) + SizeUtils.getMarginRight(element); return element.scrollWidth + margin; } // Adapted from WinJS // Gets the height of the content of the specified element. The content height does not include borders or padding. export function getContentHeight(element: HTMLElement): number { - const border = SizeUtils.getBorderTopWidth(element) + SizeUtils.getBorderBottomWidth(element); - const padding = SizeUtils.getPaddingTop(element) + SizeUtils.getPaddingBottom(element); + let border = SizeUtils.getBorderTopWidth(element) + SizeUtils.getBorderBottomWidth(element); + let padding = SizeUtils.getPaddingTop(element) + SizeUtils.getPaddingBottom(element); return element.offsetHeight - border - padding; } // Adapted from WinJS // Gets the height of the element, including its margins. export function getTotalHeight(element: HTMLElement): number { - const margin = SizeUtils.getMarginTop(element) + SizeUtils.getMarginBottom(element); + let margin = SizeUtils.getMarginTop(element) + SizeUtils.getMarginBottom(element); return element.offsetHeight + margin; } @@ -630,16 +641,16 @@ function getRelativeLeft(element: HTMLElement, parent: HTMLElement): number { return 0; } - const elementPosition = getTopLeftOffset(element); - const parentPosition = getTopLeftOffset(parent); + let elementPosition = getTopLeftOffset(element); + let parentPosition = getTopLeftOffset(parent); return elementPosition.left - parentPosition.left; } export function getLargestChildWidth(parent: HTMLElement, children: HTMLElement[]): number { - const childWidths = children.map((child) => { + let childWidths = children.map((child) => { return Math.max(getTotalScrollWidth(child), getTotalWidth(child)) + getRelativeLeft(child, parent) || 0; }); - const maxWidth = Math.max(...childWidths); + let maxWidth = Math.max(...childWidths); return maxWidth; } @@ -758,7 +769,7 @@ export function getActiveElement(): Element | null { } export function createStyleSheet(container: HTMLElement = document.getElementsByTagName('head')[0]): HTMLStyleElement { - const style = document.createElement('style'); + let style = document.createElement('style'); style.type = 'text/css'; style.media = 'screen'; container.appendChild(style); @@ -766,7 +777,7 @@ export function createStyleSheet(container: HTMLElement = document.getElementsBy } export function createMetaElement(container: HTMLElement = document.getElementsByTagName('head')[0]): HTMLMetaElement { - const meta = document.createElement('meta'); + let meta = document.createElement('meta'); container.appendChild(meta); return meta; } @@ -804,10 +815,10 @@ export function removeCSSRulesContainingSelector(ruleName: string, style: HTMLSt return; } - const rules = getDynamicStyleSheetRules(style); - const toDelete: number[] = []; + let rules = getDynamicStyleSheetRules(style); + let toDelete: number[] = []; for (let i = 0; i < rules.length; i++) { - const rule = rules[i]; + let rule = rules[i]; if (rule.selectorText.indexOf(ruleName) !== -1) { toDelete.push(i); } @@ -841,7 +852,6 @@ export const EventType = { POINTER_UP: 'pointerup', POINTER_DOWN: 'pointerdown', POINTER_MOVE: 'pointermove', - POINTER_LEAVE: 'pointerleave', CONTEXT_MENU: 'contextmenu', WHEEL: 'wheel', // Keyboard @@ -918,7 +928,7 @@ export interface IFocusTracker extends Disposable { } export function saveParentsScrollTop(node: Element): number[] { - const r: number[] = []; + let r: number[] = []; for (let i = 0; node && node.nodeType === node.ELEMENT_NODE; i++) { r[i] = node.scrollTop; node = node.parentNode; @@ -978,7 +988,7 @@ class FocusTracker extends Disposable implements IFocusTracker { }; this._refreshStateHandler = () => { - const currentNodeHasFocus = FocusTracker.hasFocusWithin(element); + let currentNodeHasFocus = FocusTracker.hasFocusWithin(element); if (currentNodeHasFocus !== hasFocus) { if (hasFocus) { onBlur(); @@ -1038,7 +1048,7 @@ export enum Namespace { } function _$(namespace: Namespace, description: string, attrs?: { [key: string]: any }, ...children: Array): T { - const match = SELECTOR_REGEX.exec(description); + let match = SELECTOR_REGEX.exec(description); if (!match) { throw new Error('Bad use of emmet'); @@ -1046,7 +1056,7 @@ function _$(namespace: Namespace, description: string, attrs? attrs = { ...(attrs || {}) }; - const tagName = match[1] || 'div'; + let tagName = match[1] || 'div'; let result: T; if (namespace !== Namespace.HTML) { @@ -1113,14 +1123,14 @@ export function join(nodes: Node[], separator: Node | string): Node[] { } export function show(...elements: HTMLElement[]): void { - for (const element of elements) { + for (let element of elements) { element.style.display = ''; element.removeAttribute('aria-hidden'); } } export function hide(...elements: HTMLElement[]): void { - for (const element of elements) { + for (let element of elements) { element.style.display = 'none'; element.setAttribute('aria-hidden', 'true'); } @@ -1148,7 +1158,7 @@ export function removeTabIndexAndUpdateFocus(node: HTMLElement): void { // typically never want that, rather put focus to the closest element // in the hierarchy of the parent DOM nodes. if (document.activeElement === node) { - const parentFocusable = findParentWithAttribute(node.parentElement, 'tabIndex'); + let parentFocusable = findParentWithAttribute(node.parentElement, 'tabIndex'); if (parentFocusable) { parentFocusable.focus(); } @@ -1279,7 +1289,7 @@ RemoteAuthorities.setPreferredWebSchema(/^https:/.test(window.location.href) ? ' /** * returns url('...') */ -export function asCSSUrl(uri: URI | null | undefined): string { +export function asCSSUrl(uri: URI): string { if (!uri) { return `url('')`; } @@ -1659,12 +1669,25 @@ export function getCookieValue(name: string): string | undefined { return match ? match.pop() : undefined; } +export const enum ZIndex { + SASH = 35, + SuggestWidget = 40, + Hover = 50, + DragImage = 1000, + MenubarMenuItemsHolder = 2000, // quick-input-widget + ContextView = 2500, + ModalDialog = 2600, + PaneDropOverlay = 10000 +} + + export interface IDragAndDropObserverCallbacks { readonly onDragEnter: (e: DragEvent) => void; readonly onDragLeave: (e: DragEvent) => void; readonly onDrop: (e: DragEvent) => void; readonly onDragEnd: (e: DragEvent) => void; - readonly onDragOver?: (e: DragEvent, dragDuration: number) => void; + + readonly onDragOver?: (e: DragEvent) => void; } export class DragAndDropObserver extends Disposable { @@ -1675,9 +1698,6 @@ export class DragAndDropObserver extends Disposable { // repeadedly. private counter: number = 0; - // Allows to measure the duration of the drag operation. - private dragStartTime = 0; - constructor(private readonly element: HTMLElement, private readonly callbacks: IDragAndDropObserverCallbacks) { super(); @@ -1687,7 +1707,6 @@ export class DragAndDropObserver extends Disposable { private registerListeners(): void { this._register(addDisposableListener(this.element, EventType.DRAG_ENTER, (e: DragEvent) => { this.counter++; - this.dragStartTime = e.timeStamp; this.callbacks.onDragEnter(e); })); @@ -1695,194 +1714,27 @@ export class DragAndDropObserver extends Disposable { this._register(addDisposableListener(this.element, EventType.DRAG_OVER, (e: DragEvent) => { e.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) - this.callbacks.onDragOver?.(e, e.timeStamp - this.dragStartTime); + if (this.callbacks.onDragOver) { + this.callbacks.onDragOver(e); + } })); this._register(addDisposableListener(this.element, EventType.DRAG_LEAVE, (e: DragEvent) => { this.counter--; if (this.counter === 0) { - this.dragStartTime = 0; - this.callbacks.onDragLeave(e); } })); this._register(addDisposableListener(this.element, EventType.DRAG_END, (e: DragEvent) => { this.counter = 0; - this.dragStartTime = 0; - this.callbacks.onDragEnd(e); })); this._register(addDisposableListener(this.element, EventType.DROP, (e: DragEvent) => { this.counter = 0; - this.dragStartTime = 0; - this.callbacks.onDrop(e); })); } } - -export function computeClippingRect(elementOrRect: HTMLElement | DOMRectReadOnly, clipper: HTMLElement) { - const frameRect = (elementOrRect instanceof HTMLElement ? elementOrRect.getBoundingClientRect() : elementOrRect); - const rootRect = clipper.getBoundingClientRect(); - - const top = Math.max(rootRect.top - frameRect.top, 0); - const right = Math.max(frameRect.width - (frameRect.right - rootRect.right), 0); - const bottom = Math.max(frameRect.height - (frameRect.bottom - rootRect.bottom), 0); - const left = Math.max(rootRect.left - frameRect.left, 0); - - return { top, right, bottom, left }; -} - -type HTMLElementAttributeKeys = Partial<{ [K in keyof T]: T[K] extends Function ? never : T[K] extends object ? HTMLElementAttributeKeys : T[K] }>; -type ElementAttributes = HTMLElementAttributeKeys & Record; -type RemoveHTMLElement = T extends HTMLElement ? never : T; -type UnionToIntersection = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; -type ArrayToObj = UnionToIntersection>; -type HHTMLElementTagNameMap = HTMLElementTagNameMap & { '': HTMLDivElement }; - -type TagToElement = T extends `${infer TStart}#${string}` - ? TStart extends keyof HHTMLElementTagNameMap - ? HHTMLElementTagNameMap[TStart] - : HTMLElement - : T extends `${infer TStart}.${string}` - ? TStart extends keyof HHTMLElementTagNameMap - ? HHTMLElementTagNameMap[TStart] - : HTMLElement - : T extends keyof HTMLElementTagNameMap - ? HTMLElementTagNameMap[T] - : HTMLElement; - -type TagToElementAndId = TTag extends `${infer TTag}@${infer TId}` - ? { element: TagToElement; id: TId } - : { element: TagToElement; id: 'root' }; - -type TagToRecord = TagToElementAndId extends { element: infer TElement; id: infer TId } - ? Record<(TId extends string ? TId : never) | 'root', TElement> - : never; - -type Child = HTMLElement | string | Record; -type Children = [] - | [Child] - | [Child, Child] - | [Child, Child, Child] - | [Child, Child, Child, Child] - | [Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child] - | [Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child, Child]; - -const H_REGEX = /(?[\w\-]+)?(?:#(?[\w\-]+))?(?(?:\.(?:[\w\-]+))*)(?:@(?(?:[\w\_])+))?/; - -/** - * A helper function to create nested dom nodes. - * - * - * ```ts - * const elements = h('div.code-view', [ - * h('div.title@title'), - * h('div.container', [ - * h('div.gutter@gutterDiv'), - * h('div@editor'), - * ]), - * ]); - * const editor = createEditor(elements.editor); - * ``` -*/ -export function h - (tag: TTag): - TagToRecord extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; - -export function h - (tag: TTag, children: T): - (ArrayToObj & TagToRecord) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; - -export function h - (tag: TTag, attributes: Partial>>): - TagToRecord extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; - -export function h - (tag: TTag, attributes: Partial>>, children: T): - (ArrayToObj & TagToRecord) extends infer Y ? { [TKey in keyof Y]: Y[TKey] } : never; - -export function h(tag: string, ...args: [] | [attributes: { $: string } & Partial> | Record, children?: any[]] | [children: any[]]): Record { - let attributes: { $?: string } & Partial>; - let children: (Record | HTMLElement)[] | undefined; - - if (Array.isArray(args[0])) { - attributes = {}; - children = args[0]; - } else { - attributes = args[0] as any || {}; - children = args[1]; - } - - const match = H_REGEX.exec(tag); - - if (!match || !match.groups) { - throw new Error('Bad use of h'); - } - - const tagName = match.groups['tag'] || 'div'; - const el = document.createElement(tagName); - - if (match.groups['id']) { - el.id = match.groups['id']; - } - - if (match.groups['class']) { - el.className = match.groups['class'].replace(/\./g, ' ').trim(); - } - - const result: Record = {}; - - if (match.groups['name']) { - result[match.groups['name']] = el; - } - - if (children) { - for (const c of children) { - if (c instanceof HTMLElement) { - el.appendChild(c); - } else if (typeof c === 'string') { - el.append(c); - } else { - Object.assign(result, c); - el.appendChild(c.root); - } - } - } - - for (const [key, value] of Object.entries(attributes)) { - if (key === 'style') { - for (const [cssKey, cssValue] of Object.entries(value)) { - el.style.setProperty( - camelCaseToHyphenCase(cssKey), - typeof cssValue === 'number' ? cssValue + 'px' : '' + cssValue - ); - } - } else if (key === 'tabIndex') { - el.tabIndex = value; - } else { - el.setAttribute(camelCaseToHyphenCase(key), value.toString()); - } - } - - result['root'] = el; - - return result; -} - -function camelCaseToHyphenCase(str: string) { - return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); -} diff --git a/src/vs/base/browser/formattedTextRenderer.ts b/src/vs/base/browser/formattedTextRenderer.ts index 7a37d820c4..c8a8b668d2 100644 --- a/src/vs/base/browser/formattedTextRenderer.ts +++ b/src/vs/base/browser/formattedTextRenderer.ts @@ -8,7 +8,7 @@ import { IMouseEvent } from 'vs/base/browser/mouseEvent'; import { DisposableStore } from 'vs/base/common/lifecycle'; export interface IContentActionHandler { - callback: (content: string, event: IMouseEvent) => void; + callback: (content: string, event?: IMouseEvent) => void; readonly disposables: DisposableStore; } diff --git a/src/vs/base/browser/globalPointerMoveMonitor.ts b/src/vs/base/browser/globalPointerMoveMonitor.ts index 9acd7ece52..95e6f3d16a 100644 --- a/src/vs/base/browser/globalPointerMoveMonitor.ts +++ b/src/vs/base/browser/globalPointerMoveMonitor.ts @@ -6,18 +6,40 @@ import * as dom from 'vs/base/browser/dom'; import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -export interface IPointerMoveCallback { - (event: PointerEvent): void; +export interface IPointerMoveEventData { + leftButton: boolean; + buttons: number; + pageX: number; + pageY: number; +} + +export interface IEventMerger { + (lastEvent: R | null, currentEvent: PointerEvent): R; +} + +export interface IPointerMoveCallback { + (pointerMoveData: R): void; } export interface IOnStopCallback { (browserEvent?: PointerEvent | KeyboardEvent): void; } -export class GlobalPointerMoveMonitor implements IDisposable { +export function standardPointerMoveMerger(lastEvent: IPointerMoveEventData | null, currentEvent: PointerEvent): IPointerMoveEventData { + currentEvent.preventDefault(); + return { + leftButton: (currentEvent.button === 0), + buttons: currentEvent.buttons, + pageX: currentEvent.pageX, + pageY: currentEvent.pageY + }; +} + +export class GlobalPointerMoveMonitor implements IDisposable { private readonly _hooks = new DisposableStore(); - private _pointerMoveCallback: IPointerMoveCallback | null = null; + private _pointerMoveEventMerger: IEventMerger | null = null; + private _pointerMoveCallback: IPointerMoveCallback | null = null; private _onStopCallback: IOnStopCallback | null = null; public dispose(): void { @@ -33,6 +55,7 @@ export class GlobalPointerMoveMonitor implements IDisposable { // Unhook this._hooks.clear(); + this._pointerMoveEventMerger = null; this._pointerMoveCallback = null; const onStopCallback = this._onStopCallback; this._onStopCallback = null; @@ -43,19 +66,21 @@ export class GlobalPointerMoveMonitor implements IDisposable { } public isMonitoring(): boolean { - return !!this._pointerMoveCallback; + return !!this._pointerMoveEventMerger; } public startMonitoring( initialElement: Element, pointerId: number, initialButtons: number, - pointerMoveCallback: IPointerMoveCallback, + pointerMoveEventMerger: IEventMerger, + pointerMoveCallback: IPointerMoveCallback, onStopCallback: IOnStopCallback ): void { if (this.isMonitoring()) { this.stopMonitoring(false); } + this._pointerMoveEventMerger = pointerMoveEventMerger; this._pointerMoveCallback = pointerMoveCallback; this._onStopCallback = onStopCallback; @@ -78,19 +103,18 @@ export class GlobalPointerMoveMonitor implements IDisposable { eventSource = window; } - this._hooks.add(dom.addDisposableListener( + this._hooks.add(dom.addDisposableThrottledListener( eventSource, dom.EventType.POINTER_MOVE, - (e) => { - if (e.buttons !== initialButtons) { + (data: R) => { + if (data.buttons !== initialButtons) { // Buttons state has changed in the meantime this.stopMonitoring(true); return; } - - e.preventDefault(); - this._pointerMoveCallback!(e); - } + this._pointerMoveCallback!(data); + }, + (lastEvent: R | null, currentEvent) => this._pointerMoveEventMerger!(lastEvent, currentEvent) )); this._hooks.add(dom.addDisposableListener( diff --git a/src/vs/base/browser/history.ts b/src/vs/base/browser/history.ts index a78482e249..48fbb8218f 100644 --- a/src/vs/base/browser/history.ts +++ b/src/vs/base/browser/history.ts @@ -3,18 +3,10 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Event } from 'vs/base/common/event'; - export interface IHistoryNavigationWidget { - readonly element: HTMLElement; - showPreviousValue(): void; showNextValue(): void; - onDidFocus: Event; - - onDidBlur: Event; - } diff --git a/src/vs/base/browser/iframe.ts b/src/vs/base/browser/iframe.ts index 5564597f44..baa78fd7b1 100644 --- a/src/vs/base/browser/iframe.ts +++ b/src/vs/base/browser/iframe.ts @@ -27,8 +27,8 @@ function getParentWindowIfSameOrigin(w: Window): Window | null { // Cannot really tell if we have access to the parent window unless we try to access something in it try { - const location = w.location; - const parentLocation = w.parent.location; + let location = w.location; + let parentLocation = w.parent.location; if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) { hasDifferentOriginAncestorFlag = true; return null; @@ -97,7 +97,7 @@ export class IframeUtils { let top = 0, left = 0; - const windowChain = this.getSameOriginWindowChain(); + let windowChain = this.getSameOriginWindowChain(); for (const windowChainEl of windowChain) { @@ -112,7 +112,7 @@ export class IframeUtils { break; } - const boundingRect = windowChainEl.iframeElement.getBoundingClientRect(); + let boundingRect = windowChainEl.iframeElement.getBoundingClientRect(); top += boundingRect.top; left += boundingRect.left; } diff --git a/src/vs/base/browser/indexedDB.ts b/src/vs/base/browser/indexedDB.ts index 7081ff88af..5cb39b4191 100644 --- a/src/vs/base/browser/indexedDB.ts +++ b/src/vs/base/browser/indexedDB.ts @@ -14,13 +14,6 @@ class MissingStoresError extends Error { } } -export class DBClosedError extends Error { - readonly code = 'DBClosed'; - constructor(dbName: string) { - super(`IndexedDB database '${dbName}' is closed.`); - } -} - export class IndexedDB { static async create(name: string, version: number | undefined, stores: string[]): Promise { @@ -28,7 +21,7 @@ export class IndexedDB { return new IndexedDB(database, name); } - private static async openDatabase(name: string, version: number | undefined, stores: string[]): Promise { + static async openDatabase(name: string, version: number | undefined, stores: string[]): Promise { mark(`code/willOpenDatabase/${name}`); try { return await IndexedDB.doOpenDatabase(name, version, stores); @@ -116,7 +109,7 @@ export class IndexedDB { runInTransaction(store: string, transactionMode: IDBTransactionMode, dbRequestFn: (store: IDBObjectStore) => IDBRequest): Promise; async runInTransaction(store: string, transactionMode: IDBTransactionMode, dbRequestFn: (store: IDBObjectStore) => IDBRequest | IDBRequest[]): Promise { if (!this.database) { - throw new DBClosedError(this.name); + throw new Error(`IndexedDB database '${this.name}' is not opened.`); } const transaction = this.database.transaction(store, transactionMode); this.pendingTransactions.push(transaction); @@ -135,7 +128,7 @@ export class IndexedDB { async getKeyValues(store: string, isValid: (value: unknown) => value is V): Promise> { if (!this.database) { - throw new DBClosedError(this.name); + throw new Error(`IndexedDB database '${this.name}' is not opened.`); } const transaction = this.database.transaction(store, 'readonly'); this.pendingTransactions.push(transaction); diff --git a/src/vs/base/browser/keyboardEvent.ts b/src/vs/base/browser/keyboardEvent.ts index dd6441db7e..9bb731a64c 100644 --- a/src/vs/base/browser/keyboardEvent.ts +++ b/src/vs/base/browser/keyboardEvent.ts @@ -13,7 +13,7 @@ import * as platform from 'vs/base/common/platform'; function extractKeyCode(e: KeyboardEvent): KeyCode { if (e.charCode) { // "keypress" events mostly - const char = String.fromCharCode(e.charCode).toUpperCase(); + let char = String.fromCharCode(e.charCode).toUpperCase(); return KeyCodeUtils.fromString(char); } @@ -77,7 +77,7 @@ const shiftKeyMod = KeyMod.Shift; const metaKeyMod = (platform.isMacintosh ? KeyMod.CtrlCmd : KeyMod.WinCtrl); export function printKeyboardEvent(e: KeyboardEvent): string { - const modifiers: string[] = []; + let modifiers: string[] = []; if (e.ctrlKey) { modifiers.push(`ctrl`); } @@ -94,7 +94,7 @@ export function printKeyboardEvent(e: KeyboardEvent): string { } export function printStandardKeyboardEvent(e: StandardKeyboardEvent): string { - const modifiers: string[] = []; + let modifiers: string[] = []; if (e.ctrlKey) { modifiers.push(`ctrl`); } @@ -128,7 +128,7 @@ export class StandardKeyboardEvent implements IKeyboardEvent { private _asRuntimeKeybinding: SimpleKeybinding; constructor(source: KeyboardEvent) { - const e = source; + let e = source; this.browserEvent = e; this.target = e.target; diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts index 86cac17c99..24957ad6fe 100644 --- a/src/vs/base/browser/markdownRenderer.ts +++ b/src/vs/base/browser/markdownRenderer.ts @@ -9,9 +9,11 @@ import { DomEmitter } from 'vs/base/browser/event'; import { createElement, FormattedTextRenderOptions } from 'vs/base/browser/formattedTextRenderer'; import { StandardMouseEvent } from 'vs/base/browser/mouseEvent'; import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels'; +import { raceCancellation } from 'vs/base/common/async'; +import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; -import { IMarkdownString, escapeDoubleQuotes, parseHrefAndDimensions, removeMarkdownEscapes } from 'vs/base/common/htmlContent'; +import { IMarkdownString, parseHrefAndDimensions, removeMarkdownEscapes } from 'vs/base/common/htmlContent'; import { markdownEscapeEscapedIcons } from 'vs/base/common/iconLabels'; import { defaultGenerator } from 'vs/base/common/idGenerator'; import { DisposableStore } from 'vs/base/common/lifecycle'; @@ -42,6 +44,8 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende const disposables = new DisposableStore(); let isDisposed = false; + const cts = disposables.add(new CancellationTokenSource()); + const element = createElement(options); const _uriMassage = function (part: string): string { @@ -92,6 +96,11 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende return uri.toString(); }; + // signal to code-block render that the + // element has been created + let signalInnerHTML: () => void; + const withInnerHTML = new Promise(c => signalInnerHTML = c); + const renderer = new marked.Renderer(); renderer.image = (href: string, title: string, text: string) => { @@ -99,13 +108,13 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende let attributes: string[] = []; if (href) { ({ href, dimensions } = parseHrefAndDimensions(href)); - attributes.push(`src="${escapeDoubleQuotes(href)}"`); + attributes.push(`src="${href}"`); } if (text) { - attributes.push(`alt="${escapeDoubleQuotes(text)}"`); + attributes.push(`alt="${text}"`); } if (title) { - attributes.push(`title="${escapeDoubleQuotes(title)}"`); + attributes.push(`title="${title}"`); } if (dimensions.length) { attributes = attributes.concat(dimensions); @@ -121,30 +130,53 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende if (href === text) { // raw link case text = removeMarkdownEscapes(text); } - - title = typeof title === 'string' ? escapeDoubleQuotes(removeMarkdownEscapes(title)) : ''; + href = _href(href, false); + if (markdown.baseUri) { + href = resolveWithBaseUri(URI.from(markdown.baseUri), href); + } + title = typeof title === 'string' ? removeMarkdownEscapes(title) : ''; href = removeMarkdownEscapes(href); + if ( + !href + || /^data:|javascript:/i.test(href) + || (/^command:/i.test(href) && !markdown.isTrusted) + || /^command:(\/\/\/)?_workbench\.downloadResource/i.test(href) + ) { + // drop the link + return text; - // HTML Encode href - href = href.replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - return `${text}`; + } else { + // HTML Encode href + href = href.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + return `${text}`; + } }; renderer.paragraph = (text): string => { return `

${text}

`; }; - // Will collect [id, renderedElement] tuples - const codeBlocks: Promise<[string, HTMLElement]>[] = []; - if (options.codeBlockRenderer) { renderer.code = (code, lang) => { - const id = defaultGenerator.nextId(); const value = options.codeBlockRenderer!(lang ?? '', code); - codeBlocks.push(value.then(element => [id, element])); + // when code-block rendering is async we return sync + // but update the node with the real result later. + const id = defaultGenerator.nextId(); + raceCancellation(Promise.all([value, withInnerHTML]), cts.token).then(values => { + if (!isDisposed && values) { + const span = element.querySelector(`div[data-code="${id}"]`); + if (span) { + DOM.reset(span, values[0]); + } + options.asyncRenderCallback?.(); + } + }).catch(() => { + // ignore + }); + return `
${escape(code)}
`; }; } @@ -236,45 +268,10 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende } }); - markdownHtmlDoc.body.querySelectorAll('a') - .forEach(a => { - const href = a.getAttribute('href'); // Get the raw 'href' attribute value as text, not the resolved 'href' - a.setAttribute('href', ''); // Clear out href. We use the `data-href` for handling clicks instead - if ( - !href - || /^data:|javascript:/i.test(href) - || (/^command:/i.test(href) && !markdown.isTrusted) - || /^command:(\/\/\/)?_workbench\.downloadResource/i.test(href) - ) { - // drop the link - a.replaceWith(...a.childNodes); - } else { - let resolvedHref = _href(href, false); - if (markdown.baseUri) { - resolvedHref = resolveWithBaseUri(URI.from(markdown.baseUri), href); - } - a.dataset.href = resolvedHref; - } - }); - element.innerHTML = sanitizeRenderedMarkdown(markdown, markdownHtmlDoc.body.innerHTML) as unknown as string; - if (codeBlocks.length > 0) { - Promise.all(codeBlocks).then((tuples) => { - if (isDisposed) { - return; - } - const renderedElements = new Map(tuples); - const placeholderElements = element.querySelectorAll(`div[data-code]`); - for (const placeholderElement of placeholderElements) { - const renderedElement = renderedElements.get(placeholderElement.dataset['code'] ?? ''); - if (renderedElement) { - DOM.reset(placeholderElement, renderedElement); - } - } - options.asyncRenderCallback?.(); - }); - } + // signal that async code blocks can be now be inserted + signalInnerHTML!(); // signal size changes for image tags if (options.asyncRenderCallback) { @@ -290,6 +287,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende element, dispose: () => { isDisposed = true; + cts.cancel(); disposables.dispose(); } }; diff --git a/src/vs/base/browser/mouseEvent.ts b/src/vs/base/browser/mouseEvent.ts index c18f6fbe5f..95f0d67d27 100644 --- a/src/vs/base/browser/mouseEvent.ts +++ b/src/vs/base/browser/mouseEvent.ts @@ -74,7 +74,7 @@ export class StandardMouseEvent implements IMouseEvent { } // Find the position of the iframe this code is executing in relative to the iframe where the event was captured. - const iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(self, e.view); + let iframeOffsets = IframeUtils.getPositionOfChildWindowRelativeToAncestorWindow(self, e.view); this.posx -= iframeOffsets.left; this.posy -= iframeOffsets.top; } @@ -152,8 +152,8 @@ export class StandardWheelEvent { if (e) { // Old (deprecated) wheel events - const e1 = e; - const e2 = e; + let e1 = e; + let e2 = e; // vertical delta scroll if (typeof e1.wheelDeltaY !== 'undefined') { diff --git a/src/vs/base/browser/touch.ts b/src/vs/base/browser/touch.ts index f30c6dc8e2..7862280764 100644 --- a/src/vs/base/browser/touch.ts +++ b/src/vs/base/browser/touch.ts @@ -146,7 +146,7 @@ export class Gesture extends Disposable { } private onTouchStart(e: TouchEvent): void { - const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. + let timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. if (this.handle) { this.handle.dispose(); @@ -154,7 +154,7 @@ export class Gesture extends Disposable { } for (let i = 0, len = e.targetTouches.length; i < len; i++) { - const touch = e.targetTouches.item(i); + let touch = e.targetTouches.item(i); this.activeTouches[touch.identifier] = { id: touch.identifier, @@ -167,7 +167,7 @@ export class Gesture extends Disposable { rollingPageY: [touch.pageY] }; - const evt = this.newGestureEvent(EventType.Start, touch.target); + let evt = this.newGestureEvent(EventType.Start, touch.target); evt.pageX = touch.pageX; evt.pageY = touch.pageY; this.dispatchEvent(evt); @@ -181,27 +181,27 @@ export class Gesture extends Disposable { } private onTouchEnd(e: TouchEvent): void { - const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. + let timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. - const activeTouchCount = Object.keys(this.activeTouches).length; + let activeTouchCount = Object.keys(this.activeTouches).length; for (let i = 0, len = e.changedTouches.length; i < len; i++) { - const touch = e.changedTouches.item(i); + let touch = e.changedTouches.item(i); if (!this.activeTouches.hasOwnProperty(String(touch.identifier))) { console.warn('move of an UNKNOWN touch', touch); continue; } - const data = this.activeTouches[touch.identifier], + let data = this.activeTouches[touch.identifier], holdTime = Date.now() - data.initialTimeStamp; if (holdTime < Gesture.HOLD_DELAY && Math.abs(data.initialPageX - arrays.tail(data.rollingPageX)) < 30 && Math.abs(data.initialPageY - arrays.tail(data.rollingPageY)) < 30) { - const evt = this.newGestureEvent(EventType.Tap, data.initialTarget); + let evt = this.newGestureEvent(EventType.Tap, data.initialTarget); evt.pageX = arrays.tail(data.rollingPageX); evt.pageY = arrays.tail(data.rollingPageY); this.dispatchEvent(evt); @@ -210,18 +210,18 @@ export class Gesture extends Disposable { && Math.abs(data.initialPageX - arrays.tail(data.rollingPageX)) < 30 && Math.abs(data.initialPageY - arrays.tail(data.rollingPageY)) < 30) { - const evt = this.newGestureEvent(EventType.Contextmenu, data.initialTarget); + let evt = this.newGestureEvent(EventType.Contextmenu, data.initialTarget); evt.pageX = arrays.tail(data.rollingPageX); evt.pageY = arrays.tail(data.rollingPageY); this.dispatchEvent(evt); } else if (activeTouchCount === 1) { - const finalX = arrays.tail(data.rollingPageX); - const finalY = arrays.tail(data.rollingPageY); + let finalX = arrays.tail(data.rollingPageX); + let finalY = arrays.tail(data.rollingPageY); - const deltaT = arrays.tail(data.rollingTimestamps) - data.rollingTimestamps[0]; - const deltaX = finalX - data.rollingPageX[0]; - const deltaY = finalY - data.rollingPageY[0]; + let deltaT = arrays.tail(data.rollingTimestamps) - data.rollingTimestamps[0]; + let deltaX = finalX - data.rollingPageX[0]; + let deltaY = finalY - data.rollingPageY[0]; // We need to get all the dispatch targets on the start of the inertia event const dispatchTo = this.targets.filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget)); @@ -249,7 +249,7 @@ export class Gesture extends Disposable { } private newGestureEvent(type: string, initialTarget?: EventTarget): GestureEvent { - const event = document.createEvent('CustomEvent') as unknown as GestureEvent; + let event = document.createEvent('CustomEvent') as unknown as GestureEvent; event.initEvent(type, false, true); event.initialTarget = initialTarget; event.tapCount = 0; @@ -289,12 +289,12 @@ export class Gesture extends Disposable { private inertia(dispatchTo: EventTarget[], t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void { this.handle = DomUtils.scheduleAtNextAnimationFrame(() => { - const now = Date.now(); + let now = Date.now(); // velocity: old speed + accel_over_time - const deltaT = now - t1; - let delta_pos_x = 0, delta_pos_y = 0; - let stopped = true; + let deltaT = now - t1, + delta_pos_x = 0, delta_pos_y = 0, + stopped = true; vX += Gesture.SCROLL_FRICTION * deltaT; vY += Gesture.SCROLL_FRICTION * deltaT; @@ -310,7 +310,7 @@ export class Gesture extends Disposable { } // dispatch translation event - const evt = this.newGestureEvent(EventType.Change); + let evt = this.newGestureEvent(EventType.Change); evt.translationX = delta_pos_x; evt.translationY = delta_pos_y; dispatchTo.forEach(d => d.dispatchEvent(evt)); @@ -322,20 +322,20 @@ export class Gesture extends Disposable { } private onTouchMove(e: TouchEvent): void { - const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. + let timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based. for (let i = 0, len = e.changedTouches.length; i < len; i++) { - const touch = e.changedTouches.item(i); + let touch = e.changedTouches.item(i); if (!this.activeTouches.hasOwnProperty(String(touch.identifier))) { console.warn('end of an UNKNOWN touch', touch); continue; } - const data = this.activeTouches[touch.identifier]; + let data = this.activeTouches[touch.identifier]; - const evt = this.newGestureEvent(EventType.Change, data.initialTarget); + let evt = this.newGestureEvent(EventType.Change, data.initialTarget); evt.translationX = touch.pageX - arrays.tail(data.rollingPageX); evt.translationY = touch.pageY - arrays.tail(data.rollingPageY); evt.pageX = touch.pageX; diff --git a/src/vs/base/browser/ui/actionbar/actionViewItems.ts b/src/vs/base/browser/ui/actionbar/actionViewItems.ts index a4fe9f3df5..af5ca1f46d 100644 --- a/src/vs/base/browser/ui/actionbar/actionViewItems.ts +++ b/src/vs/base/browser/ui/actionbar/actionViewItems.ts @@ -9,8 +9,6 @@ import { $, addDisposableListener, append, EventHelper, EventLike, EventType } f import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch'; import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar'; import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; -import { IHoverDelegate } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; -import { ICustomHover, setupCustomHover } from 'vs/base/browser/ui/iconLabel/iconLabelHover'; import { ISelectBoxOptions, ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; import { Action, ActionRunner, IAction, IActionChangeEvent, IActionRunner, Separator } from 'vs/base/common/actions'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -23,7 +21,6 @@ export interface IBaseActionViewItemOptions { draggable?: boolean; isMenu?: boolean; useEventAsContext?: boolean; - hoverDelegate?: IHoverDelegate; } export class BaseActionViewItem extends Disposable implements IActionViewItem { @@ -31,9 +28,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem { element: HTMLElement | undefined; _context: unknown; - readonly _action: IAction; - - private customHover?: ICustomHover; + _action: IAction; get action() { return this._action; @@ -218,27 +213,8 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem { // implement in subclass } - protected getTooltip(): string | undefined { - return this.getAction().tooltip; - } - protected updateTooltip(): void { - if (!this.element) { - return; - } - const title = this.getTooltip() ?? ''; - this.element.setAttribute('aria-label', title); - if (!this.options.hoverDelegate) { - this.element.title = title; - } else { - this.element.title = ''; - if (!this.customHover) { - this.customHover = setupCustomHover(this.options.hoverDelegate, this.element, title); - this._store.add(this.customHover); - } else { - this.customHover.update(title); - } - } + // implement in subclass } protected updateClass(): void { @@ -347,7 +323,7 @@ export class ActionViewItem extends BaseActionViewItem { } } - override getTooltip() { + override updateTooltip(): void { let title: string | null = null; if (this.getAction().tooltip) { @@ -360,7 +336,11 @@ export class ActionViewItem extends BaseActionViewItem { title = nls.localize({ key: 'titleLabel', comment: ['action title', 'action keybinding'] }, "{0} ({1})", title, this.options.keybinding); } } - return title ?? undefined; + + if (title && this.label) { + this.label.title = title; + this.label.setAttribute('aria-label', title); + } } override updateClass(): void { @@ -392,7 +372,9 @@ export class ActionViewItem extends BaseActionViewItem { this.updateEnabled(); } else { - this.label?.classList.remove('codicon'); + if (this.label) { + this.label.classList.remove('codicon'); + } } } @@ -403,14 +385,18 @@ export class ActionViewItem extends BaseActionViewItem { this.label.classList.remove('disabled'); } - this.element?.classList.remove('disabled'); + if (this.element) { + this.element.classList.remove('disabled'); + } } else { if (this.label) { this.label.setAttribute('aria-disabled', 'true'); this.label.classList.add('disabled'); } - this.element?.classList.add('disabled'); + if (this.element) { + this.element.classList.add('disabled'); + } } } diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index d1a3bff9a8..3fd79799a4 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -6,7 +6,6 @@ import * as DOM from 'vs/base/browser/dom'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { ActionViewItem, BaseActionViewItem, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems'; -import { IHoverDelegate } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate'; import { ActionRunner, IAction, IActionRunner, IRunEvent, Separator } from 'vs/base/common/actions'; import { Emitter } from 'vs/base/common/event'; import { KeyCode, KeyMod } from 'vs/base/common/keyCodes'; @@ -50,7 +49,6 @@ export interface IActionBarOptions { readonly allowContextMenu?: boolean; readonly preventLoopNavigation?: boolean; readonly focusOnlyEnabledItems?: boolean; - readonly hoverDelegate?: IHoverDelegate; } export interface IActionOptions extends IActionViewItemOptions { @@ -329,7 +327,7 @@ export class ActionBar extends Disposable implements IActionRunner { } if (!item) { - item = new ActionViewItem(this.context, action, { hoverDelegate: this.options.hoverDelegate, ...options }); + item = new ActionViewItem(this.context, action, options); } // Prevent native context menu on actions diff --git a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts index 642145c356..60d1ed117a 100644 --- a/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts +++ b/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.ts @@ -170,7 +170,7 @@ export class BreadcrumbsWidget { } domFocus(): void { - const idx = this._focusedItemIdx >= 0 ? this._focusedItemIdx : this._items.length - 1; + let idx = this._focusedItemIdx >= 0 ? this._focusedItemIdx : this._items.length - 1; if (idx >= 0 && idx < this._items.length) { this._focus(idx, undefined); } else { @@ -226,7 +226,7 @@ export class BreadcrumbsWidget { } reveal(item: BreadcrumbsItem): void { - const idx = this._items.indexOf(item); + let idx = this._items.indexOf(item); if (idx >= 0) { this._reveal(idx, false); } @@ -281,7 +281,7 @@ export class BreadcrumbsWidget { dispose(removed); this._focus(-1, undefined); } catch (e) { - const newError = new Error(`BreadcrumbsItem#setItems: newItems: ${items.length}, prefix: ${prefix}, removed: ${removed.length}`); + let newError = new Error(`BreadcrumbsItem#setItems: newItems: ${items.length}, prefix: ${prefix}, removed: ${removed.length}`); newError.name = e.name; newError.stack = e.stack; throw newError; @@ -291,8 +291,8 @@ export class BreadcrumbsWidget { private _render(start: number): void { let didChange = false; for (; start < this._items.length && start < this._nodes.length; start++) { - const item = this._items[start]; - const node = this._nodes[start]; + let item = this._items[start]; + let node = this._nodes[start]; this._renderItem(item, node); didChange = true; } @@ -308,8 +308,8 @@ export class BreadcrumbsWidget { // case b: more items -> render them for (; start < this._items.length; start++) { - const item = this._items[start]; - const node = this._freeNodes.length > 0 ? this._freeNodes.pop() : document.createElement('div'); + let item = this._items[start]; + let node = this._freeNodes.length > 0 ? this._freeNodes.pop() : document.createElement('div'); if (node) { this._renderItem(item, node); this._domNode.appendChild(node); @@ -343,7 +343,7 @@ export class BreadcrumbsWidget { return; } for (let el: HTMLElement | null = event.target; el; el = el.parentElement) { - const idx = this._nodes.indexOf(el as HTMLDivElement); + let idx = this._nodes.indexOf(el as HTMLDivElement); if (idx >= 0) { this._focus(idx, event); this._select(idx, event); diff --git a/src/vs/base/browser/ui/button/button.css b/src/vs/base/browser/ui/button/button.css index 3781de7daa..71a2f6a8af 100644 --- a/src/vs/base/browser/ui/button/button.css +++ b/src/vs/base/browser/ui/button/button.css @@ -38,36 +38,8 @@ cursor: pointer; } -.monaco-button-dropdown.disabled { - cursor: default; -} - -.monaco-button-dropdown > .monaco-button:focus { - outline-offset: -1px !important; -} - -.monaco-button-dropdown.disabled > .monaco-button.disabled, -.monaco-button-dropdown.disabled > .monaco-button.disabled:focus, -.monaco-button-dropdown.disabled > .monaco-button-dropdown-separator { - opacity: 0.4 !important; -} - -.monaco-button-dropdown > .monaco-button.monaco-text-button { - border-right-width: 0 !important; -} - -.monaco-button-dropdown .monaco-button-dropdown-separator { - padding: 4px 0; - cursor: default; -} - -.monaco-button-dropdown .monaco-button-dropdown-separator > div { - height: 100%; - width: 1px; -} - -.monaco-button-dropdown > .monaco-button.monaco-dropdown-button { - border-left-width: 0 !important; +.monaco-button-dropdown > .monaco-dropdown-button { + margin-left: 1px; } .monaco-description-button { diff --git a/src/vs/base/browser/ui/button/button.ts b/src/vs/base/browser/ui/button/button.ts index cfaa963689..7786d3ef55 100644 --- a/src/vs/base/browser/ui/button/button.ts +++ b/src/vs/base/browser/ui/button/button.ts @@ -15,7 +15,6 @@ import { Emitter, Event as BaseEvent } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { mixin } from 'vs/base/common/objects'; -import { localize } from 'vs/nls'; import 'vs/css!./button'; export interface IButtonOptions extends IButtonStyles { @@ -28,7 +27,6 @@ export interface IButtonStyles { buttonBackground?: Color; buttonHoverBackground?: Color; buttonForeground?: Color; - buttonSeparator?: Color; buttonSecondaryBackground?: Color; buttonSecondaryHoverBackground?: Color; buttonSecondaryForeground?: Color; @@ -43,7 +41,6 @@ export interface IButtonStyles { const defaultOptions: IButtonStyles = { buttonBackground: Color.fromHex('#0E639C'), buttonHoverBackground: Color.fromHex('#006BB3'), - buttonSeparator: Color.white, buttonForeground: Color.white }; @@ -157,8 +154,8 @@ export class Button extends Disposable implements IButton { // Also set hover background when button is focused for feedback this.focusTracker = this._register(trackFocus(this._element)); - this._register(this.focusTracker.onDidFocus(() => { if (this.enabled) { this.setHoverBackground(); } })); - this._register(this.focusTracker.onDidBlur(() => { if (this.enabled) { this.applyStyles(); } })); + this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground())); + this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles this.applyStyles(); } @@ -320,7 +317,6 @@ export interface IButtonWithDropdownOptions extends IButtonOptions { readonly contextMenuProvider: IContextMenuProvider; readonly actions: IAction[]; readonly actionRunner?: IActionRunner; - readonly addPrimaryActionToDropdown?: boolean; } export class ButtonWithDropdown extends Disposable implements IButton { @@ -328,8 +324,6 @@ export class ButtonWithDropdown extends Disposable implements IButton { private readonly button: Button; private readonly action: Action; private readonly dropdownButton: Button; - private readonly separatorContainer: HTMLDivElement; - private readonly separator: HTMLDivElement; readonly element: HTMLElement; private readonly _onDidClick = this._register(new Emitter()); @@ -346,23 +340,13 @@ export class ButtonWithDropdown extends Disposable implements IButton { this._register(this.button.onDidClick(e => this._onDidClick.fire(e))); this.action = this._register(new Action('primaryAction', this.button.label, undefined, true, async () => this._onDidClick.fire(undefined))); - this.separatorContainer = document.createElement('div'); - this.separatorContainer.classList.add('monaco-button-dropdown-separator'); - - this.separator = document.createElement('div'); - this.separatorContainer.appendChild(this.separator); - this.element.appendChild(this.separatorContainer); - this.dropdownButton = this._register(new Button(this.element, { ...options, title: false, supportIcons: true })); - this.dropdownButton.element.title = localize("button dropdown more actions", 'More Actions...'); - this.dropdownButton.element.setAttribute('aria-haspopup', 'true'); - this.dropdownButton.element.setAttribute('aria-expanded', 'false'); this.dropdownButton.element.classList.add('monaco-dropdown-button'); this.dropdownButton.icon = Codicon.dropDownButton; this._register(this.dropdownButton.onDidClick(e => { options.contextMenuProvider.showContextMenu({ getAnchor: () => this.dropdownButton.element, - getActions: () => options.addPrimaryActionToDropdown === false ? [...options.actions] : [this.action, ...options.actions], + getActions: () => [this.action, ...options.actions], actionRunner: options.actionRunner, onHide: () => this.dropdownButton.element.setAttribute('aria-expanded', 'false') }); @@ -382,8 +366,6 @@ export class ButtonWithDropdown extends Disposable implements IButton { set enabled(enabled: boolean) { this.button.enabled = enabled; this.dropdownButton.enabled = enabled; - - this.element.classList.toggle('disabled', !enabled); } get enabled(): boolean { @@ -393,20 +375,6 @@ export class ButtonWithDropdown extends Disposable implements IButton { style(styles: IButtonStyles): void { this.button.style(styles); this.dropdownButton.style(styles); - - // Separator - const border = styles.buttonBorder ? styles.buttonBorder.toString() : ''; - - this.separatorContainer.style.borderTopWidth = border ? '1px' : ''; - this.separatorContainer.style.borderTopStyle = border ? 'solid' : ''; - this.separatorContainer.style.borderTopColor = border; - - this.separatorContainer.style.borderBottomWidth = border ? '1px' : ''; - this.separatorContainer.style.borderBottomStyle = border ? 'solid' : ''; - this.separatorContainer.style.borderBottomColor = border; - - this.separatorContainer.style.backgroundColor = styles.buttonBackground?.toString() ?? ''; - this.separator.style.backgroundColor = styles.buttonSeparator?.toString() ?? ''; } focus(): void { @@ -430,10 +398,12 @@ export class ButtonWithDescription extends Button implements IButtonWithDescript this._labelElement = document.createElement('div'); this._labelElement.classList.add('monaco-button-label'); + this._labelElement.tabIndex = -1; this._element.appendChild(this._labelElement); this._descriptionElement = document.createElement('div'); this._descriptionElement.classList.add('monaco-button-description'); + this._descriptionElement.tabIndex = -1; this._element.appendChild(this._descriptionElement); } diff --git a/src/vs/base/browser/ui/codicons/codicon/codicon.ttf b/src/vs/base/browser/ui/codicons/codicon/codicon.ttf index 5abfa748fb56c712c19d127f550727acc3fabe59..2f5dbfcc76de9fe983e8eb2b5aaf163e1aa32740 100644 GIT binary patch delta 6977 zcmXBZ3w+OI`v>sPwZm_-vz<50n1(U7vCUy-4mqwl&1sZvW`;S$2+2>9a!6w}d;0fC zQc03bNGeHEkED`R(n+fOmgpdPJo%O;tuV3wRezhsy z4uGr$P&#>L*_^mH+w24a3xT+Ar&cejeBx@(6F^D@aOPUol(LF(8#j;QXTPSLDt^Id zg3nugeUREz&8%5?_K&}B@_ZKoPigh+$z`28{J8)~&H#L~W|l3Sa|#-9C+*{Gxs9Hu>$XTNW7AV)s9vh3^jd{`0CMV-VoC8-Bja>UIUj^2h3q1?GBB zNs1(6i!_xAffT?>fAo`wBwKn(9_~Y?1Ysfe;T!aja?C`mtieNAEG_UCF5`;K$4h9y zGcsF-;T|cKK{8fG%U~HNlcYpOVVe}mMEJlD{=9%-gdh}Q2uB1W5sw5f644C9FdQQ= z5~DE&Noa{=v_fm#g0^Uf_DDkqbVNEjp))ej71_u^F1n#RdLj?`=#2vO#UKpE5DY~L zCgKj1p%PV?hUu7rYRtlH%)y9ZGh1FPtwOEH* ztj7k_;SoHFjrbQH!~gL!kK^Cigr~3-&*C|}fSuTd-Dt!fyo>{Qm0kZDUdJ0agg5aq zKEY{xhO_t*=kOK2!+Cs<3-|#B7x6PL;TQad-@W(~*YIE55FhbKfCNet36>BEl`sjH z2#JwciIaFqkVI)F%_T`%N-JqCZR8e7mA2AO+Dn>rmJG?1Ea@U$rJHn@9@10trML8v zzS2)_l>stDhDxE_Cc|ZfjFe&-BjaU)+%DcqnJRPSPMIt7q(&CVU9wOX$zoY5%j8~J zF89kyc|calYFQ@_ORcPz4N@-~@hQ&Wb9{kOD8^(|U<$^{9Vo|Cl%fbJXoDZ&#R|MA zUJk%GjKfE`E*+&z{P48oN)B$yK=JoV6mF9T(F;Fe8MfnFT$N~~iZA|$EObF1nJo9o zJ#x1!!Di_o>G%Vaq)r}{M`W5zml;wmGi8=kp(zI9Z#>NB_jc^Z5xj-N7=T;RAJKRP zPvA)uVuEx+J;oyj&tr!Onj^ObAK)lifnV_<-o{b<2k+uN9LM`Ofe&yJ$MB9!!Cr~P z5_k}RKs4bq=&2hKa-*&^B)}WOM-owdsNFwl08FXk0|!&4aEh^9Nebg+CCQAOP#kPw zoT8*DW2F-J{i(`5|E5Yw0pm2UJMgQPak}CI3^PNaA7izWhZtun$!46Tq!;6C#YY}y zj^e`)bEiTk<6OlF0cM_pcOhTYD9#cv^A+a{7*2N%dNAIlIETQvpCQgBFpCso85b+g zFfey3&NVPg6x{dkQJjBZmI7XP;8XmcSoGOU{)wR z!+5_E*CHzwr#6@e6x;Vhme1p>?^#Zm$07lpO#e{)%}et@~6SV_SA zs#sIN{H9o4!2GUQXTbcSSaHByRjfT={#2|&V6G|FBQSp{Rwgjl$;$(a6qx_2f9~uC zUlR)#nExr3Ffcb2iy4@|70VizME=17hjpN0sRQeySoFa9DwaR6eu{+=j7{yWzHde7{gN;)x-(cev3pv;X#gYy-QL(s#ZN}ekoAK^B zLTz)!iVwDhV(kZ;q*w*Qwp6SKVUrarL)cb|H6mmlMhznnsA5`ww@iT#I<0d64!#aDRC`Wq{Ox0a3!vFyd!uZam_PQiEExwN?hv{ zD{-wbT8V3gF-qK>k5%ICe4G+@=i`;QyDd@TZgzt5io27EO5B~?uEgER9ZKAtOj6>m zzEp|3_%bE#;>(q|3!bdRU1Wt4cQI3xxC^Ls{a?wucfWM1627-pO5E3`DVf7KUCEt{ zGnC9_tX49Qai)?Q##u@hFwRzT7o$5D$wKzObtfZP#OO{&vY64GjASXJI~mC`#`(%^ z16X%rlI4u<#3c7KE>yCT(Vds%0Y-OTl2wd%la~is%@<3QtYf@K$-|89my^^ox{D=Q z&*(0MWCNqS5R!UEcOk^39_)RJi$2&DipxJ(cY(x(AfJDCg~T->th++u>Jaup#dRXA zyISIk5!PKSaqS4ZMsXDhyH;T=<3oxoOIUY9#5E?YyCLFg6V}~Otvh2WU${FWEc)R&yfsde8#mi58}@^&nhmUVYex` z=j%DeMK$bp#pN~Z^NI^?*c}SX7++9ae8cWkT!zECTPIv)+@-iQ=X3TF-w;w6cPp;f zVH*`!?y!3l*YL0}E3W2Y_bT*Z+^1wR<9;RgF}|Y2jot%F+z@}&al_UP@q-GkXsR8Q-9C3RC_G873 z4%kzQTOP2VC~khho>trjf&J7C9v-+O0((YrZv^%;#a$9uKFJREOJLoDOx!tvJ*&8f z0{f-H1jciU`zo+sDekbqeyzCI0{e~Pt_uf`8(G8+7})O=b}*h-+?0X+UU7Q{_JTqS z#vc^i$=${J+-MrubaB%Yk=-I2BCkhfL={I>M=gn38`TiCBkF)R>Rj~1 z=mpWW(dS}{Viw1&jX4?{5nB*j61zOMK6ZEPvDoWz&EpE@-rq-TiADdzmR_U{nqt6(BGTfe|Y}|{ZI5a z{jc4+dqDhvya9U$+#EP-;Hg2$gBA{YX3*KeIfFM0zBnX$NVg#qhb$SgdB}~SIYSo= zeSGN2!l1&c!p90v-&TIx@uC4m>xTIa%Nw>}*va9s!Ea1!9pDKFlK@W(i4O3DOP98(oh2(Ei{H#niH=K>+-Ohh)UG*MvA_HJg#`79 z3l9wQ3+~$_*iU@I!$V`jBK!gZ{lh~2gMBbe!+d0AEk4$2VYQt4^)> z|Nf}ZB5Nq%}`{iyqr8nfqBH))i6lEUgHtSPCxvL>T$ z)vDHw-nBiNH1?@~qgrw|im$9;c*s{aOT)fSev;w4Z(#ucNZ{{RKBc;P-fhKq zNLKCpB1lI0#6(w2DW5+zeO^u3$I)%!Ad^ToB$fkW?NAQmb8#_cw oa&%O6*`nF=YtrXU;}4b1O|PC(S+lV=Qm*W)jgoBvzMRhf9|a4pfdBvi delta 8457 zcmZYF34B!5*#_|Eog_1vnd~!}$wpR^up|MpvqM1EfXF7YNytKgkVFWJXdMJZML-}3 z)D;maP--buuof*^#ibT4F10QQR;|4^Qna{K5x?i;#m|1f5BT5r&di;ebI!f@ocEkz z^ZxKBj)rf}2~`5J0l=KvMK!G%PYl}xM6LpocFt?MvEler?>+}~tpnaa)L36rH*LqR zNj&x}l{fMU#|+17+&@lT8yB^$=qUc-dwyOA;M~^KQd^TcbMhxZRuT|ay{KkItK+2H z%GdcAnawqe>R+Fp@=-X%;pdZIwze#38)DDs4+)O~f(2WS=R`jW;j!dcGkyG)jz02e zd%7HQbVMC_O%6NSFH2={gN&>NVJT@H*yU|%e_)1V`Mb$K&b@rGyDM^ z7%VMVjDYOKR)nO7IPpC$%WC`%58zjFv&_V5StL`WPUgx~sh1|1Cv)&?nIZGrd%J_7 z6r`aG(lG^7aV@4{24*4)*~mdxG7H^v3`U#2^g8Pz=Lx zT!oPskE<~O*I*9jq7L)05R1@^7PR69EI}KVVi}fW1#ZMj+=QEP3s!}&2J3J;*5fX0 zz(#Ds-PnvRXvaO+jvd&EpW|NKj|cG(cJY{pu^W%z0Dg(ba0tJ}<9Gs3;`co7PvKeo z5zpayoWu)w5ij8kua0y02>-yR_$Mr!$G`9e{*8CYK+Ag`0)((U@s=3M*8DET#rN?#u15`j0|MLhEKNO2fT+r;}l-UUvL_4;w`+5 zcknJ=!>h6wPfG@Fg%d7B!i~S-4g3|UIEK%00sWASB#go@u#dN>vt6Ptx1W%R_8+30 z?pJuD@egm;nCM{W1Kw_PmGow;RlM0?v2QW3pRry^I%9*98yM#)iDqn6yggyfSNMi; zf#NL-YoWqu#wH+SHo|+~TBM|kv02F&#uml999FC1{SM1~IiZwsv0@(pYl&iS0IN;0 zUx2k#v4?=QOkprWu$J=yvD<*PLa_sZb)!OnaiwCX0_!Hl?giG(iXQ{Zd?85>##vkn`7`G|>n(-bbGZ?ok zcBr?+-pvjb)+35tE37?=oh+NLX(u4wbOp zR2(#6y`?yO!uqS?Knm+^#UT~e-xLQ|SnsG1$5~kKDvr3Y-cuZVVZE<73d1_1I3C0L zKyhS-byjhVhILMHw1)Me;QKxLV11^TCBQnbm@mNkm%%wu3(R?KK%{h*lJa5z-Va$t*Mz60B#nEAjCQ_O*2hbv}72-y*QKunBaI~7wT z*e=Cn33jA1>9XxsOrT(U6;mnLQHn_w>}bXG3U-WQq6IrvG3A0C*NN@_0(asS^Dx*6 ziWwPfpJHwX+plnzF;OvJgB?)J++YV4b2!*ZirF0OWW~G=c8X$#2RoJDZ>O^Myg2MM z#k3E07sUh+cDiCJ2s=YDDTJM=m>$B;QcM(KXDg)VxB8sd=RmQ}ez`OwIc#$>aTR_vZr=Q}Y2zOw9)> zF*P5g#ME}M5>wkDN=yxhDls*zQerAKOo^$~a3!WvR~c-7F|`_@#MEk}5>u;DN=&Ur zD=~!}qr?<)tP)emY9*$SHpcl%e#U5yBe{ifp)$9S-K1m{ z<056|>vpq}HHc%zbSj4PFFXS|6*+{g~@+^pn2MpILg`x#A5NgiM{g(Z2A(bSaWAx2YEl1CU< zE6(>|n_3fRey~lgiE}{Mw<*pBdH@AA(P}rvVh%-{yrum3-Q`n~Y zh_h7K_bAR+VVkBT&Rk)emLwcy+^J+k`}EYD&}=?3?MZl_(X=Oti_x?viK&ulPZD$G z>{6Wn!hTrcAmeT&!x==I@l43*<>9<|6vNVJ=&9f{rVg=6Omd{&7$6@OG>PSJBpmN7oBWI1E#BsV1H#(Y7^jf^iUF*oK*O3aP< zvf?rY>^~_kSipWoVI1S16&EpJpHeVa>8pwh8?awfQ@O?g`!5QnR;Lx$Jz&4CxB>$E z4aKz(*l#MXiokwLaeV~#Ulqo*k53PVOuM|JxM~9XUB&ei*zYN>q`)?pJ)ws2jN<<*zSzw=4TycSYPI2u8_J@kAFtGowU@n}GfF5QeF?{f`;u;O?PZTm4|Dkv*$7BRU zTlmOQT*HBFE3W3i?oeFUf&H1{3J>h_ifcWv|E0L<1N(yF`VZ{S6<2~_f1$W01pD8L zt3$9a0@KZg3q`QMR9rHG{gvY45$vxO%xU~aaX|_8e-zBM`mN$36YTF4Zf(DuQ5<3w z%qj}F=7bJWTzx_ZFK2`6Q0U;zX>dgf9pQ>=Q|O3LT%|&XQ*pft9qgqHu3VubQgICn z9d5Uq-hir4SW^HzGtcxQT-dGGLU^B(q|iHeG9joKM?D(b^%PxOlD1JU2a z6vtG@?2fqyn+x<;gRX4l-LOZjLW}VJDpFJRZW%gs)@8yioIoUO# z>wvDubE|US%A1(?PJY+?#{5g&`gMD+`_%3idMxg7sK;|XJw1zhPVaed&l3gd1>*}2 z6?7D)6wWC;QFx&!rf6o-s-p9~hWA?4>rk)Dy^r?(w9oiHM~gkh)x|4|w-z5LezEvM ziNB=0WOB*klFgx#eI+ML&Xim#^_LcuHk9rzy;xRSHm&T*veRYf%h#6QU;cFYg^I}) ziz}Y1xKNp1Sy#Ef@<8RYmFN5V`ws8Br|;AK{QU;?TiNe$zc2dd^`F*%UH=pP&kV>O zFlNAO13d%R4m>sJ@E~h&+ThiL_YS@|Wa^N|hFlyvYUqh7e^o=(%~c1hLSGE)F|2CX zf??~2S;NzZ@4L!*RpV9nUS*94jJSEk!4aoN_82*0N4+_Z69$DJPc&G>@x4db61|JBvSS3fBrAaB1BPaKpJYn*($tOaS&rV60GIh!)QzNHVO$E7EF9PW_IA&%(OuKw7+MUXYA$P4~h z^4%U+$nA*@Mu(?4U2$FV{8QW>htst(Axewxoal`8=E_p1%NxCVTl77y60L+JMS8*_ z64T?l$H#Z^1p?juT~nhSTf)Sb;P+`A;;Wsk!}~6mCwksJ(f2szr^>J&{HZb_)~1*> z`LU^8KQ@0L=qkz28z>d#q_}eYtVBKwZd%?YL3uSXwX>O%#WcG=ZeWuu(&zHJ+31Oq z*V*DXi97o8*AfvIex-pElihA@_OPgf{^XQ^uX`Y&v(*!06HJS{JKu5SgPvz%+viUx z9K&^xR&mA5gNZb$+ z?uhhyT;7;ik2fw5ofwD@cON<4|2}6;&@8(8N`i@b`DHnYjDw}bnV93^qx`a9=VuNQ zetg>xd|i>*YQbpBC**%Fgg*iOaLf?QGoc$?6v7_LRGNx%aR1Wn?Eg zqtoJpSx2g?y2KpWGU1N&Q1}lVbNRbY3Sv3>WSC5^A~9G}QP#`R`PDgP6*(*f_Y+IX zN?aw0ITfz_iX3x6_m{++?7Y(Q{=zG!(zib$qB15ox9|QnxxQTfn>A~euUm9dWmH^T zl-uo3P4!nMMR&Vltk1VErZOU-@4m5Pb8|z!yu7i#pYu2l6~5H`G#mcXGX-0k-LpAnvxQPPGe~1GiX^{C zvYoLScvtz;B||C(Iry8Z!|n2Z(7&VK4o134-Cd9 zto`w|i{?O}{kwI=?E`P?7QeoyF(_kFf*Hr{JGc#rUDg-6=lJ){KQ~c zMPlAicH~vhZ|uJD(8e78?Y{9!^T%;v${e3)G7IyL5+2Wbm+@*0Rs<7c*$493UX{Me zp(A4=#=1w2Fx!~Q6U%d!^Iu&-%rlJmlErc-XPq@rYxO<59=nV|&H?cp5XezNx8jNmI>|#=^Rm zHqTEF!_98Q+@_l5g~wiX@W;_CU+w(GwN3SfOBU7eJq`1ln(FJK{`th1FQK+& z(W3h1w!)>&i|d!PG%c&IJN9_EOmZCS;*vi(2BgoM-&WYVlpnFU{)VOXOWF$OwG_6s z6xKG@G|#JFlJ@^zZmwVcxp diff --git a/src/vs/base/browser/ui/contextview/contextview.css b/src/vs/base/browser/ui/contextview/contextview.css index 22d8b86cb7..73e0627590 100644 --- a/src/vs/base/browser/ui/contextview/contextview.css +++ b/src/vs/base/browser/ui/contextview/contextview.css @@ -5,6 +5,7 @@ .context-view { position: absolute; + z-index: 2500; } .context-view.fixed { @@ -12,5 +13,6 @@ font-family: inherit; font-size: 13px; position: fixed; + z-index: 2500; color: inherit; } diff --git a/src/vs/base/browser/ui/contextview/contextview.ts b/src/vs/base/browser/ui/contextview/contextview.ts index 9e8449d5d8..acc51d4685 100644 --- a/src/vs/base/browser/ui/contextview/contextview.ts +++ b/src/vs/base/browser/ui/contextview/contextview.ts @@ -206,7 +206,7 @@ export class ContextView extends Disposable { this.view.className = 'context-view'; this.view.style.top = '0px'; this.view.style.left = '0px'; - this.view.style.zIndex = '2575'; + this.view.style.zIndex = '2500'; this.view.style.position = this.useFixedPosition ? 'fixed' : 'absolute'; DOM.show(this.view); @@ -220,7 +220,9 @@ export class ContextView extends Disposable { this.doLayout(); // Focus - this.delegate.focus?.(); + if (this.delegate.focus) { + this.delegate.focus(); + } } getViewElement(): HTMLElement { @@ -251,25 +253,20 @@ export class ContextView extends Disposable { } // Get anchor - const anchor = this.delegate!.getAnchor(); + let anchor = this.delegate!.getAnchor(); // Compute around let around: IView; // Get the element's position and size (to anchor the view) if (DOM.isHTMLElement(anchor)) { - const elementPosition = DOM.getDomNodePagePosition(anchor); - - // In areas where zoom is applied to the element or its ancestors, we need to adjust the size of the element - // e.g. The title bar has counter zoom behavior meaning it applies the inverse of zoom level. - // Window Zoom Level: 1.5, Title Bar Zoom: 1/1.5, Size Multiplier: 1.5 - const zoom = DOM.getDomNodeZoomLevel(anchor); + let elementPosition = DOM.getDomNodePagePosition(anchor); around = { - top: elementPosition.top * zoom, - left: elementPosition.left * zoom, - width: elementPosition.width * zoom, - height: elementPosition.height * zoom + top: elementPosition.top, + left: elementPosition.left, + width: elementPosition.width, + height: elementPosition.height }; } else { around = { @@ -362,7 +359,7 @@ export class ContextView extends Disposable { } } -const SHADOW_ROOT_CSS = /* css */ ` +let SHADOW_ROOT_CSS = /* css */ ` :host { all: initial; /* 1st rule so subsequent properties are reset. */ } diff --git a/src/vs/base/browser/ui/dialog/dialog.ts b/src/vs/base/browser/ui/dialog/dialog.ts index 2dc0b2c077..b18a349545 100644 --- a/src/vs/base/browser/ui/dialog/dialog.ts +++ b/src/vs/base/browser/ui/dialog/dialog.ts @@ -165,7 +165,7 @@ export class Dialog extends Disposable { } private getIconAriaLabel(): string { - const typeLabel = nls.localize('dialogInfoMessage', 'Info'); + let typeLabel = nls.localize('dialogInfoMessage', 'Info'); switch (this.options.type) { case 'error': nls.localize('dialogErrorMessage', 'Error'); @@ -427,9 +427,13 @@ export class Dialog extends Disposable { this.element.style.backgroundColor = bgColor?.toString() ?? ''; this.element.style.border = border; - this.buttonBar?.buttons.forEach(button => button.style(style)); + if (this.buttonBar) { + this.buttonBar.buttons.forEach(button => button.style(style)); + } - this.checkbox?.style(style); + if (this.checkbox) { + this.checkbox.style(style); + } if (fgColor && bgColor) { const messageDetailColor = fgColor.transparent(.9); diff --git a/src/vs/base/browser/ui/dropdown/dropdown.ts b/src/vs/base/browser/ui/dropdown/dropdown.ts index b35fd37dff..1ef15a03b8 100644 --- a/src/vs/base/browser/ui/dropdown/dropdown.ts +++ b/src/vs/base/browser/ui/dropdown/dropdown.ts @@ -56,10 +56,8 @@ export class BaseDropdown extends ActionRunner { for (const event of [EventType.MOUSE_DOWN, GestureEventType.Tap]) { this._register(addDisposableListener(this._label, event, e => { - if (e instanceof MouseEvent && (e.detail > 1 || e.button !== 0)) { - // prevent right click trigger to allow separate context menu (https://github.com/microsoft/vscode/issues/151064) - // prevent multiple clicks to open multiple context menus (https://github.com/microsoft/vscode/issues/41363) - return; + if (e instanceof MouseEvent && e.detail > 1) { + return; // prevent multiple clicks to open multiple context menus (https://github.com/microsoft/vscode/issues/41363) } if (this.visible) { diff --git a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts index 7b4bffa10d..0c2051287b 100644 --- a/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts +++ b/src/vs/base/browser/ui/dropdown/dropdownActionViewItem.ts @@ -126,22 +126,9 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem { }; } - this.updateTooltip(); this.updateEnabled(); } - override getTooltip(): string | undefined { - let title: string | null = null; - - if (this.getAction().tooltip) { - title = this.getAction().tooltip; - } else if (this.getAction().label) { - title = this.getAction().label; - } - - return title ?? undefined; - } - override setActionContext(newContext: unknown): void { super.setActionContext(newContext); diff --git a/src/vs/base/browser/ui/findinput/findInput.ts b/src/vs/base/browser/ui/findinput/findInput.ts index 1fed42abf6..24410b29fb 100644 --- a/src/vs/base/browser/ui/findinput/findInput.ts +++ b/src/vs/base/browser/ui/findinput/findInput.ts @@ -6,7 +6,7 @@ import * as dom from 'vs/base/browser/dom'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IMouseEvent } from 'vs/base/browser/mouseEvent'; -import { IToggleStyles, Toggle } from 'vs/base/browser/ui/toggle/toggle'; +import { IToggleStyles } from 'vs/base/browser/ui/toggle/toggle'; import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; import { CaseSensitiveToggle, RegexToggle, WholeWordsToggle } from 'vs/base/browser/ui/findinput/findInputToggles'; import { HistoryInputBox, IInputBoxStyles, IInputValidator, IMessage as InputBoxMessage } from 'vs/base/browser/ui/inputbox/inputBox'; @@ -31,7 +31,6 @@ export interface IFindInputOptions extends IFindInputStyles { readonly appendWholeWordsLabel?: string; readonly appendRegexLabel?: string; readonly history?: string[]; - readonly additionalToggles?: Toggle[]; readonly showHistoryHint?: () => boolean; } @@ -75,7 +74,6 @@ export class FindInput extends Widget { protected regex: RegexToggle; protected wholeWords: WholeWordsToggle; protected caseSensitive: CaseSensitiveToggle; - protected additionalToggles: Toggle[] = []; public domNode: HTMLElement; public inputBox: HistoryInputBox; @@ -211,11 +209,15 @@ export class FindInput extends Widget { this._onCaseSensitiveKeyDown.fire(e); })); + if (this._showOptionButtons) { + this.inputBox.paddingRight = this.caseSensitive.width() + this.wholeWords.width() + this.regex.width(); + } + // Arrow-Key support to navigate between options - const indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode]; + let indexes = [this.caseSensitive.domNode, this.wholeWords.domNode, this.regex.domNode]; this.onkeydown(this.domNode, (event: IKeyboardEvent) => { if (event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Escape)) { - const index = indexes.indexOf(document.activeElement); + let index = indexes.indexOf(document.activeElement); if (index >= 0) { let newIndex: number = -1; if (event.equals(KeyCode.RightArrow)) { @@ -248,37 +250,11 @@ export class FindInput extends Widget { this.controls.appendChild(this.wholeWords.domNode); this.controls.appendChild(this.regex.domNode); - if (!this._showOptionButtons) { - this.caseSensitive.domNode.style.display = 'none'; - this.wholeWords.domNode.style.display = 'none'; - this.regex.domNode.style.display = 'none'; - } - - for (const toggle of options?.additionalToggles ?? []) { - this._register(toggle); - this.controls.appendChild(toggle.domNode); - - this._register(toggle.onChange(viaKeyboard => { - this._onDidOptionChange.fire(viaKeyboard); - if (!viaKeyboard && this.fixFocusOnOptionClickEnabled) { - this.inputBox.focus(); - } - })); - - this.additionalToggles.push(toggle); - } - - if (this.additionalToggles.length > 0) { - this.controls.style.display = 'block'; - } - - this.inputBox.paddingRight = - (this._showOptionButtons ? this.caseSensitive.width() + this.wholeWords.width() + this.regex.width() : 0) - + this.additionalToggles.reduce((r, t) => r + t.width(), 0); - this.domNode.appendChild(this.controls); - parent?.appendChild(this.domNode); + if (parent) { + parent.appendChild(this.domNode); + } this._register(dom.addDisposableListener(this.inputBox.inputElement, 'compositionstart', (e: CompositionEvent) => { this.imeSessionInProgress = true; @@ -308,10 +284,6 @@ export class FindInput extends Widget { this.regex.enable(); this.wholeWords.enable(); this.caseSensitive.enable(); - - for (const toggle of this.additionalToggles) { - toggle.enable(); - } } public disable(): void { @@ -320,10 +292,6 @@ export class FindInput extends Widget { this.regex.disable(); this.wholeWords.disable(); this.caseSensitive.disable(); - - for (const toggle of this.additionalToggles) { - toggle.disable(); - } } public setFocusInputOnOptionClick(value: boolean): void { @@ -390,10 +358,6 @@ export class FindInput extends Widget { this.wholeWords.style(toggleStyles); this.caseSensitive.style(toggleStyles); - for (const toggle of this.additionalToggles) { - toggle.style(toggleStyles); - } - const inputBoxStyles: IInputBoxStyles = { inputBackground: this.inputBackground, inputForeground: this.inputForeground, diff --git a/src/vs/base/browser/ui/findinput/replaceInput.ts b/src/vs/base/browser/ui/findinput/replaceInput.ts index ae34d42d37..62b38bbae3 100644 --- a/src/vs/base/browser/ui/findinput/replaceInput.ts +++ b/src/vs/base/browser/ui/findinput/replaceInput.ts @@ -189,10 +189,10 @@ export class ReplaceInput extends Widget { } // Arrow-Key support to navigate between options - const indexes = [this.preserveCase.domNode]; + let indexes = [this.preserveCase.domNode]; this.onkeydown(this.domNode, (event: IKeyboardEvent) => { if (event.equals(KeyCode.LeftArrow) || event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Escape)) { - const index = indexes.indexOf(document.activeElement); + let index = indexes.indexOf(document.activeElement); if (index >= 0) { let newIndex: number = -1; if (event.equals(KeyCode.RightArrow)) { @@ -218,14 +218,16 @@ export class ReplaceInput extends Widget { }); - const controls = document.createElement('div'); + let controls = document.createElement('div'); controls.className = 'controls'; controls.style.display = this._showOptionButtons ? 'block' : 'none'; controls.appendChild(this.preserveCase.domNode); this.domNode.appendChild(controls); - parent?.appendChild(this.domNode); + if (parent) { + parent.appendChild(this.domNode); + } this.onkeydown(this.inputBox.inputElement, (e) => this._onKeyDown.fire(e)); this.onkeyup(this.inputBox.inputElement, (e) => this._onKeyUp.fire(e)); @@ -359,7 +361,9 @@ export class ReplaceInput extends Widget { } public showMessage(message: InputBoxMessage): void { - this.inputBox?.showMessage(message); + if (this.inputBox) { + this.inputBox.showMessage(message); + } } public clearMessage(): void { diff --git a/src/vs/base/browser/ui/grid/grid.ts b/src/vs/base/browser/ui/grid/grid.ts index 5c00b23928..726b29e1bb 100644 --- a/src/vs/base/browser/ui/grid/grid.ts +++ b/src/vs/base/browser/ui/grid/grid.ts @@ -527,16 +527,6 @@ export class Grid extends Disposable { return this.gridview.resizeView(location, size); } - /** - * Returns whether all other {@link IView views} are at their minimum size. - * - * @param view The reference {@link IView view}. - */ - isViewSizeMaximized(view: T): boolean { - const location = this.getViewLocation(view); - return this.gridview.isViewSizeMaximized(location); - } - /** * Get the size of a {@link IView view}. * @@ -758,16 +748,6 @@ export class SerializableGrid extends Grid { return result; } - /** - * Construct a new {@link SerializableGrid} from a grid descriptor. - * - * @param gridDescriptor A grid descriptor in which leaf nodes point to actual views. - * @returns A new {@link SerializableGrid} instance. - */ - static from(gridDescriptor: GridDescriptor, options: IGridOptions = {}): SerializableGrid { - return SerializableGrid.deserialize(createSerializedGrid(gridDescriptor), { fromJSON: view => view }, options); - } - /** * Useful information in order to proportionally restore view sizes * upon the very first layout call. @@ -796,21 +776,15 @@ export class SerializableGrid extends Grid { } } -export type GridLeafNodeDescriptor = { size?: number; data?: any }; -export type GridBranchNodeDescriptor = { size?: number; groups: GridNodeDescriptor[] }; -export type GridNodeDescriptor = GridBranchNodeDescriptor | GridLeafNodeDescriptor; -export type GridDescriptor = { orientation: Orientation } & GridBranchNodeDescriptor; +export type GridNodeDescriptor = { size?: number; groups?: GridNodeDescriptor[] }; +export type GridDescriptor = { orientation: Orientation; groups?: GridNodeDescriptor[] }; -function isGridBranchNodeDescriptor(nodeDescriptor: GridNodeDescriptor): nodeDescriptor is GridBranchNodeDescriptor { - return !!(nodeDescriptor as GridBranchNodeDescriptor).groups; -} - -export function sanitizeGridNodeDescriptor(nodeDescriptor: GridNodeDescriptor, rootNode: boolean): void { - if (!rootNode && (nodeDescriptor as any).groups && (nodeDescriptor as any).groups.length <= 1) { - (nodeDescriptor as any).groups = undefined; +export function sanitizeGridNodeDescriptor(nodeDescriptor: GridNodeDescriptor, rootNode: boolean): void { + if (!rootNode && nodeDescriptor.groups && nodeDescriptor.groups.length <= 1) { + nodeDescriptor.groups = undefined; } - if (!isGridBranchNodeDescriptor(nodeDescriptor)) { + if (!nodeDescriptor.groups) { return; } @@ -837,11 +811,11 @@ export function sanitizeGridNodeDescriptor(nodeDescriptor: GridNodeDescriptor } } -function createSerializedNode(nodeDescriptor: GridNodeDescriptor): ISerializedNode { - if (isGridBranchNodeDescriptor(nodeDescriptor)) { +function createSerializedNode(nodeDescriptor: GridNodeDescriptor): ISerializedNode { + if (nodeDescriptor.groups) { return { type: 'branch', data: nodeDescriptor.groups.map(c => createSerializedNode(c)), size: nodeDescriptor.size! }; } else { - return { type: 'leaf', data: nodeDescriptor.data, size: nodeDescriptor.size! }; + return { type: 'leaf', data: null, size: nodeDescriptor.size! }; } } @@ -869,7 +843,7 @@ function getDimensions(node: ISerializedNode, orientation: Orientation): { width * Creates a new JSON object from a {@link GridDescriptor}, which can * be deserialized by {@link SerializableGrid.deserialize}. */ -export function createSerializedGrid(gridDescriptor: GridDescriptor): ISerializedGrid { +export function createSerializedGrid(gridDescriptor: GridDescriptor): ISerializedGrid { sanitizeGridNodeDescriptor(gridDescriptor, true); const root = createSerializedNode(gridDescriptor); diff --git a/src/vs/base/browser/ui/grid/gridview.ts b/src/vs/base/browser/ui/grid/gridview.ts index 47d83d510c..e807aaade3 100644 --- a/src/vs/base/browser/ui/grid/gridview.ts +++ b/src/vs/base/browser/ui/grid/gridview.ts @@ -592,10 +592,6 @@ class BranchNode implements ISplitView, IDisposable { this.splitview.resizeView(index, size); } - isChildSizeMaximized(index: number): boolean { - return this.splitview.isViewSizeMaximized(index); - } - distributeViewSizes(recursive = false): void { this.splitview.distributeViewSizes(); @@ -861,7 +857,9 @@ class LeafNode implements ISplitView, IDisposable { set boundarySashes(boundarySashes: IRelativeBoundarySashes) { this._boundarySashes = boundarySashes; - this.view.setBoundarySashes?.(toAbsoluteBoundarySashes(boundarySashes, this.orientation)); + if (this.view.setBoundarySashes) { + this.view.setBoundarySashes(toAbsoluteBoundarySashes(boundarySashes, this.orientation)); + } } layout(size: number, offset: number, ctx: ILayoutContext | undefined): void { @@ -899,7 +897,9 @@ class LeafNode implements ISplitView, IDisposable { } setVisible(visible: boolean): void { - this.view.setVisible?.(visible); + if (this.view.setVisible) { + this.view.setVisible(visible); + } } dispose(): void { @@ -1435,27 +1435,6 @@ export class GridView implements IDisposable { } } - /** - * Returns whether all other {@link IView views} are at their minimum size. - * - * @param location The {@link GridLocation location} of the view. - */ - isViewSizeMaximized(location: GridLocation): boolean { - const [ancestors, node] = this.getNode(location); - - if (!(node instanceof LeafNode)) { - throw new Error('Invalid location'); - } - - for (let i = 0; i < ancestors.length; i++) { - if (!ancestors[i].isChildSizeMaximized(location[i])) { - return false; - } - } - - return true; - } - /** * Distribute the size among all {@link IView views} within the entire * grid or within a single {@link SplitView}. diff --git a/src/vs/base/browser/ui/iconLabel/iconHoverDelegate.ts b/src/vs/base/browser/ui/iconLabel/iconHoverDelegate.ts index 738047d69d..b5415c0f7d 100644 --- a/src/vs/base/browser/ui/iconLabel/iconHoverDelegate.ts +++ b/src/vs/base/browser/ui/iconLabel/iconHoverDelegate.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget'; -import { IUpdatableHoverOptions } from 'vs/base/browser/ui/iconLabel/iconLabelHover'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -13,7 +12,7 @@ export interface IHoverDelegateTarget extends IDisposable { x?: number; } -export interface IHoverDelegateOptions extends IUpdatableHoverOptions { +export interface IHoverDelegateOptions { content: IMarkdownString | string | HTMLElement; target: IHoverDelegateTarget | HTMLElement; hoverPosition?: HoverPosition; diff --git a/src/vs/base/browser/ui/iconLabel/iconLabelHover.ts b/src/vs/base/browser/ui/iconLabel/iconLabelHover.ts index 3079fa99f6..ad6238db67 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabelHover.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabelHover.ts @@ -33,21 +33,6 @@ export function setupNativeHover(htmlElement: HTMLElement, tooltip: string | ITo export type IHoverContent = string | ITooltipMarkdownString | HTMLElement | undefined; type IResolvedHoverContent = IMarkdownString | string | HTMLElement | undefined; -/** - * Copied from src\vs\workbench\services\hover\browser\hover.ts - * @deprecated Use IHoverService - */ -export interface IHoverAction { - label: string; - commandId: string; - iconClass?: string; - run(target: HTMLElement): void; -} - -export interface IUpdatableHoverOptions { - actions?: IHoverAction[]; - linkHandler?(url: string): void; -} export interface ICustomHover extends IDisposable { @@ -64,7 +49,7 @@ export interface ICustomHover extends IDisposable { /** * Updates the contents of the hover. */ - update(tooltip: IHoverContent, options?: IUpdatableHoverOptions): void; + update(tooltip: IHoverContent): void; } @@ -76,7 +61,7 @@ class UpdatableHoverWidget implements IDisposable { constructor(private hoverDelegate: IHoverDelegate, private target: IHoverDelegateTarget | HTMLElement, private fadeInAnimation: boolean) { } - async update(content: IHoverContent, focus?: boolean, options?: IUpdatableHoverOptions): Promise { + async update(content: IHoverContent, focus?: boolean): Promise { if (this._cancellationTokenSource) { // there's an computation ongoing, cancel it this._cancellationTokenSource.dispose(true); @@ -114,10 +99,10 @@ class UpdatableHoverWidget implements IDisposable { } } - this.show(resolvedContent, focus, options); + this.show(resolvedContent, focus); } - private show(content: IResolvedHoverContent, focus?: boolean, options?: IUpdatableHoverOptions): void { + private show(content: IResolvedHoverContent, focus?: boolean): void { const oldHoverWidget = this._hoverWidget; if (this.hasContent(content)) { @@ -126,8 +111,7 @@ class UpdatableHoverWidget implements IDisposable { target: this.target, showPointer: this.hoverDelegate.placement === 'element', hoverPosition: HoverPosition.BELOW, - skipFadeInAnimation: !this.fadeInAnimation || !!oldHoverWidget, // do not fade in if the hover is already showing - ...options + skipFadeInAnimation: !this.fadeInAnimation || !!oldHoverWidget // do not fade in if the hover is already showing }; this._hoverWidget = this.hoverDelegate.showHover(hoverOptions, focus); @@ -158,7 +142,7 @@ class UpdatableHoverWidget implements IDisposable { } } -export function setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTMLElement, content: IHoverContent, options?: IUpdatableHoverOptions): ICustomHover { +export function setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTMLElement, content: IHoverContent): ICustomHover { let hoverPreparation: IDisposable | undefined; let hoverWidget: UpdatableHoverWidget | undefined; @@ -179,7 +163,7 @@ export function setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTM return new TimeoutTimer(async () => { if (!hoverWidget || hoverWidget.isDisposed) { hoverWidget = new UpdatableHoverWidget(hoverDelegate, target || htmlElement, delay > 0); - await hoverWidget.update(content, focus, options); + await hoverWidget.update(content, focus); } }, delay); }; @@ -224,9 +208,9 @@ export function setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTM hide: () => { hideHover(true, true); }, - update: async (newContent, hoverOptions) => { + update: async newContent => { content = newContent; - await hoverWidget?.update(content, undefined, hoverOptions); + await hoverWidget?.update(content); }, dispose: () => { mouseOverDomEmitter.dispose(); diff --git a/src/vs/base/browser/ui/inputbox/inputBox.ts b/src/vs/base/browser/ui/inputbox/inputBox.ts index 60d2591d4d..5384199ba4 100644 --- a/src/vs/base/browser/ui/inputbox/inputBox.ts +++ b/src/vs/base/browser/ui/inputbox/inputBox.ts @@ -171,9 +171,9 @@ export class InputBox extends Widget { this.element = dom.append(container, $('.monaco-inputbox.idle')); - const tagName = this.options.flexibleHeight ? 'textarea' : 'input'; + let tagName = this.options.flexibleHeight ? 'textarea' : 'input'; - const wrapper = dom.append(this.element, $('.ibwrapper')); + let wrapper = dom.append(this.element, $('.ibwrapper')); this.input = dom.append(wrapper, $(tagName + '.input.empty')); this.input.setAttribute('autocorrect', 'off'); this.input.setAttribute('autocapitalize', 'off'); @@ -257,14 +257,14 @@ export class InputBox extends Widget { this.applyStyles(); } - protected onBlur(): void { + private onBlur(): void { this._hideMessage(); if (this.options.showPlaceholderOnFocus) { this.input.setAttribute('placeholder', ''); } } - protected onFocus(): void { + private onFocus(): void { this._showMessage(); if (this.options.showPlaceholderOnFocus) { this.input.setAttribute('placeholder', this.placeholder || ''); @@ -491,7 +491,7 @@ export class InputBox extends Widget { } let div: HTMLElement; - const layout = () => div.style.width = dom.getTotalWidth(this.element) + 'px'; + let layout = () => div.style.width = dom.getTotalWidth(this.element) + 'px'; this.contextViewProvider.showContextView({ getAnchor: () => this.element, @@ -672,19 +672,11 @@ export class HistoryInputBox extends InputBox implements IHistoryNavigationWidge private readonly history: HistoryNavigator; private observer: MutationObserver | undefined; - private readonly _onDidFocus = this._register(new Emitter()); - readonly onDidFocus = this._onDidFocus.event; - - private readonly _onDidBlur = this._register(new Emitter()); - readonly onDidBlur = this._onDidBlur.event; - constructor(container: HTMLElement, contextViewProvider: IContextViewProvider | undefined, options: IHistoryInputOptions) { - super(container, contextViewProvider, options); - const NLS_PLACEHOLDER_HISTORY_HINT = nls.localize({ key: 'history.inputbox.hint', comment: ['Text will be prefixed with \u21C5 plus a single space, then used as a hint where input field keeps history'] }, "for history"); const NLS_PLACEHOLDER_HISTORY_HINT_SUFFIX = ` or \u21C5 ${NLS_PLACEHOLDER_HISTORY_HINT}`; const NLS_PLACEHOLDER_HISTORY_HINT_SUFFIX_IN_PARENS = ` (\u21C5 ${NLS_PLACEHOLDER_HISTORY_HINT})`; - + super(container, contextViewProvider, options); this.history = new HistoryNavigator(options.history, 100); // Function to append the history suffix to the placeholder if necessary @@ -789,16 +781,6 @@ export class HistoryInputBox extends InputBox implements IHistoryNavigationWidge this.history.clear(); } - protected override onBlur(): void { - super.onBlur(); - this._onDidBlur.fire(); - } - - protected override onFocus(): void { - super.onFocus(); - this._onDidFocus.fire(); - } - private getCurrentValue(): string | null { let currentValue = this.history.current(); if (!currentValue) { diff --git a/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts b/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts index 0eb2c54792..d8b8c251c4 100644 --- a/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts +++ b/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts @@ -89,7 +89,7 @@ export class KeybindingLabel implements IThemable { this.clear(); if (this.keybinding) { - const [firstPart, chordPart] = this.keybinding.getParts(); + let [firstPart, chordPart] = this.keybinding.getParts(); if (firstPart) { this.renderPart(this.domNode, firstPart, this.matches ? this.matches.firstPart : null); } diff --git a/src/vs/base/browser/ui/list/list.css b/src/vs/base/browser/ui/list/list.css index 1eee599f26..4c14ad6644 100644 --- a/src/vs/base/browser/ui/list/list.css +++ b/src/vs/base/browser/ui/list/list.css @@ -65,7 +65,72 @@ z-index: 1000; } -/* Filter */ +/* Type filter */ + +.monaco-list-type-filter { + display: flex; + align-items: center; + position: absolute; + border-radius: 2px; + padding: 0px 3px; + max-width: calc(100% - 10px); + text-overflow: ellipsis; + overflow: hidden; + text-align: right; + box-sizing: border-box; + cursor: all-scroll; + font-size: 13px; + line-height: 18px; + height: 20px; + z-index: 1; + top: 4px; +} + +.monaco-list-type-filter.dragging { + transition: top 0.2s, left 0.2s; +} + +.monaco-list-type-filter.ne { + right: 4px; +} + +.monaco-list-type-filter.nw { + left: 4px; +} + +.monaco-list-type-filter > .controls { + display: flex; + align-items: center; + box-sizing: border-box; + transition: width 0.2s; + width: 0; +} + +.monaco-list-type-filter.dragging > .controls, +.monaco-list-type-filter:hover > .controls { + width: 36px; +} + +.monaco-list-type-filter > .controls > * { + border: none; + box-sizing: border-box; + -webkit-appearance: none; + -moz-appearance: none; + background: none; + width: 16px; + height: 16px; + flex-shrink: 0; + margin: 0; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; +} + +.monaco-list-type-filter > .controls > .filter { + margin-left: 4px; +} .monaco-list-type-filter-message { position: absolute; @@ -84,3 +149,13 @@ .monaco-list-type-filter-message:empty { display: none; } + +/* Electron */ + +.monaco-list-type-filter { + cursor: grab; +} + +.monaco-list-type-filter.dragging { + cursor: grabbing; +} diff --git a/src/vs/base/browser/ui/list/listPaging.ts b/src/vs/base/browser/ui/list/listPaging.ts index cd1498ef3d..ff1823b2ce 100644 --- a/src/vs/base/browser/ui/list/listPaging.ts +++ b/src/vs/base/browser/ui/list/listPaging.ts @@ -12,7 +12,7 @@ import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { IThemable } from 'vs/base/common/styler'; import 'vs/css!./list'; import { IListContextMenuEvent, IListEvent, IListMouseEvent, IListRenderer, IListVirtualDelegate } from './list'; -import { IListAccessibilityProvider, IListOptions, IListOptionsUpdate, IListStyles, List, TypeNavigationMode } from './listWidget'; +import { IListAccessibilityProvider, IListOptions, IListOptionsUpdate, IListStyles, List } from './listWidget'; export interface IPagedRenderer extends IListRenderer { renderPlaceholder(index: number, templateData: TTemplateData): void; @@ -95,8 +95,8 @@ class PagedAccessibilityProvider implements IListAccessibilityProvider { - readonly typeNavigationEnabled?: boolean; - readonly typeNavigationMode?: TypeNavigationMode; + readonly enableKeyboardNavigation?: boolean; + readonly automaticKeyboardNavigation?: boolean; readonly ariaLabel?: string; readonly keyboardSupport?: boolean; readonly multipleSelectionSupport?: boolean; @@ -282,8 +282,8 @@ export class PagedList implements IThemable, IDisposable { this.list.layout(height, width); } - triggerTypeNavigation(): void { - this.list.triggerTypeNavigation(); + toggleKeyboardNavigation(): void { + this.list.toggleKeyboardNavigation(); } reveal(index: number, relativeTop?: number): void { diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index decc1896e5..df961e66d4 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -15,6 +15,7 @@ import { Delayer, disposableTimeout } from 'vs/base/common/async'; import { memoize } from 'vs/base/common/decorators'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { getOrDefault } from 'vs/base/common/objects'; import { IRange, Range } from 'vs/base/common/range'; import { INewScrollDimensions, Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable'; import { ISpliceable } from 'vs/base/common/sequence'; @@ -256,7 +257,7 @@ export class ListView implements ISpliceable, IDisposable { private readonly disposables: DisposableStore = new DisposableStore(); private readonly _onDidChangeContentHeight = new Emitter(); - readonly onDidChangeContentHeight: Event = Event.latch(this._onDidChangeContentHeight.event, undefined, this.disposables); + readonly onDidChangeContentHeight: Event = Event.latch(this._onDidChangeContentHeight.event); get contentHeight(): number { return this.rangeMap.size; } get onDidScroll(): Event { return this.scrollableElement.onScroll; } @@ -324,7 +325,7 @@ export class ListView implements ISpliceable, IDisposable { this.domNode.classList.toggle('mouse-support', typeof options.mouseSupport === 'boolean' ? options.mouseSupport : true); - this._horizontalScrolling = options.horizontalScrolling ?? DefaultOptions.horizontalScrolling; + this._horizontalScrolling = getOrDefault(options, o => o.horizontalScrolling, DefaultOptions.horizontalScrolling); this.domNode.classList.toggle('horizontal-scrolling', this._horizontalScrolling); this.additionalScrollHeight = typeof options.additionalScrollHeight === 'undefined' ? 0 : options.additionalScrollHeight; @@ -334,7 +335,7 @@ export class ListView implements ISpliceable, IDisposable { this.rowsContainer = document.createElement('div'); this.rowsContainer.className = 'monaco-list-rows'; - const transformOptimization = options.transformOptimization ?? DefaultOptions.transformOptimization; + const transformOptimization = getOrDefault(options, o => o.transformOptimization, DefaultOptions.transformOptimization); if (transformOptimization) { this.rowsContainer.style.transform = 'translate3d(0px, 0px, 0px)'; } @@ -343,14 +344,14 @@ export class ListView implements ISpliceable, IDisposable { this.scrollable = new Scrollable({ forceIntegerValues: true, - smoothScrollDuration: (options.smoothScrolling ?? false) ? 125 : 0, + smoothScrollDuration: getOrDefault(options, o => o.smoothScrolling, false) ? 125 : 0, scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(cb) }); this.scrollableElement = this.disposables.add(new SmoothScrollableElement(this.rowsContainer, { - alwaysConsumeMouseWheel: options.alwaysConsumeMouseWheel ?? DefaultOptions.alwaysConsumeMouseWheel, + alwaysConsumeMouseWheel: getOrDefault(options, o => o.alwaysConsumeMouseWheel, DefaultOptions.alwaysConsumeMouseWheel), horizontal: ScrollbarVisibility.Auto, - vertical: options.verticalScrollMode ?? DefaultOptions.verticalScrollMode, - useShadows: options.useShadows ?? DefaultOptions.useShadows, + vertical: getOrDefault(options, o => o.verticalScrollMode, DefaultOptions.verticalScrollMode), + useShadows: getOrDefault(options, o => o.useShadows, DefaultOptions.useShadows), mouseWheelScrollSensitivity: options.mouseWheelScrollSensitivity, fastScrollSensitivity: options.fastScrollSensitivity }, this.scrollable)); @@ -370,10 +371,10 @@ export class ListView implements ISpliceable, IDisposable { this.disposables.add(addDisposableListener(this.domNode, 'dragleave', e => this.onDragLeave(this.toDragEvent(e)))); this.disposables.add(addDisposableListener(this.domNode, 'dragend', e => this.onDragEnd(e))); - this.setRowLineHeight = options.setRowLineHeight ?? DefaultOptions.setRowLineHeight; - this.setRowHeight = options.setRowHeight ?? DefaultOptions.setRowHeight; - this.supportDynamicHeights = options.supportDynamicHeights ?? DefaultOptions.supportDynamicHeights; - this.dnd = options.dnd ?? DefaultOptions.dnd; + this.setRowLineHeight = getOrDefault(options, o => o.setRowLineHeight, DefaultOptions.setRowLineHeight); + this.setRowHeight = getOrDefault(options, o => o.setRowHeight, DefaultOptions.setRowHeight); + this.supportDynamicHeights = getOrDefault(options, o => o.supportDynamicHeights, DefaultOptions.supportDynamicHeights); + this.dnd = getOrDefault, IListViewDragAndDrop>(options, o => o.dnd, DefaultOptions.dnd); this.layout(); } @@ -704,7 +705,7 @@ export class ListView implements ISpliceable, IDisposable { } layout(height?: number, width?: number): void { - const scrollDimensions: INewScrollDimensions = { + let scrollDimensions: INewScrollDimensions = { height: typeof height === 'number' ? height : getContentHeight(this.domNode) }; @@ -812,7 +813,9 @@ export class ListView implements ISpliceable, IDisposable { throw new Error(`No renderer found for template id ${item.templateId}`); } - renderer?.renderElement(item.element, index, item.row.templateData, item.size); + if (renderer) { + renderer.renderElement(item.element, index, item.row.templateData, item.size); + } const uri = this.dnd.getDragURI(item.element); item.dragStartDisposable.dispose(); @@ -935,17 +938,17 @@ export class ListView implements ISpliceable, IDisposable { // Events - @memoize get onMouseClick(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'click')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onMouseDblClick(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'dblclick')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onMouseMiddleClick(): Event> { return Event.filter(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'auxclick')).event, e => this.toMouseEvent(e as MouseEvent), this.disposables), e => e.browserEvent.button === 1, this.disposables); } - @memoize get onMouseUp(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseup')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onMouseDown(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousedown')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onMouseOver(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseover')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onMouseMove(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousemove')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onMouseOut(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseout')).event, e => this.toMouseEvent(e), this.disposables); } - @memoize get onContextMenu(): Event | IListGestureEvent> { return Event.any(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'contextmenu')).event, e => this.toMouseEvent(e), this.disposables), Event.map(this.disposables.add(new DomEmitter(this.domNode, TouchEventType.Contextmenu)).event as Event, e => this.toGestureEvent(e), this.disposables)); } - @memoize get onTouchStart(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'touchstart')).event, e => this.toTouchEvent(e), this.disposables); } - @memoize get onTap(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.rowsContainer, TouchEventType.Tap)).event, e => this.toGestureEvent(e as GestureEvent), this.disposables); } + @memoize get onMouseClick(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'click')).event, e => this.toMouseEvent(e)); } + @memoize get onMouseDblClick(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'dblclick')).event, e => this.toMouseEvent(e)); } + @memoize get onMouseMiddleClick(): Event> { return Event.filter(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'auxclick')).event, e => this.toMouseEvent(e as MouseEvent)), e => e.browserEvent.button === 1); } + @memoize get onMouseUp(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseup')).event, e => this.toMouseEvent(e)); } + @memoize get onMouseDown(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousedown')).event, e => this.toMouseEvent(e)); } + @memoize get onMouseOver(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseover')).event, e => this.toMouseEvent(e)); } + @memoize get onMouseMove(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousemove')).event, e => this.toMouseEvent(e)); } + @memoize get onMouseOut(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseout')).event, e => this.toMouseEvent(e)); } + @memoize get onContextMenu(): Event | IListGestureEvent> { return Event.any(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'contextmenu')).event, e => this.toMouseEvent(e)), Event.map(this.disposables.add(new DomEmitter(this.domNode, TouchEventType.Contextmenu)).event as Event, e => this.toGestureEvent(e))); } + @memoize get onTouchStart(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'touchstart')).event, e => this.toTouchEvent(e)); } + @memoize get onTap(): Event> { return Event.map(this.disposables.add(new DomEmitter(this.rowsContainer, TouchEventType.Tap)).event, e => this.toGestureEvent(e as GestureEvent)); } private toMouseEvent(browserEvent: MouseEvent): IListMouseEvent { const index = this.getItemIndexFromEventTarget(browserEvent.target || null); @@ -1029,7 +1032,9 @@ export class ListView implements ISpliceable, IDisposable { this.currentDragData = new ElementsDragAndDropData(elements); StaticDND.CurrentDragAndDropData = new ExternalElementsDragAndDropData(elements); - this.dnd.onDragStart?.(this.currentDragData, event); + if (this.dnd.onDragStart) { + this.dnd.onDragStart(this.currentDragData, event); + } } private onDragOver(event: IListDragEvent): boolean { @@ -1109,7 +1114,9 @@ export class ListView implements ISpliceable, IDisposable { const item = this.items[index]!; item.dropTarget = true; - item.row?.domNode.classList.add('drop-target'); + if (item.row) { + item.row.domNode.classList.add('drop-target'); + } } this.currentDragFeedbackDisposable = toDisposable(() => { @@ -1117,7 +1124,9 @@ export class ListView implements ISpliceable, IDisposable { const item = this.items[index]!; item.dropTarget = false; - item.row?.domNode.classList.remove('drop-target'); + if (item.row) { + item.row.domNode.classList.remove('drop-target'); + } } }); } @@ -1160,7 +1169,9 @@ export class ListView implements ISpliceable, IDisposable { this.currentDragData = undefined; StaticDND.CurrentDragAndDropData = undefined; - this.dnd.onDragEnd?.(event); + if (this.dnd.onDragEnd) { + this.dnd.onDragEnd(event); + } } private clearDragOverFeedback(): void { @@ -1353,7 +1364,7 @@ export class ListView implements ISpliceable, IDisposable { const size = item.size; if (!this.setRowHeight && item.row) { - const newSize = item.row.domNode.offsetHeight; + let newSize = item.row.domNode.offsetHeight; item.size = newSize; item.lastDynamicHeightWidth = this.renderWidth; return newSize - size; @@ -1368,12 +1379,16 @@ export class ListView implements ISpliceable, IDisposable { if (renderer) { renderer.renderElement(item.element, index, row.templateData, undefined); - renderer.disposeElement?.(item.element, index, row.templateData, undefined); + if (renderer.disposeElement) { + renderer.disposeElement(item.element, index, row.templateData, undefined); + } } item.size = row.domNode.offsetHeight; - this.virtualDelegate.setDynamicHeight?.(item.element, item.size); + if (this.virtualDelegate.setDynamicHeight) { + this.virtualDelegate.setDynamicHeight(item.element, item.size); + } item.lastDynamicHeightWidth = this.renderWidth; this.rowsContainer.removeChild(row.domNode); @@ -1414,7 +1429,9 @@ export class ListView implements ISpliceable, IDisposable { if (item.row) { const renderer = this.renderers.get(item.row.templateId); if (renderer) { - renderer.disposeElement?.(item.element, -1, item.row.templateData, undefined); + if (renderer.disposeElement) { + renderer.disposeElement(item.element, -1, item.row.templateData, undefined); + } renderer.disposeTemplate(item.row.templateData); } } diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 0e356c596f..c9fb17f0e8 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -9,7 +9,6 @@ import { DomEmitter, stopEvent } from 'vs/base/browser/event'; import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Gesture } from 'vs/base/browser/touch'; import { alert } from 'vs/base/browser/ui/aria/aria'; -import { IFindInputStyles } from 'vs/base/browser/ui/findinput/findInput'; import { CombinedSpliceable } from 'vs/base/browser/ui/list/splice'; import { ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions'; import { binarySearch, firstOrDefault, range } from 'vs/base/common/arrays'; @@ -259,23 +258,6 @@ export function isMonacoEditor(e: HTMLElement): boolean { return isMonacoEditor(e.parentElement); } -export function isButton(e: HTMLElement): boolean { - if ((e.tagName === 'A' && e.classList.contains('monaco-button')) || - (e.tagName === 'DIV' && e.classList.contains('monaco-button-dropdown'))) { - return true; - } - - if (e.classList.contains('monaco-list')) { - return false; - } - - if (!e.parentElement) { - return false; - } - - return isButton(e.parentElement); -} - class KeyboardController implements IDisposable { private readonly disposables = new DisposableStore(); @@ -283,9 +265,9 @@ class KeyboardController implements IDisposable { @memoize private get onKeyDown(): Event.IChainableEvent { - return this.disposables.add(Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event) + return Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event) .filter(e => !isInputElement(e.target as HTMLElement)) - .map(e => new StandardKeyboardEvent(e))); + .map(e => new StandardKeyboardEvent(e)); } constructor( @@ -385,12 +367,7 @@ class KeyboardController implements IDisposable { } } -export enum TypeNavigationMode { - Automatic, - Trigger -} - -enum TypeNavigationControllerState { +enum TypeLabelControllerState { Idle, Typing } @@ -408,12 +385,12 @@ export const DefaultKeyboardNavigationDelegate = new class implements IKeyboardN } }; -class TypeNavigationController implements IDisposable { +class TypeLabelController implements IDisposable { private enabled = false; - private state: TypeNavigationControllerState = TypeNavigationControllerState.Idle; + private state: TypeLabelControllerState = TypeLabelControllerState.Idle; - private mode = TypeNavigationMode.Automatic; + private automaticKeyboardNavigation = true; private triggered = false; private previouslyFocused = -1; @@ -424,23 +401,26 @@ class TypeNavigationController implements IDisposable { private list: List, private view: ListView, private keyboardNavigationLabelProvider: IKeyboardNavigationLabelProvider, - private keyboardNavigationEventFilter: IKeyboardNavigationEventFilter, private delegate: IKeyboardNavigationDelegate ) { this.updateOptions(list.options); } updateOptions(options: IListOptions): void { - if (options.typeNavigationEnabled ?? true) { + const enableKeyboardNavigation = typeof options.enableKeyboardNavigation === 'undefined' ? true : !!options.enableKeyboardNavigation; + + if (enableKeyboardNavigation) { this.enable(); } else { this.disable(); } - this.mode = options.typeNavigationMode ?? TypeNavigationMode.Automatic; + if (typeof options.automaticKeyboardNavigation !== 'undefined') { + this.automaticKeyboardNavigation = options.automaticKeyboardNavigation; + } } - trigger(): void { + toggle(): void { this.triggered = !this.triggered; } @@ -449,27 +429,21 @@ class TypeNavigationController implements IDisposable { return; } - let typing = false; - - const onChar = this.enabledDisposables.add(Event.chain(this.enabledDisposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)) + const onChar = Event.chain(this.enabledDisposables.add(new DomEmitter(this.view.domNode, 'keydown')).event) .filter(e => !isInputElement(e.target as HTMLElement)) - .filter(() => this.mode === TypeNavigationMode.Automatic || this.triggered) + .filter(() => this.automaticKeyboardNavigation || this.triggered) .map(event => new StandardKeyboardEvent(event)) - .filter(e => typing || this.keyboardNavigationEventFilter(e)) .filter(e => this.delegate.mightProducePrintableCharacter(e)) - .forEach(stopEvent) + .forEach(e => e.preventDefault()) .map(event => event.browserEvent.key) .event; - const onClear = Event.debounce(onChar, () => null, 800, undefined, undefined, this.enabledDisposables); - const onInput = Event.reduce(Event.any(onChar, onClear), (r, i) => i === null ? null : ((r || '') + i), undefined, this.enabledDisposables); + const onClear = Event.debounce(onChar, () => null, 800); + const onInput = Event.reduce(Event.any(onChar, onClear), (r, i) => i === null ? null : ((r || '') + i)); onInput(this.onInput, this, this.enabledDisposables); onClear(this.onClear, this, this.enabledDisposables); - onChar(() => typing = true, undefined, this.enabledDisposables); - onClear(() => typing = false, undefined, this.enabledDisposables); - this.enabled = true; this.triggered = false; } @@ -499,15 +473,15 @@ class TypeNavigationController implements IDisposable { private onInput(word: string | null): void { if (!word) { - this.state = TypeNavigationControllerState.Idle; + this.state = TypeLabelControllerState.Idle; this.triggered = false; return; } const focus = this.list.getFocus(); const start = focus.length > 0 ? focus[0] : 0; - const delta = this.state === TypeNavigationControllerState.Idle ? 1 : 0; - this.state = TypeNavigationControllerState.Typing; + const delta = this.state === TypeLabelControllerState.Idle ? 1 : 0; + this.state = TypeLabelControllerState.Typing; for (let i = 0; i < this.list.length; i++) { const index = (start + i + delta) % this.list.length; @@ -538,7 +512,7 @@ class DOMFocusController implements IDisposable { private list: List, private view: ListView ) { - const onKeyDown = this.disposables.add(Event.chain(this.disposables.add(new DomEmitter(view.domNode, 'keydown')).event)) + const onKeyDown = Event.chain(this.disposables.add(new DomEmitter(view.domNode, 'keydown')).event) .filter(e => !isInputElement(e.target as HTMLElement)) .map(e => new StandardKeyboardEvent(e)); @@ -827,10 +801,6 @@ export class DefaultStyleController implements IStyleController { content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected .codicon { color: ${styles.listActiveSelectionIconForeground}; }`); } - if (styles.listFocusAndSelectionOutline) { - content.push(`.monaco-list${suffix}:focus .monaco-list-row.selected { outline-color: ${styles.listFocusAndSelectionOutline} !important; }`); - } - if (styles.listFocusAndSelectionBackground) { content.push(` .monaco-drag-image, @@ -904,6 +874,22 @@ export class DefaultStyleController implements IStyleController { `); } + if (styles.listFilterWidgetBackground) { + content.push(`.monaco-list-type-filter { background-color: ${styles.listFilterWidgetBackground} }`); + } + + if (styles.listFilterWidgetOutline) { + content.push(`.monaco-list-type-filter { border: 1px solid ${styles.listFilterWidgetOutline}; }`); + } + + if (styles.listFilterWidgetNoMatchesOutline) { + content.push(`.monaco-list-type-filter.no-matches { border: 1px solid ${styles.listFilterWidgetNoMatchesOutline}; }`); + } + + if (styles.listMatchesShadow) { + content.push(`.monaco-list-type-filter { box-shadow: 1px 1px 1px ${styles.listMatchesShadow}; }`); + } + if (styles.tableColumnsBorder) { content.push(` .monaco-table:hover > .monaco-split-view2, @@ -926,13 +912,9 @@ export class DefaultStyleController implements IStyleController { } } -export interface IKeyboardNavigationEventFilter { - (e: StandardKeyboardEvent): boolean; -} - export interface IListOptionsUpdate extends IListViewOptionsUpdate { - readonly typeNavigationEnabled?: boolean; - readonly typeNavigationMode?: TypeNavigationMode; + readonly enableKeyboardNavigation?: boolean; + readonly automaticKeyboardNavigation?: boolean; readonly multipleSelectionSupport?: boolean; } @@ -945,7 +927,6 @@ export interface IListOptions extends IListOptionsUpdate { readonly multipleSelectionController?: IMultipleSelectionController; readonly styleController?: (suffix: string) => IStyleController; readonly accessibilityProvider?: IListAccessibilityProvider; - readonly keyboardNavigationEventFilter?: IKeyboardNavigationEventFilter; // list view options readonly useShadows?: boolean; @@ -962,14 +943,13 @@ export interface IListOptions extends IListOptionsUpdate { readonly alwaysConsumeMouseWheel?: boolean; } -export interface IListStyles extends IFindInputStyles { +export interface IListStyles { listBackground?: Color; listFocusBackground?: Color; listFocusForeground?: Color; listActiveSelectionBackground?: Color; listActiveSelectionForeground?: Color; listActiveSelectionIconForeground?: Color; - listFocusAndSelectionOutline?: Color; listFocusAndSelectionBackground?: Color; listFocusAndSelectionForeground?: Color; listInactiveSelectionBackground?: Color; @@ -987,8 +967,7 @@ export interface IListStyles extends IFindInputStyles { listFilterWidgetBackground?: Color; listFilterWidgetOutline?: Color; listFilterWidgetNoMatchesOutline?: Color; - listFilterWidgetShadow?: Color; - listMatchesShadow?: Color; // {{SQL CARBON EDIT}} + listMatchesShadow?: Color; treeIndentGuidesStroke?: Color; tableColumnsBorder?: Color; tableOddRowsBackgroundColor?: Color; @@ -999,7 +978,6 @@ const defaultStyles: IListStyles = { listActiveSelectionBackground: Color.fromHex('#0E639C'), listActiveSelectionForeground: Color.fromHex('#FFFFFF'), listActiveSelectionIconForeground: Color.fromHex('#FFFFFF'), - listFocusAndSelectionOutline: Color.fromHex('#90C2F9'), listFocusAndSelectionBackground: Color.fromHex('#094771'), listFocusAndSelectionForeground: Color.fromHex('#FFFFFF'), listInactiveSelectionBackground: Color.fromHex('#3F3F46'), @@ -1131,7 +1109,9 @@ class PipelineRenderer implements IListRenderer { let i = 0; for (const renderer of this.renderers) { - renderer.disposeElement?.(element, index, templateData[i], height); + if (renderer.disposeElement) { + renderer.disposeElement(element, index, templateData[i], height); + } i += 1; } @@ -1202,7 +1182,9 @@ class ListViewDragAndDrop implements IListViewDragAndDrop { } onDragStart(data: IDragAndDropData, originalEvent: DragEvent): void { - this.dnd.onDragStart?.(data, originalEvent); + if (this.dnd.onDragStart) { + this.dnd.onDragStart(data, originalEvent); + } } onDragOver(data: IDragAndDropData, targetElement: T, targetIndex: number, originalEvent: DragEvent): boolean | IListDragOverReaction { @@ -1214,7 +1196,9 @@ class ListViewDragAndDrop implements IListViewDragAndDrop { } onDragEnd(originalEvent: DragEvent): void { - this.dnd.onDragEnd?.(originalEvent); + if (this.dnd.onDragEnd) { + this.dnd.onDragEnd(originalEvent); + } } drop(data: IDragAndDropData, targetElement: T, targetIndex: number, originalEvent: DragEvent): void { @@ -1246,7 +1230,7 @@ export class List implements ISpliceable, IThemable, IDisposable { protected view: ListView; private spliceable: ISpliceable; private styleController: IStyleController; - private typeNavigationController?: TypeNavigationController; + private typeLabelController?: TypeLabelController; private accessibilityProvider?: IListAccessibilityProvider; private keyboardController: KeyboardController | undefined; private mouseController: MouseController; @@ -1255,11 +1239,11 @@ export class List implements ISpliceable, IThemable, IDisposable { protected readonly disposables = new DisposableStore(); @memoize get onDidChangeFocus(): Event> { - return Event.map(this.eventBufferer.wrapEvent(this.focus.onChange), e => this.toListEvent(e), this.disposables); + return Event.map(this.eventBufferer.wrapEvent(this.focus.onChange), e => this.toListEvent(e)); } @memoize get onDidChangeSelection(): Event> { - return Event.map(this.eventBufferer.wrapEvent(this.selection.onChange), e => this.toListEvent(e), this.disposables); + return Event.map(this.eventBufferer.wrapEvent(this.selection.onChange), e => this.toListEvent(e)); } get domId(): string { return this.view.domId; } @@ -1286,14 +1270,14 @@ export class List implements ISpliceable, IThemable, IDisposable { @memoize get onContextMenu(): Event> { let didJustPressContextMenuKey = false; - const fromKeyDown = this.disposables.add(Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)) + const fromKeyDown = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event) .map(e => new StandardKeyboardEvent(e)) .filter(e => didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10)) .map(stopEvent) .filter(() => false) .event as Event; - const fromKeyUp = this.disposables.add(Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event)) + const fromKeyUp = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event) .forEach(() => didJustPressContextMenuKey = false) .map(e => new StandardKeyboardEvent(e)) .filter(e => e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10)) @@ -1307,7 +1291,7 @@ export class List implements ISpliceable, IThemable, IDisposable { }) .event; - const fromMouse = this.disposables.add(Event.chain(this.view.onContextMenu)) + const fromMouse = Event.chain(this.view.onContextMenu) .filter(_ => !didJustPressContextMenuKey) .map(({ element, index, browserEvent }) => ({ element, index, anchor: { x: browserEvent.pageX + 1, y: browserEvent.pageY }, browserEvent })) .event; @@ -1345,7 +1329,9 @@ export class List implements ISpliceable, IThemable, IDisposable { if (this.accessibilityProvider) { baseRenderers.push(new AccessibiltyRenderer(this.accessibilityProvider)); - this.accessibilityProvider.onDidChangeActiveDescendant?.(this.onDidChangeActiveDescendant, this, this.disposables); + if (this.accessibilityProvider.onDidChangeActiveDescendant) { + this.accessibilityProvider.onDidChangeActiveDescendant(this.onDidChangeActiveDescendant, this, this.disposables); + } } renderers = renderers.map(r => new PipelineRenderer(r.templateId, [...baseRenderers, r])); @@ -1387,8 +1373,8 @@ export class List implements ISpliceable, IThemable, IDisposable { if (_options.keyboardNavigationLabelProvider) { const delegate = _options.keyboardNavigationDelegate || DefaultKeyboardNavigationDelegate; - this.typeNavigationController = new TypeNavigationController(this, this.view, _options.keyboardNavigationLabelProvider, _options.keyboardNavigationEventFilter ?? (() => true), delegate); - this.disposables.add(this.typeNavigationController); + this.typeLabelController = new TypeLabelController(this, this.view, _options.keyboardNavigationLabelProvider, delegate); + this.disposables.add(this.typeLabelController); } this.mouseController = this.createMouseController(_options); @@ -1413,7 +1399,9 @@ export class List implements ISpliceable, IThemable, IDisposable { updateOptions(optionsUpdate: IListOptionsUpdate = {}): void { this._options = { ...this._options, ...optionsUpdate }; - this.typeNavigationController?.updateOptions(this._options); + if (this.typeLabelController) { + this.typeLabelController.updateOptions(this._options); + } if (this._options.multipleSelectionController !== undefined) { if (this._options.multipleSelectionSupport) { @@ -1529,9 +1517,9 @@ export class List implements ISpliceable, IThemable, IDisposable { this.view.layout(height, width); } - triggerTypeNavigation(): void { - if (this.typeNavigationController) { - this.typeNavigationController.trigger(); + toggleKeyboardNavigation(): void { + if (this.typeLabelController) { + this.typeLabelController.toggle(); } } @@ -1610,25 +1598,20 @@ export class List implements ISpliceable, IThemable, IDisposable { async focusNextPage(browserEvent?: UIEvent, filter?: (element: T) => boolean): Promise { let lastPageIndex = this.view.indexAt(this.view.getScrollTop() + this.view.renderHeight); lastPageIndex = lastPageIndex === 0 ? 0 : lastPageIndex - 1; - const currentlyFocusedElementIndex = this.getFocus()[0]; + const lastPageElement = this.view.element(lastPageIndex); + const currentlyFocusedElement = this.getFocusedElements()[0]; - if (currentlyFocusedElementIndex !== lastPageIndex && (currentlyFocusedElementIndex === undefined || lastPageIndex > currentlyFocusedElementIndex)) { + if (currentlyFocusedElement !== lastPageElement) { const lastGoodPageIndex = this.findPreviousIndex(lastPageIndex, false, filter); - if (lastGoodPageIndex > -1 && currentlyFocusedElementIndex !== lastGoodPageIndex) { + if (lastGoodPageIndex > -1 && currentlyFocusedElement !== this.view.element(lastGoodPageIndex)) { this.setFocus([lastGoodPageIndex], browserEvent); } else { this.setFocus([lastPageIndex], browserEvent); } } else { const previousScrollTop = this.view.getScrollTop(); - let nextpageScrollTop = previousScrollTop + this.view.renderHeight; - if (lastPageIndex > currentlyFocusedElementIndex) { - // scroll last page element to the top only if the last page element is below the focused element - nextpageScrollTop -= this.view.elementHeight(lastPageIndex); - } - - this.view.setScrollTop(nextpageScrollTop); + this.view.setScrollTop(previousScrollTop + this.view.renderHeight - this.view.elementHeight(lastPageIndex)); if (this.view.getScrollTop() !== previousScrollTop) { this.setFocus([]); @@ -1650,12 +1633,13 @@ export class List implements ISpliceable, IThemable, IDisposable { firstPageIndex = this.view.indexAfter(scrollTop - 1); } - const currentlyFocusedElementIndex = this.getFocus()[0]; + const firstPageElement = this.view.element(firstPageIndex); + const currentlyFocusedElement = this.getFocusedElements()[0]; - if (currentlyFocusedElementIndex !== firstPageIndex && (currentlyFocusedElementIndex === undefined || currentlyFocusedElementIndex >= firstPageIndex)) { + if (currentlyFocusedElement !== firstPageElement) { const firstGoodPageIndex = this.findNextIndex(firstPageIndex, false, filter); - if (firstGoodPageIndex > -1 && currentlyFocusedElementIndex !== firstGoodPageIndex) { + if (firstGoodPageIndex > -1 && currentlyFocusedElement !== this.view.element(firstGoodPageIndex)) { this.setFocus([firstGoodPageIndex], browserEvent); } else { this.setFocus([firstPageIndex], browserEvent); @@ -1799,10 +1783,6 @@ export class List implements ISpliceable, IThemable, IDisposable { return this.view.domNode; } - getElementID(index: number): string { - return this.view.getElementDomId(index); - } - style(styles: IListStyles): void { this.styleController.style(styles); } diff --git a/src/vs/base/browser/ui/list/rangeMap.ts b/src/vs/base/browser/ui/list/rangeMap.ts index e8aaa5faaa..450d0e3ccb 100644 --- a/src/vs/base/browser/ui/list/rangeMap.ts +++ b/src/vs/base/browser/ui/list/rangeMap.ts @@ -21,7 +21,7 @@ export interface IRangedGroup { export function groupIntersect(range: IRange, groups: IRangedGroup[]): IRangedGroup[] { const result: IRangedGroup[] = []; - for (const r of groups) { + for (let r of groups) { if (range.start >= r.range.end) { continue; } @@ -62,7 +62,7 @@ export function consolidate(groups: IRangedGroup[]): IRangedGroup[] { const result: IRangedGroup[] = []; let previousGroup: IRangedGroup | null = null; - for (const group of groups) { + for (let group of groups) { const start = group.range.start; const end = group.range.end; const size = group.size; @@ -138,7 +138,7 @@ export class RangeMap { let index = 0; let size = 0; - for (const group of this.groups) { + for (let group of this.groups) { const count = group.range.end - group.range.start; const newSize = size + (count * group.size); @@ -172,7 +172,7 @@ export class RangeMap { let position = 0; let count = 0; - for (const group of this.groups) { + for (let group of this.groups) { const groupCount = group.range.end - group.range.start; const newCount = count + groupCount; diff --git a/src/vs/base/browser/ui/list/rowCache.ts b/src/vs/base/browser/ui/list/rowCache.ts index f6f4f39ce3..70019a71ee 100644 --- a/src/vs/base/browser/ui/list/rowCache.ts +++ b/src/vs/base/browser/ui/list/rowCache.ts @@ -15,7 +15,9 @@ export interface IRow { function removeFromParent(element: HTMLElement): void { try { - element.parentElement?.removeChild(element); + if (element.parentElement) { + element.parentElement.removeChild(element); + } } catch (e) { // this will throw if this happens due to a blur event, nasty business } diff --git a/src/vs/base/browser/ui/menu/menu.ts b/src/vs/base/browser/ui/menu/menu.ts index f8879a6c05..cbe14eede2 100644 --- a/src/vs/base/browser/ui/menu/menu.ts +++ b/src/vs/base/browser/ui/menu/menu.ts @@ -90,13 +90,14 @@ export class Menu extends ActionBar { context: options.context, actionRunner: options.actionRunner, ariaLabel: options.ariaLabel, - ariaRole: 'menu', focusOnlyEnabledItems: true, triggerKeys: { keys: [KeyCode.Enter, ...(isMacintosh || isLinux ? [KeyCode.Space] : [])], keyDown: true } }); this.menuElement = menuElement; + this.actionsList.setAttribute('role', 'menu'); + this.actionsList.tabIndex = 0; this.menuDisposables = this._register(new DisposableStore()); @@ -159,7 +160,7 @@ export class Menu extends ActionBar { } this._register(addDisposableListener(this.domNode, EventType.MOUSE_OUT, e => { - const relatedTarget = e.relatedTarget as HTMLElement; + let relatedTarget = e.relatedTarget as HTMLElement; if (!isAncestor(relatedTarget, this.domNode)) { this.focusedItem = undefined; this.updateFocus(); @@ -210,7 +211,7 @@ export class Menu extends ActionBar { })); - const parentData: ISubMenuData = { + let parentData: ISubMenuData = { parent: this }; @@ -286,13 +287,11 @@ export class Menu extends ActionBar { const fgColor = style.foregroundColor ? `${style.foregroundColor}` : ''; const bgColor = style.backgroundColor ? `${style.backgroundColor}` : ''; const border = style.borderColor ? `1px solid ${style.borderColor}` : ''; - const borderRadius = '5px'; - const shadow = style.shadowColor ? `0 2px 8px ${style.shadowColor}` : ''; + const shadow = style.shadowColor ? `0 2px 4px ${style.shadowColor}` : ''; - container.style.outline = border; - container.style.borderRadius = borderRadius; - container.style.color = fgColor; - container.style.backgroundColor = bgColor; + container.style.border = border; + this.domNode.style.color = fgColor; + this.domNode.style.backgroundColor = bgColor; container.style.boxShadow = shadow; if (this.viewItems) { @@ -341,7 +340,7 @@ export class Menu extends ActionBar { private setFocusedItem(element: HTMLElement): void { for (let i = 0; i < this.actionsList.children.length; i++) { - const elem = this.actionsList.children[i]; + let elem = this.actionsList.children[i]; if (element === elem) { this.focusedItem = i; break; @@ -446,9 +445,9 @@ class BaseMenuActionViewItem extends BaseActionViewItem { // Set mnemonic if (this.options.label && options.enableMnemonics) { - const label = this.getAction().label; + let label = this.getAction().label; if (label) { - const matches = MENU_MNEMONIC_REGEX.exec(label); + let matches = MENU_MNEMONIC_REGEX.exec(label); if (matches) { this.mnemonic = (!!matches[1] ? matches[1] : matches[3]).toLocaleLowerCase(); } @@ -609,7 +608,9 @@ class BaseMenuActionViewItem extends BaseActionViewItem { this.label.innerText = replaceDoubleEscapes(label).trim(); } - this.item?.setAttribute('aria-keyshortcuts', (!!matches[1] ? matches[1] : matches[3]).toLocaleLowerCase()); + if (this.item) { + this.item.setAttribute('aria-keyshortcuts', (!!matches[1] ? matches[1] : matches[3]).toLocaleLowerCase()); + } } else { this.label.innerText = label.replace(/&&/g, '&').trim(); } @@ -690,19 +691,20 @@ class BaseMenuActionViewItem extends BaseActionViewItem { const isSelected = this.element && this.element.classList.contains('focused'); const fgColor = isSelected && this.menuStyle.selectionForegroundColor ? this.menuStyle.selectionForegroundColor : this.menuStyle.foregroundColor; const bgColor = isSelected && this.menuStyle.selectionBackgroundColor ? this.menuStyle.selectionBackgroundColor : undefined; - const outline = isSelected && this.menuStyle.selectionBorderColor ? `1px solid ${this.menuStyle.selectionBorderColor}` : ''; - const outlineOffset = isSelected && this.menuStyle.selectionBorderColor ? `-1px` : ''; + const border = isSelected && this.menuStyle.selectionBorderColor ? `thin solid ${this.menuStyle.selectionBorderColor}` : ''; if (this.item) { this.item.style.color = fgColor ? fgColor.toString() : ''; this.item.style.backgroundColor = bgColor ? bgColor.toString() : ''; - this.item.style.outline = outline; - this.item.style.outlineOffset = outlineOffset; } if (this.check) { this.check.style.color = fgColor ? fgColor.toString() : ''; } + + if (this.container) { + this.container.style.border = border; + } } style(style: IMenuStyles): void { @@ -763,7 +765,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { } this._register(addDisposableListener(this.element, EventType.KEY_UP, e => { - const event = new StandardKeyboardEvent(e); + let event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { EventHelper.stop(e, true); @@ -772,7 +774,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { })); this._register(addDisposableListener(this.element, EventType.KEY_DOWN, e => { - const event = new StandardKeyboardEvent(e); + let event = new StandardKeyboardEvent(e); if (getActiveElement() === this.item) { if (event.equals(KeyCode.RightArrow) || event.equals(KeyCode.Enter)) { @@ -912,7 +914,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { this.submenuContainer.style.top = `${top - viewBox.top}px`; this.submenuDisposables.add(addDisposableListener(this.submenuContainer, EventType.KEY_UP, e => { - const event = new StandardKeyboardEvent(e); + let event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.LeftArrow)) { EventHelper.stop(e, true); @@ -923,7 +925,7 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { })); this.submenuDisposables.add(addDisposableListener(this.submenuContainer, EventType.KEY_DOWN, e => { - const event = new StandardKeyboardEvent(e); + let event = new StandardKeyboardEvent(e); if (event.equals(KeyCode.LeftArrow)) { EventHelper.stop(e, true); } @@ -964,7 +966,9 @@ class SubmenuMenuActionViewItem extends BaseMenuActionViewItem { this.submenuIndicator.style.color = fgColor ? `${fgColor}` : ''; } - this.parentData.submenu?.style(this.menuStyle); + if (this.parentData.submenu) { + this.parentData.submenu.style(this.menuStyle); + } } override dispose(): void { @@ -1008,8 +1012,7 @@ function getMenuWidgetCSS(style: IMenuStyles, isForShadowDom: boolean): string { let result = /* css */` .monaco-menu { font-size: 13px; - border-radius: 5px; - min-width: 160px; + } ${formatRule(Codicon.menuSelection)} @@ -1084,9 +1087,10 @@ ${formatRule(Codicon.menuSubmenu)} .monaco-menu .monaco-action-bar.vertical .action-label.separator { display: block; - border-bottom: 1px solid var(--vscode-menu-separatorBackground); + border-bottom: 1px solid #bbb; padding-top: 1px; - padding: 30px; + margin-left: .8em; + margin-right: .8em; } .monaco-menu .secondary-actions .monaco-action-bar .action-label { @@ -1132,11 +1136,6 @@ ${formatRule(Codicon.menuSubmenu)} position: relative; } -.monaco-menu .monaco-action-bar.vertical .action-menu-item:hover .keybinding, -.monaco-menu .monaco-action-bar.vertical .action-menu-item:focus .keybinding { - opacity: unset; -} - .monaco-menu .monaco-action-bar.vertical .action-label { flex: 1 1 auto; text-decoration: none; @@ -1192,9 +1191,12 @@ ${formatRule(Codicon.menuSubmenu)} } .monaco-menu .monaco-action-bar.vertical .action-label.separator { + padding: 0.5em 0 0 0; + margin-bottom: 0.5em; width: 100%; height: 0px !important; - opacity: 1; + margin-left: .8em !important; + margin-right: .8em !important; } .monaco-menu .monaco-action-bar.vertical .action-label.separator.text { @@ -1236,15 +1238,17 @@ ${formatRule(Codicon.menuSubmenu)} outline: 0; } -.hc-black .context-view.monaco-menu-container, -.hc-light .context-view.monaco-menu-container, +.monaco-menu .monaco-action-bar.vertical .action-item { + border: thin solid transparent; /* prevents jumping behaviour on hover or focus */ +} + + +/* High Contrast Theming */ :host-context(.hc-black) .context-view.monaco-menu-container, :host-context(.hc-light) .context-view.monaco-menu-container { box-shadow: none; } -.hc-black .monaco-menu .monaco-action-bar.vertical .action-item.focused, -.hc-light .monaco-menu .monaco-action-bar.vertical .action-item.focused, :host-context(.hc-black) .monaco-menu .monaco-action-bar.vertical .action-item.focused, :host-context(.hc-light) .monaco-menu .monaco-action-bar.vertical .action-item.focused { background: none; @@ -1253,11 +1257,11 @@ ${formatRule(Codicon.menuSubmenu)} /* Vertical Action Bar Styles */ .monaco-menu .monaco-action-bar.vertical { - padding: .6em 0; + padding: .5em 0; } .monaco-menu .monaco-action-bar.vertical .action-menu-item { - height: 2em; + height: 1.8em; } .monaco-menu .monaco-action-bar.vertical .action-label:not(.separator), @@ -1273,12 +1277,10 @@ ${formatRule(Codicon.menuSubmenu)} .monaco-menu .monaco-action-bar.vertical .action-label.separator { font-size: inherit; - margin: 5px 0 !important; - padding: 0; - border-radius: 0; + padding: 0.2em 0 0 0; + margin-bottom: 0.2em; } -.linux .monaco-menu .monaco-action-bar.vertical .action-label.separator, :host-context(.linux) .monaco-menu .monaco-action-bar.vertical .action-label.separator { margin-left: 0; margin-right: 0; @@ -1289,7 +1291,6 @@ ${formatRule(Codicon.menuSubmenu)} padding: 0 1.8em; } -.linux .monaco-menu .monaco-action-bar.vertical .submenu-indicator { :host-context(.linux) .monaco-menu .monaco-action-bar.vertical .submenu-indicator { height: 100%; mask-size: 10px 10px; diff --git a/src/vs/base/browser/ui/menu/menubar.css b/src/vs/base/browser/ui/menu/menubar.css index 2ea1400009..cb21994180 100644 --- a/src/vs/base/browser/ui/menu/menubar.css +++ b/src/vs/base/browser/ui/menu/menubar.css @@ -9,35 +9,25 @@ display: flex; flex-shrink: 1; box-sizing: border-box; - height: 100%; + height: 30px; overflow: hidden; -} - -.menubar.overflow-menu-only { - width: 38px; + flex-wrap: wrap; } .fullscreen .menubar:not(.compact) { margin: 0px; - padding: 4px 5px; + padding: 0px 5px; } .menubar > .menubar-menu-button { - display: flex; align-items: center; box-sizing: border-box; + padding: 0px 8px; cursor: default; -webkit-app-region: no-drag; zoom: 1; white-space: nowrap; - outline: 0 !important; -} - -.monaco-workbench .menubar:not(.compact) > .menubar-menu-button:focus .menubar-menu-title { - outline-width: 1px; - outline-style: solid; - outline-offset: -1px; - outline-color: var(--vscode-focusBorder); + outline: 0; } .menubar.compact { @@ -51,11 +41,6 @@ padding: 0px; } -.menubar-menu-title { - padding: 0px 8px; - border-radius: 5px; -} - .menubar .menubar-menu-items-holder { position: fixed; left: 0px; @@ -77,13 +62,8 @@ } .menubar .toolbar-toggle-more { - width: 22px; - height: 22px; - padding: 0 8px; - display: flex; - align-items: center; - justify-content: center; - vertical-align: sub; + width: 20px; + height: 100%; } .menubar.compact .toolbar-toggle-more { @@ -97,15 +77,19 @@ justify-content: center; } -.menubar:not(.compact) .menubar-menu-button:first-child .toolbar-toggle-more::before, +.menubar .toolbar-toggle-more { + padding: 0; + vertical-align: sub; +} + .menubar.compact .toolbar-toggle-more::before { content: "\eb94" !important; } /* Match behavior of outline for activity bar icons */ -.menubar.compact > .menubar-menu-button.open .menubar-menu-title, -.menubar.compact > .menubar-menu-button:focus .menubar-menu-title, -.menubar.compact > .menubar-menu-button:hover .menubar-menu-title{ +.menubar.compact > .menubar-menu-button.open, +.menubar.compact > .menubar-menu-button:focus, +.menubar.compact > .menubar-menu-button:hover { outline-width: 1px !important; outline-offset: -8px !important; } diff --git a/src/vs/base/browser/ui/menu/menubar.ts b/src/vs/base/browser/ui/menu/menubar.ts index c8719d01cc..c708528c42 100644 --- a/src/vs/base/browser/ui/menu/menubar.ts +++ b/src/vs/base/browser/ui/menu/menubar.ts @@ -116,7 +116,7 @@ export class MenuBar extends Disposable { this._register(DOM.ModifierKeyEmitter.getInstance().event(this.onModifierKeyToggled, this)); this._register(DOM.addDisposableListener(this.container, DOM.EventType.KEY_DOWN, (e) => { - const event = new StandardKeyboardEvent(e as KeyboardEvent); + let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; const key = !!e.key ? e.key.toLocaleLowerCase() : ''; @@ -154,7 +154,7 @@ export class MenuBar extends Disposable { })); this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_IN, (e) => { - const event = e as FocusEvent; + let event = e as FocusEvent; if (event.relatedTarget) { if (!this.container.contains(event.relatedTarget as HTMLElement)) { @@ -164,7 +164,7 @@ export class MenuBar extends Disposable { })); this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_OUT, (e) => { - const event = e as FocusEvent; + let event = e as FocusEvent; // We are losing focus and there is no related target, e.g. webview case if (!event.relatedTarget) { @@ -204,11 +204,11 @@ export class MenuBar extends Disposable { const menuIndex = this.menus.length; const cleanMenuLabel = cleanMnemonic(menuBarMenu.label); - const mnemonicMatches = MENU_MNEMONIC_REGEX.exec(menuBarMenu.label); + let mnemonicMatches = MENU_MNEMONIC_REGEX.exec(menuBarMenu.label); // Register mnemonics if (mnemonicMatches) { - const mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3]; + let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3]; this.registerMnemonic(this.menus.length, mnemonic); } @@ -225,7 +225,7 @@ export class MenuBar extends Disposable { this.updateLabels(titleElement, buttonElement, menuBarMenu.label); this._register(DOM.addDisposableListener(buttonElement, DOM.EventType.KEY_UP, (e) => { - const event = new StandardKeyboardEvent(e as KeyboardEvent); + let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; if ((event.equals(KeyCode.DownArrow) || event.equals(KeyCode.Enter)) && !this.isOpen) { @@ -313,7 +313,8 @@ export class MenuBar extends Disposable { createOverflowMenu(): void { const label = this.isCompact ? nls.localize('mAppMenu', 'Application Menu') : nls.localize('mMore', 'More'); - const buttonElement = $('div.menubar-menu-button', { 'role': 'menuitem', 'tabindex': this.isCompact ? 0 : -1, 'aria-label': label, 'aria-haspopup': true }); + const title = this.isCompact ? label : undefined; + const buttonElement = $('div.menubar-menu-button', { 'role': 'menuitem', 'tabindex': this.isCompact ? 0 : -1, 'aria-label': label, 'title': title, 'aria-haspopup': true }); const titleElement = $('div.menubar-menu-title.toolbar-toggle-more' + Codicon.menuBarMore.cssSelector, { 'role': 'none', 'aria-hidden': true }); buttonElement.appendChild(titleElement); @@ -321,7 +322,7 @@ export class MenuBar extends Disposable { buttonElement.style.visibility = 'hidden'; this._register(DOM.addDisposableListener(buttonElement, DOM.EventType.KEY_UP, (e) => { - const event = new StandardKeyboardEvent(e as KeyboardEvent); + let event = new StandardKeyboardEvent(e as KeyboardEvent); let eventHandled = true; const triggerKeys = [KeyCode.Enter]; @@ -329,12 +330,7 @@ export class MenuBar extends Disposable { triggerKeys.push(KeyCode.DownArrow); } else { triggerKeys.push(KeyCode.Space); - - if (this.options.compactMode === Direction.Right) { - triggerKeys.push(KeyCode.RightArrow); - } else if (this.options.compactMode === Direction.Left) { - triggerKeys.push(KeyCode.LeftArrow); - } + triggerKeys.push(this.options.compactMode === Direction.Right ? KeyCode.RightArrow : KeyCode.LeftArrow); } if ((triggerKeys.some(k => event.equals(k)) && !this.isOpen)) { @@ -473,11 +469,6 @@ export class MenuBar extends Disposable { return; } - const overflowMenuOnlyClass = 'overflow-menu-only'; - - // Remove overflow only restriction to allow the most space - this.container.classList.toggle(overflowMenuOnlyClass, false); - const sizeAvailable = this.container.offsetWidth; let currentSize = 0; let full = this.isCompact; @@ -485,7 +476,7 @@ export class MenuBar extends Disposable { this.numMenusShown = 0; const showableMenus = this.menus.filter(menu => menu.buttonElement !== undefined && menu.titleElement !== undefined) as (MenuBarMenuWithElements & { titleElement: HTMLElement; buttonElement: HTMLElement })[]; - for (const menuBarMenu of showableMenus) { + for (let menuBarMenu of showableMenus) { if (!full) { const size = menuBarMenu.buttonElement.offsetWidth; if (currentSize + size > sizeAvailable) { @@ -504,18 +495,6 @@ export class MenuBar extends Disposable { } } - - // If below minimium menu threshold, show the overflow menu only as hamburger menu - if (this.numMenusShown - 1 <= showableMenus.length / 2) { - for (const menuBarMenu of showableMenus) { - menuBarMenu.buttonElement.style.visibility = 'hidden'; - } - - full = true; - this.numMenusShown = 0; - currentSize = 0; - } - // Overflow if (this.isCompact) { this.overflowMenu.actions = []; @@ -555,9 +534,6 @@ export class MenuBar extends Disposable { this.container.appendChild(this.overflowMenu.buttonElement); this.overflowMenu.buttonElement.style.visibility = 'hidden'; } - - // If we are only showing the overflow, add this class to avoid taking up space - this.container.classList.toggle(overflowMenuOnlyClass, this.numMenusShown === 0); } private updateLabels(titleElement: HTMLElement, buttonElement: HTMLElement, label: string): void { @@ -566,7 +542,7 @@ export class MenuBar extends Disposable { // Update the button label to reflect mnemonics if (this.options.enableMnemonics) { - const cleanLabel = strings.escape(label); + let cleanLabel = strings.escape(label); // This is global so reset it MENU_ESCAPED_MNEMONIC_REGEX.lastIndex = 0; @@ -593,11 +569,11 @@ export class MenuBar extends Disposable { titleElement.innerText = cleanMenuLabel.replace(/&&/g, '&'); } - const mnemonicMatches = MENU_MNEMONIC_REGEX.exec(label); + let mnemonicMatches = MENU_MNEMONIC_REGEX.exec(label); // Register mnemonics if (mnemonicMatches) { - const mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3]; + let mnemonic = !!mnemonicMatches[1] ? mnemonicMatches[1] : mnemonicMatches[3]; if (this.options.enableMnemonics) { buttonElement.setAttribute('aria-keyshortcuts', 'Alt+' + mnemonic.toLocaleLowerCase()); @@ -764,7 +740,7 @@ export class MenuBar extends Disposable { this._onFocusStateChange.fire(this.focusState >= MenubarState.FOCUSED); } - get isVisible(): boolean { + private get isVisible(): boolean { return this.focusState >= MenubarState.VISIBLE; } @@ -862,7 +838,7 @@ export class MenuBar extends Disposable { if (this.menus) { this.menus.forEach(menuBarMenu => { if (menuBarMenu.titleElement && menuBarMenu.titleElement.children.length) { - const child = menuBarMenu.titleElement.children.item(0) as HTMLElement; + let child = menuBarMenu.titleElement.children.item(0) as HTMLElement; if (child) { child.style.textDecoration = (this.options.alwaysOnMnemonics || visible) ? 'underline' : ''; } @@ -980,7 +956,9 @@ export class MenuBar extends Disposable { } if (this.focusedMenu.holder) { - this.focusedMenu.holder.parentElement?.classList.remove('open'); + if (this.focusedMenu.holder.parentElement) { + this.focusedMenu.holder.parentElement.classList.remove('open'); + } this.focusedMenu.holder.remove(); } @@ -997,7 +975,7 @@ export class MenuBar extends Disposable { const actualMenuIndex = menuIndex >= this.numMenusShown ? MenuBar.OVERFLOW_INDEX : menuIndex; const customMenu = actualMenuIndex === MenuBar.OVERFLOW_INDEX ? this.overflowMenu : this.menus[actualMenuIndex]; - if (!customMenu.actions || !customMenu.buttonElement || !customMenu.titleElement) { + if (!customMenu.actions || !customMenu.buttonElement) { return; } @@ -1005,24 +983,23 @@ export class MenuBar extends Disposable { customMenu.buttonElement.classList.add('open'); - const titleBoundingRect = customMenu.titleElement.getBoundingClientRect(); - const titleBoundingRectZoom = DOM.getDomNodeZoomLevel(customMenu.titleElement); + const buttonBoundingRect = customMenu.buttonElement.getBoundingClientRect(); if (this.options.compactMode === Direction.Right) { - menuHolder.style.top = `${titleBoundingRect.top}px`; - menuHolder.style.left = `${titleBoundingRect.left + this.container.clientWidth}px`; + menuHolder.style.top = `${buttonBoundingRect.top}px`; + menuHolder.style.left = `${buttonBoundingRect.left + this.container.clientWidth}px`; } else if (this.options.compactMode === Direction.Left) { - menuHolder.style.top = `${titleBoundingRect.top}px`; + menuHolder.style.top = `${buttonBoundingRect.top}px`; menuHolder.style.right = `${this.container.clientWidth}px`; menuHolder.style.left = 'auto'; } else { - menuHolder.style.top = `${titleBoundingRect.bottom * titleBoundingRectZoom}px`; - menuHolder.style.left = `${titleBoundingRect.left * titleBoundingRectZoom}px`; + menuHolder.style.top = `${buttonBoundingRect.bottom}px`; + menuHolder.style.left = `${buttonBoundingRect.left}px`; } customMenu.buttonElement.appendChild(menuHolder); - const menuOptions: IMenuOptions = { + let menuOptions: IMenuOptions = { getKeyBinding: this.options.getKeybinding, actionRunner: this.actionRunner, enableMnemonics: this.options.alwaysOnMnemonics || (this.mnemonicsInUse && this.options.enableMnemonics), @@ -1031,7 +1008,7 @@ export class MenuBar extends Disposable { useEventAsContext: true }; - const menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions)); + let menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions)); if (this.menuStyle) { menuWidget.style(this.menuStyle); } diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index d194e90990..fc6be8e6e7 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -17,7 +17,7 @@ import 'vs/css!./sash'; * Allow the sashes to be visible at runtime. * @remark Use for development purposes only. */ -const DEBUG = false; +let DEBUG = false; // DEBUG = Boolean("true"); // done "weirdly" so that a lint warning prevents you from pushing this /** diff --git a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts index 69dded3ba3..93749bf6f1 100644 --- a/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +++ b/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts @@ -5,7 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { createFastDomNode, FastDomNode } from 'vs/base/browser/fastDomNode'; -import { GlobalPointerMoveMonitor } from 'vs/base/browser/globalPointerMoveMonitor'; +import { GlobalPointerMoveMonitor, IPointerMoveEventData, standardPointerMoveMerger } from 'vs/base/browser/globalPointerMoveMonitor'; import { StandardWheelEvent } from 'vs/base/browser/mouseEvent'; import { ScrollbarArrow, ScrollbarArrowOptions } from 'vs/base/browser/ui/scrollbar/scrollbarArrow'; import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState'; @@ -245,7 +245,8 @@ export abstract class AbstractScrollbar extends Widget { e.target, e.pointerId, e.buttons, - (pointerMoveData: PointerEvent) => { + standardPointerMoveMerger, + (pointerMoveData: IPointerMoveEventData) => { const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData); const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition); diff --git a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts index 0cbf432d7b..dc61139d2a 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollableElement.ts @@ -232,7 +232,7 @@ export abstract class AbstractScrollableElement extends Widget { this._setListeningToMouseWheel(this._options.handleMouseWheel); this.onmouseover(this._listenOnDomNode, (e) => this._onMouseOver(e)); - this.onmouseleave(this._listenOnDomNode, (e) => this._onMouseLeave(e)); + this.onnonbubblingmouseout(this._listenOnDomNode, (e) => this._onMouseOut(e)); this._hideTimeout = this._register(new TimeoutTimer()); this._isDragging = false; @@ -525,7 +525,7 @@ export abstract class AbstractScrollableElement extends Widget { this._hide(); } - private _onMouseLeave(e: IMouseEvent): void { + private _onMouseOut(e: IMouseEvent): void { this._mouseIsOver = false; this._hide(); } diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts b/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts index bbcd1c27fa..c594768f78 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts @@ -3,7 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { GlobalPointerMoveMonitor } from 'vs/base/browser/globalPointerMoveMonitor'; +import { GlobalPointerMoveMonitor, standardPointerMoveMerger } from 'vs/base/browser/globalPointerMoveMonitor'; import { Widget } from 'vs/base/browser/ui/widget'; import { IntervalTimer, TimeoutTimer } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; @@ -103,6 +103,7 @@ export class ScrollbarArrow extends Widget { e.target, e.pointerId, e.buttons, + standardPointerMoveMerger, (pointerMoveData) => { /* Intentional empty */ }, () => { this._pointerdownRepeatTimer.cancel(); diff --git a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts index 291f05dd45..563ee0f42a 100644 --- a/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +++ b/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts @@ -103,7 +103,9 @@ export class ScrollbarVisibilityController extends Disposable { // The CSS animation doesn't play otherwise this._revealTimer.setIfNotSet(() => { - this._domNode?.setClassName(this._visibleClassName); + if (this._domNode) { + this._domNode.setClassName(this._visibleClassName); + } }, 0); } @@ -113,6 +115,8 @@ export class ScrollbarVisibilityController extends Disposable { return; } this._isVisible = false; - this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : '')); + if (this._domNode) { + this._domNode.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : '')); + } } } diff --git a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts index 4cf69a9606..cf1872bf40 100644 --- a/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts +++ b/src/vs/base/browser/ui/selectBox/selectBoxCustom.ts @@ -131,10 +131,6 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi this.selectElement.setAttribute('aria-description', this.selectBoxOptions.ariaDescription); } - if (typeof this.selectBoxOptions.ariaDescription === 'string') { - this.selectElement.setAttribute('aria-description', this.selectBoxOptions.ariaDescription); - } - this._onDidSelect = new Emitter(); this._register(this._onDidSelect); @@ -173,8 +169,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi this.selectionDetailsPane = dom.append(this.selectDropDownContainer, $('.select-box-details-pane')); // Create span flex box item/div we can measure and control - const widthControlOuterDiv = dom.append(this.selectDropDownContainer, $('.select-box-dropdown-container-width-control')); - const widthControlInnerDiv = dom.append(widthControlOuterDiv, $('.width-control-div')); + let widthControlOuterDiv = dom.append(this.selectDropDownContainer, $('.select-box-dropdown-container-width-control')); + let widthControlInnerDiv = dom.append(widthControlOuterDiv, $('.width-control-div')); this.widthControlElement = document.createElement('span'); this.widthControlElement.className = 'option-text-width-control'; dom.append(widthControlInnerDiv, this.widthControlElement); @@ -295,8 +291,10 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi // Mirror options in drop-down // Populate select list for non-native select mode - this.selectList?.splice(0, this.selectList.length, this.options); - this.selectList?.setSelection(this.selected !== -1 ? [this.selected] : []); // {{SQL CARBON EDIT}} - Set the selected indexes. + if (this.selectList) { + this.selectList.splice(0, this.selectList.length, this.options); + this.selectList?.setSelection(this.selected !== -1 ? [this.selected] : []); // {{SQL CARBON EDIT}} - Set the selected indexes. + } } public select(index: number): void { @@ -451,7 +449,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi } private createOption(value: string, index: number, disabled?: boolean): HTMLOptionElement { - const option = document.createElement('option'); + let option = document.createElement('option'); option.value = value; option.text = value; option.disabled = !!disabled; diff --git a/src/vs/base/browser/ui/splitview/paneview.css b/src/vs/base/browser/ui/splitview/paneview.css index 1351e2119b..306c73c056 100644 --- a/src/vs/base/browser/ui/splitview/paneview.css +++ b/src/vs/base/browser/ui/splitview/paneview.css @@ -24,6 +24,7 @@ height: 22px; font-size: 11px; font-weight: bold; + text-transform: uppercase; overflow: hidden; display: flex; cursor: pointer; @@ -31,10 +32,6 @@ box-sizing: border-box; } -.monaco-pane-view .pane > .pane-header > .title { - text-transform: uppercase; -} - .monaco-pane-view .pane.horizontal:not(.expanded) > .pane-header { flex-direction: column; height: 100%; diff --git a/src/vs/base/browser/ui/splitview/paneview.ts b/src/vs/base/browser/ui/splitview/paneview.ts index a9a56b0975..fc70855a07 100644 --- a/src/vs/base/browser/ui/splitview/paneview.ts +++ b/src/vs/base/browser/ui/splitview/paneview.ts @@ -143,7 +143,9 @@ export abstract class Pane extends Disposable implements IView { return false; } - this.element?.classList.toggle('expanded', expanded); + if (this.element) { + this.element.classList.toggle('expanded', expanded); + } this._expanded = !!expanded; this.updateHeader(); diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 55ec3417a0..63ae7c6ce9 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -231,7 +231,9 @@ abstract class ViewItem { this.container.classList.toggle('visible', visible); - this.view.setVisible?.(visible); + if (this.view.setVisible) { + this.view.setVisible(visible); + } } get minimumSize(): number { return this.visible ? this.view.minimumSize : 0; } @@ -931,23 +933,6 @@ export class SplitView extends Disposable { this.state = State.Idle; } - /** - * Returns whether all other {@link IView views} are at their minimum size. - */ - isViewSizeMaximized(index: number): boolean { - if (index < 0 || index >= this.viewItems.length) { - return false; - } - - for (const item of this.viewItems) { - if (item !== this.viewItems[index] && item.size > item.minimumSize) { - return false; - } - } - - return true; - } - /** * Distribute the entire {@link SplitView} size among all {@link IView views}. */ @@ -1026,7 +1011,7 @@ export class SplitView extends Disposable { // Add sash if (this.viewItems.length > 1) { - const opts = { orthogonalStartSash: this.orthogonalStartSash, orthogonalEndSash: this.orthogonalEndSash }; + let opts = { orthogonalStartSash: this.orthogonalStartSash, orthogonalEndSash: this.orthogonalEndSash }; const sash = this.orientation === Orientation.VERTICAL ? new Sash(this.sashContainer, { getHorizontalSashTop: s => this.getSashPosition(s), getHorizontalSashWidth: this.getSashOrthogonalSize }, { ...opts, orientation: Orientation.HORIZONTAL }) diff --git a/src/vs/base/browser/ui/table/tableWidget.ts b/src/vs/base/browser/ui/table/tableWidget.ts index 1d08ab0f25..4b27576872 100644 --- a/src/vs/base/browser/ui/table/tableWidget.ts +++ b/src/vs/base/browser/ui/table/tableWidget.ts @@ -265,8 +265,8 @@ export class Table implements ISpliceable, IThemable, IDisposable { this.list.layout(listHeight, width); } - triggerTypeNavigation(): void { - this.list.triggerTypeNavigation(); + toggleKeyboardNavigation(): void { + this.list.toggleKeyboardNavigation(); } style(styles: ITableStyles): void { @@ -341,10 +341,6 @@ export class Table implements ISpliceable, IThemable, IDisposable { return this.list.getFocusedElements(); } - getRelativeTop(index: number): number | null { - return this.list.getRelativeTop(index); - } - reveal(index: number, relativeTop?: number): void { this.list.reveal(index, relativeTop); } diff --git a/src/vs/base/browser/ui/toggle/toggle.ts b/src/vs/base/browser/ui/toggle/toggle.ts index 64a8303d7c..55f1b48a0b 100644 --- a/src/vs/base/browser/ui/toggle/toggle.ts +++ b/src/vs/base/browser/ui/toggle/toggle.ts @@ -98,7 +98,6 @@ export class Toggle extends Widget { readonly onKeyDown: Event = this._onKeyDown.event; private readonly _opts: IToggleOpts; - private _icon: CSSIcon | undefined; readonly domNode: HTMLElement; private _checked: boolean; @@ -111,8 +110,7 @@ export class Toggle extends Widget { const classes = ['monaco-custom-toggle']; if (this._opts.icon) { - this._icon = this._opts.icon; - classes.push(...CSSIcon.asClassNameArray(this._icon)); + classes.push(...CSSIcon.asClassNameArray(this._opts.icon)); } if (this._opts.actionClassName) { classes.push(...this._opts.actionClassName.split(' ')); @@ -148,7 +146,6 @@ export class Toggle extends Widget { this.checked = !this._checked; this._onChange.fire(true); keyboardEvent.preventDefault(); - keyboardEvent.stopPropagation(); return; } @@ -177,16 +174,6 @@ export class Toggle extends Widget { this.applyStyles(); } - setIcon(icon: CSSIcon | undefined): void { - if (this._icon) { - this.domNode.classList.remove(...CSSIcon.asClassNameArray(this._icon)); - } - this._icon = icon; - if (this._icon) { - this.domNode.classList.add(...CSSIcon.asClassNameArray(this._icon)); - } - } - width(): number { return 2 /*margin left*/ + 2 /*border*/ + 2 /*padding*/ + 16 /* icon width */; } diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index 9967f74100..57284c0c48 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -130,7 +130,9 @@ export class ToolBar extends Disposable { set context(context: unknown) { this.actionBar.context = context; - this.toggleMenuActionViewItem?.setActionContext(context); + if (this.toggleMenuActionViewItem) { + this.toggleMenuActionViewItem.setActionContext(context); + } for (const actionViewItem of this.submenuActionViewItems) { actionViewItem.setActionContext(context); } @@ -167,7 +169,7 @@ export class ToolBar extends Disposable { setActions(primaryActions: ReadonlyArray, secondaryActions?: ReadonlyArray): void { this.clear(); - const primaryActionsToSet = primaryActions ? primaryActions.slice(0) : []; + let primaryActionsToSet = primaryActions ? primaryActions.slice(0) : []; // Inject additional action to open secondary actions if present this.hasSecondaryActions = !!(secondaryActions && secondaryActions.length > 0); diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index f858d8a369..ed5bf4bb14 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -3,34 +3,27 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { IDragAndDropData } from 'vs/base/browser/dnd'; -import { $, append, clearNode, createStyleSheet, h, hasParentWithClass } from 'vs/base/browser/dom'; +import { DragAndDropData, IDragAndDropData, StaticDND } from 'vs/base/browser/dnd'; +import { $, addDisposableListener, append, clearNode, createStyleSheet, getDomNodePagePosition, hasParentWithClass } from 'vs/base/browser/dom'; import { DomEmitter } from 'vs/base/browser/event'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; -import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview'; -import { FindInput, IFindInputStyles } from 'vs/base/browser/ui/findinput/findInput'; -import { IMessage, MessageType } from 'vs/base/browser/ui/inputbox/inputBox'; -import { IIdentityProvider, IKeyboardNavigationLabelProvider, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IListMouseEvent, IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; +import { IIdentityProvider, IKeyboardNavigationDelegate, IKeyboardNavigationLabelProvider, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IListMouseEvent, IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView'; -import { IListOptions, IListStyles, isButton, isInputElement, isMonacoEditor, List, MouseController, TypeNavigationMode } from 'vs/base/browser/ui/list/listWidget'; -import { Toggle } from 'vs/base/browser/ui/toggle/toggle'; +import { DefaultKeyboardNavigationDelegate, IListOptions, IListStyles, isInputElement, isMonacoEditor, List, MouseController } from 'vs/base/browser/ui/list/listWidget'; import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel'; import { ICollapseStateChangeEvent, ITreeContextMenuEvent, ITreeDragAndDrop, ITreeEvent, ITreeFilter, ITreeModel, ITreeModelSpliceEvent, ITreeMouseEvent, ITreeNavigator, ITreeNode, ITreeRenderer, TreeDragOverBubble, TreeError, TreeFilterResult, TreeMouseEventTarget, TreeVisibility } from 'vs/base/browser/ui/tree/tree'; -import { Action } from 'vs/base/common/actions'; import { distinct, equals, firstOrDefault, range } from 'vs/base/common/arrays'; -import { disposableTimeout, timeout } from 'vs/base/common/async'; +import { disposableTimeout } from 'vs/base/common/async'; import { Codicon } from 'vs/base/common/codicons'; import { SetMap } from 'vs/base/common/collections'; -import { Color } from 'vs/base/common/color'; import { Emitter, Event, EventBufferer, Relay } from 'vs/base/common/event'; import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { clamp } from 'vs/base/common/numbers'; +import { isMacintosh } from 'vs/base/common/platform'; import { ScrollEvent } from 'vs/base/common/scrollable'; import { ISpliceable } from 'vs/base/common/sequence'; -import { isNumber } from 'vs/base/common/types'; import 'vs/css!./media/tree'; import { localize } from 'vs/nls'; @@ -77,7 +70,9 @@ class TreeNodeListDragAndDrop implements IListDragAndDrop< } onDragStart(data: IDragAndDropData, originalEvent: DragEvent): void { - this.dnd.onDragStart?.(asTreeDragAndDropData(data), originalEvent); + if (this.dnd.onDragStart) { + this.dnd.onDragStart(asTreeDragAndDropData(data), originalEvent); + } } onDragOver(data: IDragAndDropData, targetNode: ITreeNode | undefined, targetIndex: number | undefined, originalEvent: DragEvent, raw = true): boolean | IListDragOverReaction { @@ -142,7 +137,9 @@ class TreeNodeListDragAndDrop implements IListDragAndDrop< } onDragEnd(originalEvent: DragEvent): void { - this.dnd.onDragEnd?.(originalEvent); + if (this.dnd.onDragEnd) { + this.dnd.onDragEnd(originalEvent); + } } } @@ -201,7 +198,8 @@ function asListOptions(modelProvider: () => ITreeModel implements IListV } setDynamicHeight(element: N, height: number): void { - this.delegate.setDynamicHeight?.(element.element, height); + if (this.delegate.setDynamicHeight) { + this.delegate.setDynamicHeight(element.element, height); + } } } @@ -308,9 +308,8 @@ interface Collection { readonly onDidChange: Event; } -class EventCollection implements Collection, IDisposable { +class EventCollection implements Collection { - private readonly disposables = new DisposableStore(); readonly onDidChange: Event; get elements(): T[] { @@ -318,11 +317,7 @@ class EventCollection implements Collection, IDisposable { } constructor(onDidChange: Event, private _elements: T[] = []) { - this.onDidChange = Event.forEach(onDidChange, elements => this._elements = elements, this.disposables); - } - - dispose(): void { - this.disposables.dispose(); + this.onDidChange = Event.forEach(onDidChange, elements => this._elements = elements); } } @@ -355,7 +350,9 @@ class TreeRenderer implements IListRenderer Event.map(onDidChangeCollapseState, e => e.node)(this.onDidChangeNodeTwistieState, this, this.disposables); - renderer.onDidChangeTwistieState?.(this.onDidChangeTwistieState, this, this.disposables); + if (renderer.onDidChangeTwistieState) { + renderer.onDidChangeTwistieState(this.onDidChangeTwistieState, this, this.disposables); + } } updateOptions(options: ITreeRendererOptions = {}): void { @@ -417,7 +414,9 @@ class TreeRenderer implements IListRenderer disposeElement(node: ITreeNode, index: number, templateData: ITreeListTemplateData, height: number | undefined): void { templateData.indentGuidesDisposable.dispose(); - this.renderer.disposeElement?.(node, index, templateData.templateData, height); + if (this.renderer.disposeElement) { + this.renderer.disposeElement(node, index, templateData.templateData, height); + } if (typeof height === 'number') { this.renderedNodes.delete(node); @@ -569,7 +568,7 @@ class TreeRenderer implements IListRenderer export type LabelFuzzyScore = { label: string; score: FuzzyScore }; -class FindFilter implements ITreeFilter, IDisposable { +class TypeFilter implements ITreeFilter, IDisposable { private _totalCount = 0; get totalCount(): number { return this._totalCount; } private _matchCount = 0; @@ -593,11 +592,15 @@ class FindFilter implements ITreeFilter, IDi } filter(element: T, parentVisibility: TreeVisibility): TreeFilterResult { - let visibility = TreeVisibility.Visible; - if (this._filter) { const result = this._filter.filter(element, parentVisibility); + if (this.tree.options.simpleKeyboardNavigation) { + return result; + } + + let visibility: TreeVisibility; + if (typeof result === 'boolean') { visibility = result ? TreeVisibility.Visible : TreeVisibility.Hidden; } else if (isFilterResult(result)) { @@ -613,9 +616,9 @@ class FindFilter implements ITreeFilter, IDi this._totalCount++; - if (!this._pattern) { + if (this.tree.options.simpleKeyboardNavigation || !this._pattern) { this._matchCount++; - return { data: FuzzyScore.Default, visibility }; + return { data: FuzzyScore.Default, visibility: true }; } const label = this.keyboardNavigationLabelProvider.getKeyboardNavigationLabel(element); @@ -624,22 +627,22 @@ class FindFilter implements ITreeFilter, IDi for (const l of labels) { const labelStr = l && l.toString(); if (typeof labelStr === 'undefined') { - return { data: FuzzyScore.Default, visibility }; + return { data: FuzzyScore.Default, visibility: true }; } - const score = fuzzyScore(this._pattern, this._lowercasePattern, 0, labelStr, labelStr.toLowerCase(), 0, { firstMatchCanBeWeak: true, boostFullMatch: true }); + const score = fuzzyScore(this._pattern, this._lowercasePattern, 0, labelStr, labelStr.toLowerCase(), 0); if (score) { this._matchCount++; return labels.length === 1 ? - { data: score, visibility } : - { data: { label: labelStr, score: score }, visibility }; + { data: score, visibility: true } : + { data: { label: labelStr, score: score }, visibility: true }; } } - if (this.tree.findMode === TreeFindMode.Filter) { + if (this.tree.options.filterOnType) { return TreeVisibility.Recurse; } else { - return { data: FuzzyScore.Default, visibility }; + return { data: FuzzyScore.Default, visibility: true }; } } @@ -653,282 +656,170 @@ class FindFilter implements ITreeFilter, IDi } } -export interface ICaseSensitiveToggleOpts { - readonly isChecked: boolean; - readonly inputActiveOptionBorder?: Color; - readonly inputActiveOptionForeground?: Color; - readonly inputActiveOptionBackground?: Color; -} +class TypeFilterController implements IDisposable { -export class ModeToggle extends Toggle { - constructor(opts?: ICaseSensitiveToggleOpts) { - super({ - icon: Codicon.filter, - title: localize('filter', "Filter"), - isChecked: opts?.isChecked ?? false, - inputActiveOptionBorder: opts?.inputActiveOptionBorder, - inputActiveOptionForeground: opts?.inputActiveOptionForeground, - inputActiveOptionBackground: opts?.inputActiveOptionBackground - }); - } -} - -export interface IFindWidgetStyles extends IFindInputStyles, IListStyles { } - -export interface IFindWidgetOpts extends IFindWidgetStyles { } - -export enum TreeFindMode { - Highlight, - Filter -} - -class FindWidget extends Disposable { - - private readonly elements = h('.monaco-tree-type-filter', [ - h('.monaco-tree-type-filter-grab.codicon.codicon-debug-gripper@grab', { tabIndex: 0 }), - h('.monaco-tree-type-filter-input@findInput'), - h('.monaco-tree-type-filter-actionbar@actionbar'), - ]); - - set mode(mode: TreeFindMode) { - this.modeToggle.checked = mode === TreeFindMode.Filter; - this.findInput.inputBox.setPlaceHolder(mode === TreeFindMode.Filter ? localize('type to filter', "Type to filter") : localize('type to search', "Type to search")); - } - - private readonly modeToggle: ModeToggle; - private readonly findInput: FindInput; - private readonly actionbar: ActionBar; - private width = 0; - private right = 0; - - readonly _onDidDisable = new Emitter(); - readonly onDidDisable = this._onDidDisable.event; - readonly onDidChangeValue: Event; - readonly onDidChangeMode: Event; - - constructor( - container: HTMLElement, - private tree: AbstractTree, - contextViewProvider: IContextViewProvider, - mode: TreeFindMode, - options?: IFindWidgetOpts - ) { - super(); - - container.appendChild(this.elements.root); - this._register(toDisposable(() => container.removeChild(this.elements.root))); - - this.modeToggle = this._register(new ModeToggle({ ...options, isChecked: mode === TreeFindMode.Filter })); - this.onDidChangeMode = Event.map(this.modeToggle.onChange, () => this.modeToggle.checked ? TreeFindMode.Filter : TreeFindMode.Highlight, this._store); - - this.findInput = this._register(new FindInput(this.elements.findInput, contextViewProvider, false, { - label: localize('type to search', "Type to search"), - additionalToggles: [this.modeToggle] - })); - - this.actionbar = this._register(new ActionBar(this.elements.actionbar)); - this.mode = mode; - - const emitter = this._register(new DomEmitter(this.findInput.inputBox.inputElement, 'keydown')); - const onKeyDown = this._register(Event.chain(emitter.event)) - .map(e => new StandardKeyboardEvent(e)) - .event; - - this._register(onKeyDown((e): any => { - switch (e.keyCode) { - case KeyCode.DownArrow: - e.preventDefault(); - e.stopPropagation(); - this.tree.domFocus(); - return; - } - })); - - const closeAction = this._register(new Action('close', localize('close', "Close"), 'codicon codicon-close', true, () => this.dispose())); - this.actionbar.push(closeAction, { icon: true, label: false }); - - const onGrabMouseDown = this._register(new DomEmitter(this.elements.grab, 'mousedown')); - - this._register(onGrabMouseDown.event(e => { - const disposables = new DisposableStore(); - const onWindowMouseMove = disposables.add(new DomEmitter(window, 'mousemove')); - const onWindowMouseUp = disposables.add(new DomEmitter(window, 'mouseup')); - - const startRight = this.right; - const startX = e.pageX; - this.elements.grab.classList.add('grabbing'); - - const update = (e: MouseEvent) => { - const deltaX = e.pageX - startX; - this.right = startRight - deltaX; - this.layout(); - }; - - disposables.add(onWindowMouseMove.event(update)); - disposables.add(onWindowMouseUp.event(e => { - update(e); - this.elements.grab.classList.remove('grabbing'); - disposables.dispose(); - })); - })); - - const onGrabKeyDown = this._register(Event.chain(this._register(new DomEmitter(this.elements.grab, 'keydown')).event)) - .map(e => new StandardKeyboardEvent(e)) - .event; - - this._register(onGrabKeyDown((e): any => { - let right: number | undefined; - - if (e.keyCode === KeyCode.LeftArrow) { - right = Number.POSITIVE_INFINITY; - } else if (e.keyCode === KeyCode.RightArrow) { - right = 0; - } else if (e.keyCode === KeyCode.Space) { - right = this.right === 0 ? Number.POSITIVE_INFINITY : 0; - } - - if (right !== undefined) { - e.preventDefault(); - e.stopPropagation(); - this.right = right; - this.layout(); - } - })); - - this.onDidChangeValue = this.findInput.onDidChange; - this.style(options ?? {}); - } - - style(styles: IFindWidgetStyles): void { - this.findInput.style(styles); - - if (styles.listFilterWidgetBackground) { - this.elements.root.style.backgroundColor = styles.listFilterWidgetBackground.toString(); - } - - if (styles.listFilterWidgetShadow) { - this.elements.root.style.boxShadow = `0 0 8px 2px ${styles.listFilterWidgetShadow}`; - } - } - - focus() { - this.findInput.focus(); - } - - select() { - this.findInput.select(); - } - - layout(width: number = this.width): void { - this.width = width; - this.right = clamp(this.right, 0, Math.max(0, width - 212)); - this.elements.root.style.right = `${this.right}px`; - } - - showMessage(message: IMessage): void { - this.findInput.showMessage(message); - } - - clearMessage(): void { - this.findInput.clearMessage(); - } - - override async dispose(): Promise { - this._onDidDisable.fire(); - this.elements.root.classList.add('disabled'); - await timeout(300); - super.dispose(); - } -} - -class FindController implements IDisposable { + private _enabled = false; + get enabled(): boolean { return this._enabled; } private _pattern = ''; get pattern(): string { return this._pattern; } - private _mode: TreeFindMode; - get mode(): TreeFindMode { return this._mode; } - set mode(mode: TreeFindMode) { - if (mode === this._mode) { - return; - } + private _filterOnType: boolean; + get filterOnType(): boolean { return this._filterOnType; } - this._mode = mode; + private _empty: boolean = false; + get empty(): boolean { return this._empty; } - if (this.widget) { - this.widget.mode = this._mode; - } + private readonly _onDidChangeEmptyState = new Emitter(); + readonly onDidChangeEmptyState: Event = Event.latch(this._onDidChangeEmptyState.event); - this.tree.refilter(); - this.render(); - this._onDidChangeMode.fire(mode); - } + private positionClassName = 'ne'; + private domNode: HTMLElement; + private messageDomNode: HTMLElement; + private labelDomNode: HTMLElement; + private filterOnTypeDomNode: HTMLInputElement; + private clearDomNode: HTMLElement; + private keyboardNavigationEventFilter?: IKeyboardNavigationEventFilter; - private widget: FindWidget | undefined; - private styles: IFindWidgetStyles | undefined; - private width = 0; - - private readonly _onDidChangeMode = new Emitter(); - readonly onDidChangeMode = this._onDidChangeMode.event; + private automaticKeyboardNavigation = true; + private triggered = false; private readonly _onDidChangePattern = new Emitter(); readonly onDidChangePattern = this._onDidChangePattern.event; - private readonly _onDidChangeOpenState = new Emitter(); - readonly onDidChangeOpenState = this._onDidChangeOpenState.event; - - private enabledDisposables = new DisposableStore(); + private readonly enabledDisposables = new DisposableStore(); private readonly disposables = new DisposableStore(); constructor( private tree: AbstractTree, model: ITreeModel, private view: List>, - private filter: FindFilter, - private readonly contextViewProvider: IContextViewProvider + private filter: TypeFilter, + private keyboardNavigationDelegate: IKeyboardNavigationDelegate ) { - this._mode = tree.options.defaultFindMode ?? TreeFindMode.Highlight; + this.domNode = $(`.monaco-list-type-filter.${this.positionClassName}`); + this.domNode.draggable = true; + this.disposables.add(addDisposableListener(this.domNode, 'dragstart', () => this.onDragStart())); + + this.messageDomNode = append(view.getHTMLElement(), $(`.monaco-list-type-filter-message`)); + + this.labelDomNode = append(this.domNode, $('span.label')); + const controls = append(this.domNode, $('.controls')); + + this._filterOnType = !!tree.options.filterOnType; + this.filterOnTypeDomNode = append(controls, $('input.filter')); + this.filterOnTypeDomNode.type = 'checkbox'; + this.filterOnTypeDomNode.checked = this._filterOnType; + this.filterOnTypeDomNode.tabIndex = -1; + this.updateFilterOnTypeTitleAndIcon(); + this.disposables.add(addDisposableListener(this.filterOnTypeDomNode, 'input', () => this.onDidChangeFilterOnType())); + + this.clearDomNode = append(controls, $('button.clear' + Codicon.treeFilterClear.cssSelector)); + this.clearDomNode.tabIndex = -1; + this.clearDomNode.title = localize('clear', "Clear"); + + this.keyboardNavigationEventFilter = tree.options.keyboardNavigationEventFilter; + model.onDidSplice(this.onDidSpliceModel, this, this.disposables); + this.updateOptions(tree.options); } - open(): void { - if (this.widget) { - this.widget.focus(); - this.widget.select(); + updateOptions(options: IAbstractTreeOptions): void { + if (options.simpleKeyboardNavigation) { + this.disable(); + } else { + this.enable(); + } + + if (typeof options.filterOnType !== 'undefined') { + this._filterOnType = !!options.filterOnType; + this.filterOnTypeDomNode.checked = this._filterOnType; + this.updateFilterOnTypeTitleAndIcon(); + } + + if (typeof options.automaticKeyboardNavigation !== 'undefined') { + this.automaticKeyboardNavigation = options.automaticKeyboardNavigation; + } + + this.tree.refilter(); + this.render(); + + if (!this.automaticKeyboardNavigation) { + this.onEventOrInput(''); + } + } + + toggle(): void { + this.triggered = !this.triggered; + + if (!this.triggered) { + this.onEventOrInput(''); + } + } + + private enable(): void { + if (this._enabled) { return; } - this.mode = this.tree.options.defaultFindMode ?? TreeFindMode.Highlight; - this.widget = new FindWidget(this.view.getHTMLElement(), this.tree, this.contextViewProvider, this.mode, this.styles); - this.enabledDisposables.add(this.widget); + const onRawKeyDown = this.enabledDisposables.add(new DomEmitter(this.view.getHTMLElement(), 'keydown')); + const onKeyDown = Event.chain(onRawKeyDown.event) + .filter(e => !isInputElement(e.target as HTMLElement) || e.target === this.filterOnTypeDomNode) + .filter(e => e.key !== 'Dead' && !/^Media/.test(e.key)) + .map(e => new StandardKeyboardEvent(e)) + .filter(this.keyboardNavigationEventFilter || (() => true)) + .filter(() => this.automaticKeyboardNavigation || this.triggered) + .filter(e => (this.keyboardNavigationDelegate.mightProducePrintableCharacter(e) && !(e.keyCode === KeyCode.DownArrow || e.keyCode === KeyCode.UpArrow || e.keyCode === KeyCode.LeftArrow || e.keyCode === KeyCode.RightArrow)) || ((this.pattern.length > 0 || this.triggered) && ((e.keyCode === KeyCode.Escape || e.keyCode === KeyCode.Backspace) && !e.altKey && !e.ctrlKey && !e.metaKey) || (e.keyCode === KeyCode.Backspace && (isMacintosh ? (e.altKey && !e.metaKey) : e.ctrlKey) && !e.shiftKey))) + .forEach(e => { e.stopPropagation(); e.preventDefault(); }) + .event; - this.widget.onDidChangeValue(this.onDidChangeValue, this, this.enabledDisposables); - this.widget.onDidChangeMode(mode => this.mode = mode, undefined, this.enabledDisposables); - this.widget.onDidDisable(this.close, this, this.enabledDisposables); + const onClearClick = this.enabledDisposables.add(new DomEmitter(this.clearDomNode, 'click')); - this.widget.layout(this.width); - this.widget.focus(); + Event.chain(Event.any(onKeyDown, onClearClick.event)) + .event(this.onEventOrInput, this, this.enabledDisposables); - this._onDidChangeOpenState.fire(true); + this.filter.pattern = ''; + this.tree.refilter(); + this.render(); + this._enabled = true; + this.triggered = false; } - close(): void { - if (!this.widget) { + private disable(): void { + if (!this._enabled) { return; } - this.widget = undefined; - - this.enabledDisposables.dispose(); - this.enabledDisposables = new DisposableStore(); - - this.onDidChangeValue(''); - this.tree.domFocus(); - - this._onDidChangeOpenState.fire(false); + this.domNode.remove(); + this.enabledDisposables.clear(); + this.tree.refilter(); + this.render(); + this._enabled = false; + this.triggered = false; } - private onDidChangeValue(pattern: string): void { + private onEventOrInput(e: MouseEvent | StandardKeyboardEvent | string): void { + if (typeof e === 'string') { + this.onInput(e); + } else if (e instanceof MouseEvent || e.keyCode === KeyCode.Escape || (e.keyCode === KeyCode.Backspace && (isMacintosh ? e.altKey : e.ctrlKey))) { + this.onInput(''); + } else if (e.keyCode === KeyCode.Backspace) { + this.onInput(this.pattern.length === 0 ? '' : this.pattern.substr(0, this.pattern.length - 1)); + } else { + this.onInput(this.pattern + e.browserEvent.key); + } + } + + private onInput(pattern: string): void { + const container = this.view.getHTMLElement(); + + if (pattern && !this.domNode.parentElement) { + container.append(this.domNode); + } else if (!pattern && this.domNode.parentElement) { + this.domNode.remove(); + this.tree.domFocus(); + } + this._pattern = pattern; this._onDidChangePattern.fire(pattern); @@ -950,10 +841,75 @@ class FindController implements IDisposable { } this.render(); + + if (!pattern) { + this.triggered = false; + } + } + + private onDragStart(): void { + const container = this.view.getHTMLElement(); + const { left } = getDomNodePagePosition(container); + const containerWidth = container.clientWidth; + const midContainerWidth = containerWidth / 2; + const width = this.domNode.clientWidth; + const disposables = new DisposableStore(); + let positionClassName = this.positionClassName; + + const updatePosition = () => { + switch (positionClassName) { + case 'nw': + this.domNode.style.top = `4px`; + this.domNode.style.left = `4px`; + break; + case 'ne': + this.domNode.style.top = `4px`; + this.domNode.style.left = `${containerWidth - width - 6}px`; + break; + } + }; + + const onDragOver = (event: DragEvent) => { + event.preventDefault(); // needed so that the drop event fires (https://stackoverflow.com/questions/21339924/drop-event-not-firing-in-chrome) + + const x = event.clientX - left; + if (event.dataTransfer) { + event.dataTransfer.dropEffect = 'none'; + } + + if (x < midContainerWidth) { + positionClassName = 'nw'; + } else { + positionClassName = 'ne'; + } + + updatePosition(); + }; + + const onDragEnd = () => { + this.positionClassName = positionClassName; + this.domNode.className = `monaco-list-type-filter ${this.positionClassName}`; + this.domNode.style.top = ''; + this.domNode.style.left = ''; + + dispose(disposables); + }; + + updatePosition(); + this.domNode.classList.remove(positionClassName); + + this.domNode.classList.add('dragging'); + disposables.add(toDisposable(() => this.domNode.classList.remove('dragging'))); + + disposables.add(addDisposableListener(document, 'dragover', e => onDragOver(e))); + disposables.add(addDisposableListener(this.domNode, 'dragend', () => onDragEnd())); + + StaticDND.CurrentDragAndDropData = new DragAndDropData('vscode-ui'); + disposables.add(toDisposable(() => StaticDND.CurrentDragAndDropData = undefined)); } private onDidSpliceModel(): void { - if (!this.widget || this.pattern.length === 0) { + if (!this._enabled || this.pattern.length === 0) { return; } @@ -961,18 +917,46 @@ class FindController implements IDisposable { this.render(); } - private render(): void { - const noMatches = this.filter.totalCount > 0 && this.filter.matchCount === 0; + private onDidChangeFilterOnType(): void { + this.tree.updateOptions({ filterOnType: this.filterOnTypeDomNode.checked }); + this.tree.refilter(); + this.tree.domFocus(); + this.render(); + this.updateFilterOnTypeTitleAndIcon(); + } - if (this.pattern && noMatches) { - this.widget?.showMessage({ type: MessageType.WARNING, content: localize('not found', "No elements found.") }); + private updateFilterOnTypeTitleAndIcon(): void { + if (this.filterOnType) { + this.filterOnTypeDomNode.classList.remove(...Codicon.treeFilterOnTypeOff.classNamesArray); + this.filterOnTypeDomNode.classList.add(...Codicon.treeFilterOnTypeOn.classNamesArray); + this.filterOnTypeDomNode.title = localize('disable filter on type', "Disable Filter on Type"); } else { - this.widget?.clearMessage(); + this.filterOnTypeDomNode.classList.remove(...Codicon.treeFilterOnTypeOn.classNamesArray); + this.filterOnTypeDomNode.classList.add(...Codicon.treeFilterOnTypeOff.classNamesArray); + this.filterOnTypeDomNode.title = localize('enable filter on type', "Enable Filter on Type"); } } + private render(): void { + const noMatches = this.filter.totalCount > 0 && this.filter.matchCount === 0; + + if (this.pattern && this.tree.options.filterOnType && noMatches) { + this.messageDomNode.textContent = localize('empty', "No elements found"); + this._empty = true; + } else { + this.messageDomNode.innerText = ''; + this._empty = false; + } + + this.domNode.classList.toggle('no-matches', noMatches); + this.domNode.title = localize('found', "Matched {0} out of {1} elements", this.filter.matchCount, this.filter.totalCount); + this.labelDomNode.textContent = this.pattern.length > 16 ? '…' + this.pattern.substr(this.pattern.length - 16) : this.pattern; + + this._onDidChangeEmptyState.fire(this._empty); + } + shouldAllowFocus(node: ITreeNode): boolean { - if (!this.widget || !this.pattern || this._mode === TreeFindMode.Filter) { + if (!this.enabled || !this.pattern || this.filterOnType) { return true; } @@ -983,20 +967,16 @@ class FindController implements IDisposable { return !FuzzyScore.isDefault(node.filterData as any as FuzzyScore); } - style(styles: IFindWidgetStyles): void { - this.styles = styles; - this.widget?.style(styles); - } - - layout(width: number): void { - this.width = width; - this.widget?.layout(width); - } - dispose() { + if (this._enabled) { + this.domNode.remove(); + this.enabledDisposables.dispose(); + this._enabled = false; + this.triggered = false; + } + this._onDidChangePattern.dispose(); - this.enabledDisposables.dispose(); - this.disposables.dispose(); + dispose(this.disposables); } } @@ -1007,8 +987,6 @@ function asTreeMouseEvent(event: IListMouseEvent>): ITreeMo target = TreeMouseEventTarget.Twistie; } else if (hasParentWithClass(event.browserEvent.target as HTMLElement, 'monaco-tl-contents', 'monaco-tl-row')) { target = TreeMouseEventTarget.Element; - } else if (hasParentWithClass(event.browserEvent.target as HTMLElement, 'monaco-tree-type-filter', 'monaco-list')) { - target = TreeMouseEventTarget.Filter; } return { @@ -1026,11 +1004,15 @@ function asTreeContextMenuEvent(event: IListContextMenuEvent extends IAbstractTreeOptionsUpdate, IListOptions { - readonly contextViewProvider?: IContextViewProvider; readonly collapseByDefault?: boolean; // defaults to false readonly filter?: ITreeFilter; readonly dnd?: ITreeDragAndDrop; + readonly keyboardNavigationEventFilter?: IKeyboardNavigationEventFilter; readonly additionalScrollHeight?: number; - readonly findWidgetEnabled?: boolean; } function dfs(node: ITreeNode, fn: (node: ITreeNode) => void): void { @@ -1177,9 +1158,7 @@ class TreeNodeListMouseController extends MouseController< } protected override onViewPointer(e: IListMouseEvent>): void { - if (isButton(e.browserEvent.target as HTMLElement) || - isInputElement(e.browserEvent.target as HTMLElement) || - isMonacoEditor(e.browserEvent.target as HTMLElement)) { + if (isInputElement(e.browserEvent.target as HTMLElement) || isMonacoEditor(e.browserEvent.target as HTMLElement)) { return; } @@ -1342,8 +1321,7 @@ export abstract class AbstractTree implements IDisposable private selection: Trait; private anchor: Trait; private eventBufferer = new EventBufferer(); - private findController?: FindController; - readonly onDidChangeFindOpenState: Event = Event.None; + private typeFilterController?: TypeFilterController; private focusNavigationFilter: ((node: ITreeNode) => boolean) | undefined; private styleElement: HTMLStyleElement; protected readonly disposables = new DisposableStore(); @@ -1354,7 +1332,7 @@ export abstract class AbstractTree implements IDisposable get onDidChangeSelection(): Event> { return this.eventBufferer.wrapEvent(this.selection.onDidChange); } get onMouseClick(): Event> { return Event.map(this.view.onMouseClick, asTreeMouseEvent); } - get onMouseDblClick(): Event> { return Event.filter(Event.map(this.view.onMouseDblClick, asTreeMouseEvent), e => e.target !== TreeMouseEventTarget.Filter); } + get onMouseDblClick(): Event> { return Event.map(this.view.onMouseDblClick, asTreeMouseEvent); } get onContextMenu(): Event> { return Event.map(this.view.onContextMenu, asTreeContextMenuEvent); } get onTap(): Event> { return Event.map(this.view.onTap, asTreeMouseEvent); } get onPointer(): Event> { return Event.map(this.view.onPointer, asTreeMouseEvent); } @@ -1373,11 +1351,8 @@ export abstract class AbstractTree implements IDisposable private readonly _onWillRefilter = new Emitter(); readonly onWillRefilter: Event = this._onWillRefilter.event; - get findMode(): TreeFindMode { return this.findController?.mode ?? TreeFindMode.Highlight; } - set findMode(findMode: TreeFindMode) { if (this.findController) { this.findController.mode = findMode; } } - readonly onDidChangeFindMode: Event; - - get onDidChangeFindPattern(): Event { return this.findController ? this.findController.onDidChangePattern : Event.None; } + get filterOnType(): boolean { return !!this._options.filterOnType; } + get onDidChangeTypeFilterPattern(): Event { return this.typeFilterController ? this.typeFilterController.onDidChangePattern : Event.None; } get expandOnDoubleClick(): boolean { return typeof this._options.expandOnDoubleClick === 'undefined' ? true : this._options.expandOnDoubleClick; } get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { return typeof this._options.expandOnlyOnTwistieClick === 'undefined' ? true : this._options.expandOnlyOnTwistieClick; } @@ -1398,16 +1373,16 @@ export abstract class AbstractTree implements IDisposable const onDidChangeCollapseStateRelay = new Relay>(); const onDidChangeActiveNodes = new Relay[]>(); - const activeNodes = this.disposables.add(new EventCollection(onDidChangeActiveNodes.event)); + const activeNodes = new EventCollection(onDidChangeActiveNodes.event); this.renderers = renderers.map(r => new TreeRenderer(r, () => this.model, onDidChangeCollapseStateRelay.event, activeNodes, _options)); - for (const r of this.renderers) { + for (let r of this.renderers) { this.disposables.add(r); } - let filter: FindFilter | undefined; + let filter: TypeFilter | undefined; if (_options.keyboardNavigationLabelProvider) { - filter = new FindFilter(this, _options.keyboardNavigationLabelProvider, _options.filter as any as ITreeFilter); + filter = new TypeFilter(this, _options.keyboardNavigationLabelProvider, _options.filter as any as ITreeFilter); _options = { ..._options, filter: filter as ITreeFilter }; // TODO need typescript help here this.disposables.add(filter); } @@ -1425,7 +1400,7 @@ export abstract class AbstractTree implements IDisposable this.focus.onDidModelSplice(e); this.selection.onDidModelSplice(e); }); - }, this.disposables); + }); // Make sure the `forEach` always runs onDidModelSplice(() => null, null, this.disposables); @@ -1460,14 +1435,11 @@ export abstract class AbstractTree implements IDisposable onKeyDown.filter(e => e.keyCode === KeyCode.Space).on(this.onSpace, this, this.disposables); } - if ((_options.findWidgetEnabled ?? true) && _options.keyboardNavigationLabelProvider && _options.contextViewProvider) { - this.findController = new FindController(this, this.model, this.view, filter!, _options.contextViewProvider); - this.focusNavigationFilter = node => this.findController!.shouldAllowFocus(node); - this.onDidChangeFindOpenState = this.findController.onDidChangeOpenState; - this.disposables.add(this.findController!); - this.onDidChangeFindMode = this.findController.onDidChangeMode; - } else { - this.onDidChangeFindMode = Event.None; + if (_options.keyboardNavigationLabelProvider) { + const delegate = _options.keyboardNavigationDelegate || DefaultKeyboardNavigationDelegate; + this.typeFilterController = new TypeFilterController(this, this.model, this.view, filter!, delegate); + this.focusNavigationFilter = node => this.typeFilterController!.shouldAllowFocus(node); + this.disposables.add(this.typeFilterController!); } this.styleElement = createStyleSheet(this.view.getHTMLElement()); @@ -1481,7 +1453,15 @@ export abstract class AbstractTree implements IDisposable renderer.updateOptions(optionsUpdate); } - this.view.updateOptions(this._options); + this.view.updateOptions({ + ...this._options, + enableKeyboardNavigation: this._options.simpleKeyboardNavigation, + }); + + if (this.typeFilterController) { + this.typeFilterController.updateOptions(this._options); + } + this._onDidUpdateOptions.fire(this._options); this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always); @@ -1508,11 +1488,21 @@ export abstract class AbstractTree implements IDisposable } get contentHeight(): number { + if (this.typeFilterController && this.typeFilterController.filterOnType && this.typeFilterController.empty) { + return 100; + } + return this.view.contentHeight; } get onDidChangeContentHeight(): Event { - return this.view.onDidChangeContentHeight; + let result = this.view.onDidChangeContentHeight; + + if (this.typeFilterController) { + result = Event.any(result, Event.map(this.typeFilterController.onDidChangeEmptyState, () => this.contentHeight)); + } + + return result; } get scrollTop(): number { @@ -1574,10 +1564,6 @@ export abstract class AbstractTree implements IDisposable layout(height?: number, width?: number): void { this.view.layout(height, width); - - if (isNumber(width)) { - this.findController?.layout(width); - } } style(styles: IListStyles): void { @@ -1590,8 +1576,6 @@ export abstract class AbstractTree implements IDisposable } this.styleElement.textContent = content.join('\n'); - - this.findController?.style(styles); this.view.style(styles); } @@ -1645,16 +1629,12 @@ export abstract class AbstractTree implements IDisposable return this.model.isCollapsed(location); } - triggerTypeNavigation(): void { - this.view.triggerTypeNavigation(); - } + toggleKeyboardNavigation(): void { + this.view.toggleKeyboardNavigation(); - openFind(): void { - this.findController?.open(); - } - - closeFind(): void { - this.findController?.close(); + if (this.typeFilterController) { + this.typeFilterController.toggle(); + } } refilter(): void { diff --git a/src/vs/base/browser/ui/tree/asyncDataTree.ts b/src/vs/base/browser/ui/tree/asyncDataTree.ts index 9ff33775f8..b0d35a1482 100644 --- a/src/vs/base/browser/ui/tree/asyncDataTree.ts +++ b/src/vs/base/browser/ui/tree/asyncDataTree.ts @@ -7,7 +7,7 @@ import { IDragAndDropData } from 'vs/base/browser/dnd'; import { IIdentityProvider, IListDragAndDrop, IListDragOverReaction, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView'; import { IListStyles } from 'vs/base/browser/ui/list/listWidget'; -import { ComposedTreeDelegate, TreeFindMode as TreeFindMode, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree'; +import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree'; import { ICompressedTreeElement, ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel'; import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel'; import { CompressibleObjectTree, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions, ICompressibleTreeRenderer, IObjectTreeOptions, IObjectTreeSetChildrenOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree'; @@ -119,7 +119,9 @@ class AsyncDataTreeRenderer implements IT } disposeElement(node: ITreeNode, TFilterData>, index: number, templateData: IDataTreeListTemplateData, height: number | undefined): void { - this.renderer.disposeElement?.(this.nodeMapper.map(node) as ITreeNode, index, templateData.templateData, height); + if (this.renderer.disposeElement) { + this.renderer.disposeElement(this.nodeMapper.map(node) as ITreeNode, index, templateData.templateData, height); + } } disposeTemplate(templateData: IDataTreeListTemplateData): void { @@ -194,7 +196,9 @@ class AsyncDataTreeNodeListDragAndDrop implements IListDragAndDrop | undefined, targetIndex: number | undefined, originalEvent: DragEvent, raw = true): boolean | IListDragOverReaction { @@ -206,7 +210,9 @@ class AsyncDataTreeNodeListDragAndDrop implements IListDragAndDrop implements IDisposable get onDidUpdateOptions(): Event { return this.tree.onDidUpdateOptions; } - get onDidChangeFindOpenState(): Event { return this.tree.onDidChangeFindOpenState; } - - get findMode(): TreeFindMode { return this.tree.findMode; } - set findMode(mode: TreeFindMode) { this.tree.findMode = mode; } - readonly onDidChangeFindMode: Event; - + get filterOnType(): boolean { return this.tree.filterOnType; } get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { if (typeof this.tree.expandOnlyOnTwistieClick === 'boolean') { return this.tree.expandOnlyOnTwistieClick; @@ -372,7 +373,6 @@ export class AsyncDataTree implements IDisposable this.collapseByDefault = options.collapseByDefault; this.tree = this.createTree(user, container, delegate, renderers, options); - this.onDidChangeFindMode = this.tree.onDidChangeFindMode; this.root = createAsyncDataTreeNode({ element: undefined!, @@ -622,16 +622,8 @@ export class AsyncDataTree implements IDisposable return this.tree.isCollapsed(this.getDataNode(element)); } - triggerTypeNavigation(): void { - this.tree.triggerTypeNavigation(); - } - - openFind(): void { - this.tree.openFind(); - } - - closeFind(): void { - this.tree.closeFind(); + toggleKeyboardNavigation(): void { + this.tree.toggleKeyboardNavigation(); } refilter(): void { @@ -742,16 +734,6 @@ export class AsyncDataTree implements IDisposable return result; } - if (node !== this.root) { - const treeNode = this.tree.getNode(node); - - if (treeNode.collapsed) { - node.hasChildren = !!this.dataSource.hasChildren(node.element!); - node.stale = true; - return; - } - } - return this.doRefreshSubTree(node, recursive, viewStateContext); } @@ -1104,11 +1086,15 @@ class CompressibleAsyncDataTreeRenderer i } disposeElement(node: ITreeNode, TFilterData>, index: number, templateData: IDataTreeListTemplateData, height: number | undefined): void { - this.renderer.disposeElement?.(this.nodeMapper.map(node) as ITreeNode, index, templateData.templateData, height); + if (this.renderer.disposeElement) { + this.renderer.disposeElement(this.nodeMapper.map(node) as ITreeNode, index, templateData.templateData, height); + } } disposeCompressedElements(node: ITreeNode>, TFilterData>, index: number, templateData: IDataTreeListTemplateData, height: number | undefined): void { - this.renderer.disposeCompressedElements?.(this.compressibleNodeMapperProvider().map(node) as ITreeNode, TFilterData>, index, templateData.templateData, height); + if (this.renderer.disposeCompressedElements) { + this.renderer.disposeCompressedElements(this.compressibleNodeMapperProvider().map(node) as ITreeNode, TFilterData>, index, templateData.templateData, height); + } } disposeTemplate(templateData: IDataTreeListTemplateData): void { @@ -1203,10 +1189,10 @@ export class CompressibleAsyncDataTree extends As const expanded: string[] = []; const root = this.tree.getCompressedTreeNode(); - const stack = [root]; + const queue = [root]; - while (stack.length > 0) { - const node = stack.pop()!; + while (queue.length > 0) { + const node = queue.shift()!; if (node !== root && node.collapsible && !node.collapsed) { for (const asyncNode of node.element!.elements) { @@ -1214,7 +1200,7 @@ export class CompressibleAsyncDataTree extends As } } - stack.push(...node.children); + queue.push(...node.children); } return { focus, selection, expanded, scrollTop: this.scrollTop }; diff --git a/src/vs/base/browser/ui/tree/dataTree.ts b/src/vs/base/browser/ui/tree/dataTree.ts index 30be08f52d..7627a9fd0f 100644 --- a/src/vs/base/browser/ui/tree/dataTree.ts +++ b/src/vs/base/browser/ui/tree/dataTree.ts @@ -140,7 +140,9 @@ export class DataTree extends AbstractTree) => { diff --git a/src/vs/base/browser/ui/tree/indexTreeModel.ts b/src/vs/base/browser/ui/tree/indexTreeModel.ts index 86b6ac8c4f..aa911cc6f5 100644 --- a/src/vs/base/browser/ui/tree/indexTreeModel.ts +++ b/src/vs/base/browser/ui/tree/indexTreeModel.ts @@ -554,7 +554,9 @@ export class IndexTreeModel, TFilterData = voi node.renderNodeCount = renderNodeCount; } - onDidCreateNode?.(node); + if (onDidCreateNode) { + onDidCreateNode(node); + } return node; } diff --git a/src/vs/base/browser/ui/tree/media/tree.css b/src/vs/base/browser/ui/tree/media/tree.css index 6d3faee477..edfce3bcc1 100644 --- a/src/vs/base/browser/ui/tree/media/tree.css +++ b/src/vs/base/browser/ui/tree/media/tree.css @@ -67,55 +67,3 @@ /* Use steps to throttle FPS to reduce CPU usage */ animation: codicon-spin 1.25s steps(30) infinite; } - -.monaco-tree-type-filter { - position: absolute; - top: 0; - display: flex; - padding: 3px; - transition: top 0.3s; - max-width: 200px; - z-index: 100; - margin: 0 6px; -} - -.monaco-tree-type-filter.disabled { - top: -40px; -} - -.monaco-tree-type-filter-grab { - display: flex !important; - align-items: center; - justify-content: center; - cursor: grab; - margin-right: 2px; -} - -.monaco-tree-type-filter-grab.grabbing { - cursor: grabbing; -} - -.monaco-tree-type-filter-input { - flex: 1; -} - -.monaco-tree-type-filter-input .monaco-inputbox { - height: 23px; -} - -.monaco-tree-type-filter-input .monaco-inputbox > .ibwrapper > .input, -.monaco-tree-type-filter-input .monaco-inputbox > .ibwrapper > .mirror { - padding: 2px 4px; -} - -.monaco-tree-type-filter-input .monaco-findInput > .controls { - top: 2px; -} - -.monaco-tree-type-filter-actionbar { - margin-left: 4px; -} - -.monaco-tree-type-filter-actionbar .monaco-action-bar .action-label { - padding: 2px; -} diff --git a/src/vs/base/browser/ui/tree/objectTree.ts b/src/vs/base/browser/ui/tree/objectTree.ts index c967ad91b1..3b523a655d 100644 --- a/src/vs/base/browser/ui/tree/objectTree.ts +++ b/src/vs/base/browser/ui/tree/objectTree.ts @@ -140,9 +140,13 @@ class CompressibleRenderer, TFilterData, TTemplateDat disposeElement(node: ITreeNode, index: number, templateData: CompressibleTemplateData, height: number | undefined): void { if (templateData.compressedTreeNode) { - this.renderer.disposeCompressedElements?.(templateData.compressedTreeNode, index, templateData.data, height); + if (this.renderer.disposeCompressedElements) { + this.renderer.disposeCompressedElements(templateData.compressedTreeNode, index, templateData.data, height); + } } else { - this.renderer.disposeElement?.(node, index, templateData.data, height); + if (this.renderer.disposeElement) { + this.renderer.disposeElement(node, index, templateData.data, height); + } } } diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index 126012ace8..a6ff56de80 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -141,8 +141,7 @@ export interface ITreeEvent { export enum TreeMouseEventTarget { Unknown, Twistie, - Element, - Filter + Element } export interface ITreeMouseEvent { diff --git a/src/vs/base/browser/ui/widget.ts b/src/vs/base/browser/ui/widget.ts index 669da7baa0..ea293f638d 100644 --- a/src/vs/base/browser/ui/widget.ts +++ b/src/vs/base/browser/ui/widget.ts @@ -23,8 +23,8 @@ export abstract class Widget extends Disposable { this._register(dom.addDisposableListener(domNode, dom.EventType.MOUSE_OVER, (e: MouseEvent) => listener(new StandardMouseEvent(e)))); } - protected onmouseleave(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void { - this._register(dom.addDisposableListener(domNode, dom.EventType.MOUSE_LEAVE, (e: MouseEvent) => listener(new StandardMouseEvent(e)))); + protected onnonbubblingmouseout(domNode: HTMLElement, listener: (e: IMouseEvent) => void): void { + this._register(dom.addDisposableNonBubblingMouseOutListener(domNode, (e: MouseEvent) => listener(new StandardMouseEvent(e)))); } protected onkeydown(domNode: HTMLElement, listener: (e: IKeyboardEvent) => void): void { diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index 3beed2aaec..2ae52a3e3f 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -14,9 +14,8 @@ export interface ITelemetryData { } export type WorkbenchActionExecutedClassification = { - owner: 'bpasero'; - id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifier of the action that was run.' }; - from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The name of the component the action was run from.' }; + id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; + from: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; }; export type WorkbenchActionExecutedEvent = { diff --git a/src/vs/base/common/amd.ts b/src/vs/base/common/amd.ts index 046561da04..75dff825b0 100644 --- a/src/vs/base/common/amd.ts +++ b/src/vs/base/common/amd.ts @@ -26,7 +26,7 @@ export abstract class LoaderStats { } function diff(map: Map, stat: LoaderEvent) { - const duration = map.get(stat.detail); + let duration = map.get(stat.detail); if (!duration) { // console.warn('BAD events, end WITHOUT start', stat); // map.delete(stat.detail); @@ -79,7 +79,7 @@ export abstract class LoaderStats { nodeRequire.forEach(value => nodeRequireTotal += value); function to2dArray(map: Map): [string, number][] { - const res: [string, number][] = []; + let res: [string, number][] = []; map.forEach((value, index) => res.push([index, value])); return res; } @@ -96,7 +96,7 @@ export abstract class LoaderStats { static toMarkdownTable(header: string[], rows: Array>): string { let result = ''; - const lengths: number[] = []; + let lengths: number[] = []; header.forEach((cell, ci) => { lengths[ci] = cell.length; }); diff --git a/src/vs/base/common/arrays.ts b/src/vs/base/common/arrays.ts index be9df2bae8..7637d21a89 100644 --- a/src/vs/base/common/arrays.ts +++ b/src/vs/base/common/arrays.ts @@ -46,55 +46,13 @@ export function equals(one: ReadonlyArray | undefined, other: ReadonlyArra return true; } -/** - * Remove the element at `index` by replacing it with the last element. This is faster than `splice` - * but changes the order of the array - */ -export function removeFastWithoutKeepingOrder(array: T[], index: number) { - const last = array.length - 1; - if (index < last) { - array[index] = array[last]; - } - array.pop(); -} - -/** - * Performs a binary search algorithm over a sorted array. - * - * @param array The array being searched. - * @param key The value we search for. - * @param comparator A function that takes two array elements and returns zero - * if they are equal, a negative number if the first element precedes the - * second one in the sorting order, or a positive number if the second element - * precedes the first one. - * @return See {@link binarySearch2} - */ export function binarySearch(array: ReadonlyArray, key: T, comparator: (op1: T, op2: T) => number): number { - return binarySearch2(array.length, i => comparator(array[i], key)); -} - -/** - * Performs a binary search algorithm over a sorted collection. Useful for cases - * when we need to perform a binary search over something that isn't actually an - * array, and converting data to an array would defeat the use of binary search - * in the first place. - * - * @param length The collection length. - * @param compareToKey A function that takes an index of an element in the - * collection and returns zero if the value at this index is equal to the - * search key, a negative number if the value precedes the search key in the - * sorting order, or a positive number if the search key precedes the value. - * @return A non-negative index of an element, if found. If not found, the - * result is -(n+1) (or ~n, using bitwise notation), where n is the index - * where the key should be inserted to maintain the sorting order. - */ -export function binarySearch2(length: number, compareToKey: (index: number) => number): number { let low = 0, - high = length - 1; + high = array.length - 1; while (low <= high) { const mid = ((low + high) / 2) | 0; - const comp = compareToKey(mid); + const comp = comparator(array[mid], key); if (comp < 0) { low = mid + 1; } else if (comp > 0) { @@ -138,12 +96,12 @@ export function quickSelect(nth: number, data: T[], compare: Compare): T { throw new TypeError('invalid index'); } - const pivotValue = data[Math.floor(data.length * Math.random())]; - const lower: T[] = []; - const higher: T[] = []; - const pivots: T[] = []; + let pivotValue = data[Math.floor(data.length * Math.random())]; + let lower: T[] = []; + let higher: T[] = []; + let pivots: T[] = []; - for (const value of data) { + for (let value of data) { const val = compare(value, pivotValue); if (val < 0) { lower.push(value); @@ -652,55 +610,17 @@ function getActualStartIndex(array: T[], start: number): number { return start < 0 ? Math.max(start + array.length, 0) : Math.min(start, array.length); } -/** - * When comparing two values, - * a negative number indicates that the first value is less than the second, - * a positive number indicates that the first value is greater than the second, - * and zero indicates that neither is the case. -*/ -export type CompareResult = number; - -export namespace CompareResult { - export function isLessThan(result: CompareResult): boolean { - return result < 0; - } - - export function isGreaterThan(result: CompareResult): boolean { - return result > 0; - } - - export function isNeitherLessOrGreaterThan(result: CompareResult): boolean { - return result === 0; - } - - export const greaterThan = 1; - export const lessThan = -1; - export const neitherLessOrGreaterThan = 0; -} - /** * A comparator `c` defines a total order `<=` on `T` as following: * `c(a, b) <= 0` iff `a` <= `b`. * We also have `c(a, b) == 0` iff `c(b, a) == 0`. */ -export type Comparator = (a: T, b: T) => CompareResult; +export type Comparator = (a: T, b: T) => number; export function compareBy(selector: (item: TItem) => TCompareBy, comparator: Comparator): Comparator { return (a, b) => comparator(selector(a), selector(b)); } -export function tieBreakComparators(...comparators: Comparator[]): Comparator { - return (item1, item2) => { - for (const comparator of comparators) { - const result = comparator(item1, item2); - if (!CompareResult.isNeitherLessOrGreaterThan(result)) { - return result; - } - } - return CompareResult.neitherLessOrGreaterThan; - }; -} - /** * The natural order on numbers. */ @@ -756,7 +676,7 @@ export class ArrayQueue { /** * Constructs a queue that is backed by the given array. Runtime is O(1). */ - constructor(private readonly items: readonly T[]) { } + constructor(private readonly items: T[]) { } get length(): number { return this.lastIdx - this.firstIdx + 1; @@ -798,31 +718,15 @@ export class ArrayQueue { } peek(): T | undefined { - if (this.length === 0) { - return undefined; - } return this.items[this.firstIdx]; } - peekLast(): T | undefined { - if (this.length === 0) { - return undefined; - } - return this.items[this.lastIdx]; - } - dequeue(): T | undefined { const result = this.items[this.firstIdx]; this.firstIdx++; return result; } - removeLast(): T | undefined { - const result = this.items[this.lastIdx]; - this.lastIdx--; - return result; - } - takeCount(count: number): T[] { const result = this.items.slice(this.firstIdx, this.firstIdx + count); this.firstIdx += count; diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index 0979ef200e..d493ec7874 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -354,7 +354,9 @@ export class Delayer implements IDisposable { this.cancelTimeout(); if (this.completionPromise) { - this.doReject?.(new CancellationError()); + if (this.doReject) { + this.doReject(new CancellationError()); + } this.completionPromise = null; } } @@ -883,7 +885,9 @@ export class RunOnceScheduler { } protected doRun(): void { - this.runner?.(); + if (this.runner) { + this.runner(); + } } } @@ -956,7 +960,9 @@ export class ProcessTimeRunOnceScheduler { // time elapsed clearInterval(this.intervalToken); this.intervalToken = -1; - this.runner?.(); + if (this.runner) { + this.runner(); + } } } @@ -979,7 +985,9 @@ export class RunOnceWorker extends RunOnceScheduler { const units = this.units; this.units = []; - this.runner?.(units); + if (this.runner) { + this.runner(units); + } } override dispose(): void { diff --git a/src/vs/base/common/codicons.ts b/src/vs/base/common/codicons.ts index 9f94df4e4f..d87f016735 100644 --- a/src/vs/base/common/codicons.ts +++ b/src/vs/base/common/codicons.ts @@ -429,8 +429,7 @@ export class Codicon implements CSSIcon { public static readonly debugBreakpointFunction = new Codicon('debug-breakpoint-function', { fontCharacter: '\\eb88' }); public static readonly debugBreakpointFunctionDisabled = new Codicon('debug-breakpoint-function-disabled', { fontCharacter: '\\eb88' }); public static readonly debugStackframeActive = new Codicon('debug-stackframe-active', { fontCharacter: '\\eb89' }); - public static readonly circleSmallFilled = new Codicon('circle-small-filled', { fontCharacter: '\\eb8a' }); - public static readonly debugStackframeDot = new Codicon('debug-stackframe-dot', Codicon.circleSmallFilled.definition); + public static readonly debugStackframeDot = new Codicon('debug-stackframe-dot', { fontCharacter: '\\eb8a' }); public static readonly debugStackframe = new Codicon('debug-stackframe', { fontCharacter: '\\eb8b' }); public static readonly debugStackframeFocused = new Codicon('debug-stackframe-focused', { fontCharacter: '\\eb8b' }); public static readonly debugBreakpointUnsupported = new Codicon('debug-breakpoint-unsupported', { fontCharacter: '\\eb8c' }); @@ -543,9 +542,6 @@ export class Codicon implements CSSIcon { public static readonly layoutStatusbar = new Codicon('layout-statusbar', { fontCharacter: '\\ebf5' }); public static readonly layoutMenubar = new Codicon('layout-menubar', { fontCharacter: '\\ebf6' }); public static readonly layoutCentered = new Codicon('layout-centered', { fontCharacter: '\\ebf7' }); - public static readonly layoutSidebarRightOff = new Codicon('layout-sidebar-right-off', { fontCharacter: '\\ec00' }); - public static readonly layoutPanelOff = new Codicon('layout-panel-off', { fontCharacter: '\\ec01' }); - public static readonly layoutSidebarLeftOff = new Codicon('layout-sidebar-left-off', { fontCharacter: '\\ec02' }); public static readonly target = new Codicon('target', { fontCharacter: '\\ebf8' }); public static readonly indent = new Codicon('indent', { fontCharacter: '\\ebf9' }); public static readonly recordSmall = new Codicon('record-small', { fontCharacter: '\\ebfa' }); @@ -554,15 +550,6 @@ export class Codicon implements CSSIcon { public static readonly arrowCircleLeft = new Codicon('arrow-circle-left', { fontCharacter: '\\ebfd' }); public static readonly arrowCircleRight = new Codicon('arrow-circle-right', { fontCharacter: '\\ebfe' }); public static readonly arrowCircleUp = new Codicon('arrow-circle-up', { fontCharacter: '\\ebff' }); - public static readonly heartFilled = new Codicon('heart-filled', { fontCharacter: '\\ec04' }); - public static readonly map = new Codicon('map', { fontCharacter: '\\ec05' }); - public static readonly mapFilled = new Codicon('map-filled', { fontCharacter: '\\ec06' }); - public static readonly circleSmall = new Codicon('circle-small', { fontCharacter: '\\ec07' }); - public static readonly bellSlash = new Codicon('bell-slash', { fontCharacter: '\\ec08' }); - public static readonly bellSlashDot = new Codicon('bell-slash-dot', { fontCharacter: '\\ec09' }); - public static readonly commentUnresolved = new Codicon('comment-unresolved', { fontCharacter: '\\ec0a' }); - public static readonly gitPullRequestGoToChanges = new Codicon('git-pull-request-go-to-changes', { fontCharacter: '\\ec0b' }); - public static readonly gitPullRequestNewChanges = new Codicon('git-pull-request-new-changes', { fontCharacter: '\\ec0c' }); // derived icons, that could become separate icons @@ -625,7 +612,7 @@ export namespace CSSIcon { if (!match) { return asClassNameArray(Codicon.error); } - const [, id, modifier] = match; + let [, id, modifier] = match; // {{SQL CARBON EDIT}} Modifying method to not add 'codicon' in front of sql carbon icons. let sqlCarbonIcons: string[] = [SqlIconId.activeConnectionsAction, SqlIconId.addServerAction, SqlIconId.addServerGroupAction, SqlIconId.serverPage]; diff --git a/src/vs/base/common/collections.ts b/src/vs/base/common/collections.ts index 1c6bd89e5d..7f79571e3a 100644 --- a/src/vs/base/common/collections.ts +++ b/src/vs/base/common/collections.ts @@ -9,13 +9,13 @@ */ export type IStringDictionary = Record; + /** * An interface for a JavaScript object that * acts a dictionary. The keys are numbers. */ export type INumberDictionary = Record; -// {{ SQL CARBON EDIT }} - BEGIN - Needed to retrive values from IStringDictionary's and INumberDictionary's const hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -31,9 +31,6 @@ export function values(from: IStringDictionary | INumberDictionary): T[ } return result; } -// {{SQL CARBON EDIT}} - END - Needed to retrive values from IStringDictionary's and INumberDictionary's - -// {{ SQL CARBON EDIT }} - BEGIN - Adding forEach definition /** * Iterates over each entry in the provided dictionary. The iterator allows @@ -54,8 +51,6 @@ export function forEach(from: IStringDictionary | INumberDictionary, ca } } -// {{ SQL CARBON EDIT }} - END - Adding forEach definition - /** * Groups the collection into a dictionary based on the provided * group function. @@ -73,15 +68,25 @@ export function groupBy(data: V[], groupF return result; } +export function fromMap(original: Map): IStringDictionary { + const result: IStringDictionary = Object.create(null); + if (original) { + original.forEach((value, key) => { + result[key] = value; + }); + } + return result; +} + export function diffSets(before: Set, after: Set): { removed: T[]; added: T[] } { const removed: T[] = []; const added: T[] = []; - for (const element of before) { + for (let element of before) { if (!after.has(element)) { removed.push(element); } } - for (const element of after) { + for (let element of after) { if (!before.has(element)) { added.push(element); } @@ -92,12 +97,12 @@ export function diffSets(before: Set, after: Set): { removed: T[]; adde export function diffMaps(before: Map, after: Map): { removed: V[]; added: V[] } { const removed: V[] = []; const added: V[] = []; - for (const [index, value] of before) { + for (let [index, value] of before) { if (!after.has(index)) { removed.push(value); } } - for (const [index, value] of after) { + for (let [index, value] of after) { if (!before.has(index)) { added.push(value); } diff --git a/src/vs/base/common/comparers.ts b/src/vs/base/common/comparers.ts index 8df41f1917..61b28b5d26 100644 --- a/src/vs/base/common/comparers.ts +++ b/src/vs/base/common/comparers.ts @@ -219,7 +219,7 @@ function extractExtension(str?: string | null): string { function compareAndDisambiguateByLength(collator: Intl.Collator, one: string, other: string) { // Check for differences - const result = collator.compare(one, other); + let result = collator.compare(one, other); if (result !== 0) { return result; } diff --git a/src/vs/base/common/console.ts b/src/vs/base/common/console.ts index 6e5a975df3..94162c84f0 100644 --- a/src/vs/base/common/console.ts +++ b/src/vs/base/common/console.ts @@ -11,7 +11,7 @@ export interface IRemoteConsoleLog { arguments: string; } -export interface IStackArgument { +interface IStackArgument { __$stack: string; } diff --git a/src/vs/base/common/dataTransfer.ts b/src/vs/base/common/dataTransfer.ts deleted file mode 100644 index 02dbe6cdb7..0000000000 --- a/src/vs/base/common/dataTransfer.ts +++ /dev/null @@ -1,90 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { URI } from 'vs/base/common/uri'; - -export interface IDataTransferFile { - readonly name: string; - readonly uri?: URI; - data(): Promise; -} - -export interface IDataTransferItem { - asString(): Thenable; - asFile(): IDataTransferFile | undefined; - value: any; -} - -export function createStringDataTransferItem(stringOrPromise: string | Promise): IDataTransferItem { - return { - asString: async () => stringOrPromise, - asFile: () => undefined, - value: typeof stringOrPromise === 'string' ? stringOrPromise : undefined, - }; -} - -export function createFileDataTransferItem(fileName: string, uri: URI | undefined, data: () => Promise): IDataTransferItem { - return { - asString: async () => '', - asFile: () => ({ name: fileName, uri, data }), - value: undefined, - }; -} - -export class VSDataTransfer { - - private readonly _entries = new Map(); - - public get size(): number { - return this._entries.size; - } - - public has(mimeType: string): boolean { - return this._entries.has(this.toKey(mimeType)); - } - - public get(mimeType: string): IDataTransferItem | undefined { - return this._entries.get(this.toKey(mimeType))?.[0]; - } - - public append(mimeType: string, value: IDataTransferItem): void { - const existing = this._entries.get(mimeType); - if (existing) { - existing.push(value); - } else { - this._entries.set(this.toKey(mimeType), [value]); - } - } - - public replace(mimeType: string, value: IDataTransferItem): void { - this._entries.set(this.toKey(mimeType), [value]); - } - - public delete(mimeType: string) { - this._entries.delete(this.toKey(mimeType)); - } - - public *entries(): Iterable<[string, IDataTransferItem]> { - for (const [mine, items] of this._entries.entries()) { - for (const item of items) { - yield [mine, item]; - } - } - } - - public values(): Iterable { - return Array.from(this._entries.values()).flat(); - } - - public forEach(f: (value: IDataTransferItem, key: string) => void) { - for (const [mime, item] of this.entries()) { - f(item, mime); - } - } - - private toKey(mimeType: string): string { - return mimeType.toLowerCase(); - } -} diff --git a/src/vs/base/common/diff/diff.ts b/src/vs/base/common/diff/diff.ts index 382b7d6b19..485b2a8ce5 100644 --- a/src/vs/base/common/diff/diff.ts +++ b/src/vs/base/common/diff/diff.ts @@ -851,7 +851,7 @@ export class LcsDiff { change.modifiedStart++; } - const mergedChangeArr: Array = [null]; + let mergedChangeArr: Array = [null]; if (i < changes.length - 1 && this.ChangesOverlap(changes[i], changes[i + 1], mergedChangeArr)) { changes[i] = mergedChangeArr[0]!; changes.splice(i + 1, 1); @@ -1047,7 +1047,7 @@ export class LcsDiff { * @returns The concatenated list */ private ConcatenateChanges(left: DiffChange[], right: DiffChange[]): DiffChange[] { - const mergedChangeArr: DiffChange[] = []; + let mergedChangeArr: DiffChange[] = []; if (left.length === 0 || right.length === 0) { return (right.length > 0) ? right : left; diff --git a/src/vs/base/common/errors.ts b/src/vs/base/common/errors.ts index d00f276490..2ef9f0b28c 100644 --- a/src/vs/base/common/errors.ts +++ b/src/vs/base/common/errors.ts @@ -23,10 +23,6 @@ export class ErrorHandler { this.unexpectedErrorHandler = function (e: any) { setTimeout(() => { if (e.stack) { - if (ErrorNoTelemetry.isErrorNoTelemetry(e)) { - throw new ErrorNoTelemetry(e.message + '\n\n' + e.stack); - } - throw new Error(e.message + '\n\n' + e.stack); } @@ -99,14 +95,13 @@ export interface SerializedError { readonly name: string; readonly message: string; readonly stack: string; - readonly noTelemetry: boolean; } export function transformErrorForSerialization(error: Error): SerializedError; export function transformErrorForSerialization(error: any): any; export function transformErrorForSerialization(error: any): any { if (error instanceof Error) { - const { name, message } = error; + let { name, message } = error; let errorCode = (error).errorCode; // {{SQL CARBON EDIT}} Add error code to retain more information const stack: string = (error).stacktrace || (error).stack; return { @@ -241,27 +236,24 @@ export class ExpectedError extends Error { * Error that when thrown won't be logged in telemetry as an unhandled error. */ export class ErrorNoTelemetry extends Error { - override readonly name: string; - constructor(msg?: string) { - super(msg); - this.name = 'ErrorNoTelemetry'; - } - - public static fromError(err: Error): ErrorNoTelemetry { - if (err instanceof ErrorNoTelemetry) { + public static fromError(err: any): ErrorNoTelemetry { + if (err && err instanceof ErrorNoTelemetry) { return err; } - const result = new ErrorNoTelemetry(); - result.message = err.message; - result.stack = err.stack; - return result; + if (err && err instanceof Error) { + const result = new ErrorNoTelemetry(); + result.name = err.name; + result.message = err.message; + result.stack = err.stack; + return result; + } + + return new ErrorNoTelemetry(err); } - public static isErrorNoTelemetry(err: Error): err is ErrorNoTelemetry { - return err.name === 'ErrorNoTelemetry'; - } + readonly logTelemetry = false; } /** @@ -270,8 +262,8 @@ export class ErrorNoTelemetry extends Error { * Only catch this error to recover gracefully from bugs. */ export class BugIndicatingError extends Error { - constructor(message?: string) { - super(message || 'An unexpected bug occurred.'); + constructor(message: string) { + super(message); Object.setPrototypeOf(this, BugIndicatingError.prototype); // Because we know for sure only buggy code throws this, diff --git a/src/vs/base/common/event.ts b/src/vs/base/common/event.ts index 91e039f410..0b713da184 100644 --- a/src/vs/base/common/event.ts +++ b/src/vs/base/common/event.ts @@ -8,14 +8,13 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { once as onceFn } from 'vs/base/common/functional'; import { combinedDisposable, Disposable, DisposableStore, IDisposable, SafeDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { LinkedList } from 'vs/base/common/linkedList'; -import { IObservable, IObserver } from 'vs/base/common/observable'; import { StopWatch } from 'vs/base/common/stopwatch'; // ----------------------------------------------------------------------------------------------------------------------- // Uncomment the next line to print warnings whenever an emitter with listeners is disposed. That is a sign of code smell. // ----------------------------------------------------------------------------------------------------------------------- -const _enableDisposeWithListenerWarning = false; +let _enableDisposeWithListenerWarning = false; // _enableDisposeWithListenerWarning = Boolean("TRUE"); // causes a linter warning so that it cannot be pushed @@ -23,7 +22,7 @@ const _enableDisposeWithListenerWarning = false; // Uncomment the next line to print warnings whenever a snapshotted event is used repeatedly without cleanup. // See https://github.com/microsoft/vscode/issues/142851 // ----------------------------------------------------------------------------------------------------------------------- -const _enableSnapshotPotentialLeakWarning = false; +let _enableSnapshotPotentialLeakWarning = false; // _enableSnapshotPotentialLeakWarning = Boolean("TRUE"); // causes a linter warning so that it cannot be pushed /** @@ -61,7 +60,7 @@ export namespace Event { return (listener, thisArgs = null, disposables?) => { // we need this, in case the event fires during the listener call let didFire = false; - let result: IDisposable | undefined = undefined; + let result: IDisposable; result = event(e => { if (didFire) { return; @@ -144,14 +143,14 @@ export namespace Event { } function snapshot(event: Event, disposable: DisposableStore | undefined): Event { - let listener: IDisposable | undefined; + let listener: IDisposable; const options: EmitterOptions | undefined = { onFirstListenerAdd() { listener = event(emitter.fire, emitter); }, onLastListenerRemove() { - listener?.dispose(); + listener.dispose(); } }; @@ -161,7 +160,9 @@ export namespace Event { const emitter = new Emitter(options); - disposable?.add(emitter); + if (disposable) { + disposable.add(emitter); + } return emitter.event; } @@ -222,7 +223,9 @@ export namespace Event { const emitter = new Emitter(options); - disposable?.add(emitter); + if (disposable) { + disposable.add(emitter); + } return emitter.event; } @@ -273,7 +276,9 @@ export namespace Event { }); const flush = () => { - buffer?.forEach(e => emitter.fire(e)); + if (buffer) { + buffer.forEach(e => emitter.fire(e)); + } buffer = null; }; @@ -305,7 +310,7 @@ export namespace Event { return emitter.event; } - export interface IChainableEvent extends IDisposable { + export interface IChainableEvent { event: Event; map(fn: (i: T) => O): IChainableEvent; @@ -322,36 +327,34 @@ export namespace Event { class ChainableEvent implements IChainableEvent { - private readonly disposables = new DisposableStore(); - constructor(readonly event: Event) { } map(fn: (i: T) => O): IChainableEvent { - return new ChainableEvent(map(this.event, fn, this.disposables)); + return new ChainableEvent(map(this.event, fn)); } forEach(fn: (i: T) => void): IChainableEvent { - return new ChainableEvent(forEach(this.event, fn, this.disposables)); + return new ChainableEvent(forEach(this.event, fn)); } filter(fn: (e: T) => boolean): IChainableEvent; filter(fn: (e: T | R) => e is R): IChainableEvent; filter(fn: (e: T) => boolean): IChainableEvent { - return new ChainableEvent(filter(this.event, fn, this.disposables)); + return new ChainableEvent(filter(this.event, fn)); } reduce(merge: (last: R | undefined, event: T) => R, initial?: R): IChainableEvent { - return new ChainableEvent(reduce(this.event, merge, initial, this.disposables)); + return new ChainableEvent(reduce(this.event, merge, initial)); } latch(): IChainableEvent { - return new ChainableEvent(latch(this.event, undefined, this.disposables)); + return new ChainableEvent(latch(this.event)); } debounce(merge: (last: T | undefined, event: T) => T, delay?: number, leading?: boolean, leakWarningThreshold?: number): IChainableEvent; debounce(merge: (last: R | undefined, event: T) => R, delay?: number, leading?: boolean, leakWarningThreshold?: number): IChainableEvent; debounce(merge: (last: R | undefined, event: T) => R, delay: number = 100, leading = false, leakWarningThreshold?: number): IChainableEvent { - return new ChainableEvent(debounce(this.event, merge, delay, leading, leakWarningThreshold, this.disposables)); + return new ChainableEvent(debounce(this.event, merge, delay, leading, leakWarningThreshold)); } on(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[] | DisposableStore) { @@ -361,12 +364,11 @@ export namespace Event { once(listener: (e: T) => any, thisArgs: any, disposables: IDisposable[]) { return once(this.event)(listener, thisArgs, disposables); } - - dispose() { - this.disposables.dispose(); - } } + /** + * @deprecated DO NOT use, this leaks memory + */ export function chain(event: Event): IChainableEvent { return new ChainableEvent(event); } @@ -424,55 +426,6 @@ export namespace Event { store?.dispose(); }); } - - class EmitterObserver implements IObserver { - - readonly emitter: Emitter; - - private _counter = 0; - private _hasChanged = false; - - constructor(readonly obs: IObservable, store: DisposableStore | undefined) { - const options = { - onFirstListenerAdd: () => { - obs.addObserver(this); - }, - onLastListenerRemove: () => { - obs.removeObserver(this); - } - }; - if (!store) { - _addLeakageTraceLogic(options); - } - this.emitter = new Emitter(options); - if (store) { - store.add(this.emitter); - } - } - - beginUpdate(_observable: IObservable): void { - // console.assert(_observable === this.obs); - this._counter++; - } - - handleChange(_observable: IObservable, _change: TChange): void { - this._hasChanged = true; - } - - endUpdate(_observable: IObservable): void { - if (--this._counter === 0) { - if (this._hasChanged) { - this._hasChanged = false; - this.emitter.fire(this.obs.get()); - } - } - } - } - - export function fromObservable(obs: IObservable, store?: DisposableStore): Event { - const observer = new EmitterObserver(obs, store); - return observer.emitter.event; - } } export interface EmitterOptions { @@ -737,7 +690,9 @@ export class Emitter { } const result = listener.subscription.set(() => { - removeMonitor?.(); + if (removeMonitor) { + removeMonitor(); + } if (!this._disposed) { removeListener(); if (this._options && this._options.onLastListenerRemove) { @@ -775,7 +730,7 @@ export class Emitter { this._deliveryQueue = new PrivateEventDeliveryQueue(); } - for (const listener of this._listeners) { + for (let listener of this._listeners) { this._deliveryQueue.push(this, listener, event); } diff --git a/src/vs/base/common/fuzzyScorer.ts b/src/vs/base/common/fuzzyScorer.ts index 8bf09d8522..9d30cdf518 100644 --- a/src/vs/base/common/fuzzyScorer.ts +++ b/src/vs/base/common/fuzzyScorer.ts @@ -315,7 +315,7 @@ function doScoreFuzzy2Multiple(target: string, query: IPreparedQueryPiece[], pat } function doScoreFuzzy2Single(target: string, query: IPreparedQueryPiece, patternStart: number, wordStart: number): FuzzyScore2 { - const score = fuzzyScore(query.original, query.originalLowercase, patternStart, target, target.toLowerCase(), wordStart, { firstMatchCanBeWeak: true, boostFullMatch: true }); + const score = fuzzyScore(query.original, query.originalLowercase, patternStart, target, target.toLowerCase(), wordStart); if (!score) { return NO_SCORE2; } diff --git a/src/vs/base/common/htmlContent.ts b/src/vs/base/common/htmlContent.ts index 2c4f32cf17..219e564a23 100644 --- a/src/vs/base/common/htmlContent.ts +++ b/src/vs/base/common/htmlContent.ts @@ -139,10 +139,6 @@ export function escapeMarkdownSyntaxTokens(text: string): string { return text.replace(/[\\`*_{}[\]()#+\-!]/g, '\\$&'); } -export function escapeDoubleQuotes(input: string) { - return input.replace(/"/g, '"'); -} - export function removeMarkdownEscapes(text: string): string { if (!text) { return text; diff --git a/src/vs/base/common/json.ts b/src/vs/base/common/json.ts index 3dcdea66df..e0f740a7a6 100644 --- a/src/vs/base/common/json.ts +++ b/src/vs/base/common/json.ts @@ -200,12 +200,12 @@ export interface JSONVisitor { */ export function createScanner(text: string, ignoreTrivia: boolean = false): JSONScanner { - let pos = 0; - const len = text.length; - let value: string = ''; - let tokenOffset = 0; - let token: SyntaxKind = SyntaxKind.Unknown; - let scanError: ScanError = ScanError.None; + let pos = 0, + len = text.length, + value: string = '', + tokenOffset = 0, + token: SyntaxKind = SyntaxKind.Unknown, + scanError: ScanError = ScanError.None; function scanHexDigits(count: number): number { let digits = 0; @@ -963,7 +963,7 @@ export function findNodeAtLocation(root: Node, path: JSONPath): Node | undefined return undefined; } let node = root; - for (const segment of path) { + for (let segment of path) { if (typeof segment === 'string') { if (node.type !== 'object' || !Array.isArray(node.children)) { return undefined; @@ -1019,7 +1019,7 @@ export function getNodeValue(node: Node): any { return node.children!.map(getNodeValue); case 'object': { const obj = Object.create(null); - for (const prop of node.children!) { + for (let prop of node.children!) { const valueNode = prop.children![1]; if (valueNode) { obj[prop.children![0].value] = getNodeValue(valueNode); @@ -1315,11 +1315,11 @@ export function visit(text: string, visitor: JSONVisitor, options: ParseOptions */ export function stripComments(text: string, replaceCh?: string): string { - const _scanner = createScanner(text); - const parts: string[] = []; - let kind: SyntaxKind; - let offset = 0; - let pos: number; + let _scanner = createScanner(text), + parts: string[] = [], + kind: SyntaxKind, + offset = 0, + pos: number; do { pos = _scanner.getPosition(); diff --git a/src/vs/base/common/jsonEdit.ts b/src/vs/base/common/jsonEdit.ts index 886df59218..5219796362 100644 --- a/src/vs/base/common/jsonEdit.ts +++ b/src/vs/base/common/jsonEdit.ts @@ -155,7 +155,7 @@ export function applyEdit(text: string, edit: Edit): string { } export function applyEdits(text: string, edits: Edit[]): string { - const sortedEdits = edits.slice(0).sort((a, b) => { + let sortedEdits = edits.slice(0).sort((a, b) => { const diff = a.offset - b.offset; if (diff === 0) { return a.length - b.length; @@ -164,7 +164,7 @@ export function applyEdits(text: string, edits: Edit[]): string { }); let lastModifiedOffset = text.length; for (let i = sortedEdits.length - 1; i >= 0; i--) { - const e = sortedEdits[i]; + let e = sortedEdits[i]; if (e.offset + e.length <= lastModifiedOffset) { text = applyEdit(text, e); } else { diff --git a/src/vs/base/common/jsonSchema.ts b/src/vs/base/common/jsonSchema.ts index c75f6dae7c..8834dc3807 100644 --- a/src/vs/base/common/jsonSchema.ts +++ b/src/vs/base/common/jsonSchema.ts @@ -46,7 +46,6 @@ export interface IJSONSchema { const?: any; contains?: IJSONSchema; propertyNames?: IJSONSchema; - examples?: any[]; // schema draft 07 $comment?: string; @@ -54,27 +53,7 @@ export interface IJSONSchema { then?: IJSONSchema; else?: IJSONSchema; - // schema 2019-09 - unevaluatedProperties?: boolean | IJSONSchema; - unevaluatedItems?: boolean | IJSONSchema; - minContains?: number; - maxContains?: number; - deprecated?: boolean; - dependentRequired?: { [prop: string]: string[] }; - dependentSchemas?: IJSONSchemaMap; - $defs?: { [name: string]: IJSONSchema }; - $anchor?: string; - $recursiveRef?: string; - $recursiveAnchor?: string; - $vocabulary?: any; - - // schema 2020-12 - prefixItems?: IJSONSchema[]; - $dynamicRef?: string; - $dynamicAnchor?: string; - - // VSCode extensions - + // VS Code extensions defaultSnippets?: IJSONSchemaSnippet[]; errorMessage?: string; patternErrorMessage?: string; diff --git a/src/vs/base/common/keyCodes.ts b/src/vs/base/common/keyCodes.ts index 282e7f3aa8..332cd91b71 100644 --- a/src/vs/base/common/keyCodes.ts +++ b/src/vs/base/common/keyCodes.ts @@ -722,8 +722,8 @@ for (let i = 0; i <= KeyCode.MAX_VALUE; i++) { [0, 1, ScanCode.None, empty, KeyCode.Unknown, empty, 0, 'VK_OEM_CLEAR', empty, empty], ]; - const seenKeyCode: boolean[] = []; - const seenScanCode: boolean[] = []; + let seenKeyCode: boolean[] = []; + let seenScanCode: boolean[] = []; for (const mapping of mappings) { const [_keyCodeOrd, immutable, scanCode, scanCodeStr, keyCode, keyCodeStr, eventKeyCode, vkey, usUserSettingsLabel, generalUserSettingsLabel] = mapping; if (!seenScanCode[scanCode]) { diff --git a/src/vs/base/common/labels.ts b/src/vs/base/common/labels.ts index dd35571a25..7d161badcd 100644 --- a/src/vs/base/common/labels.ts +++ b/src/vs/base/common/labels.ts @@ -4,10 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { firstOrDefault } from 'vs/base/common/arrays'; -import { hasDriveLetter, toSlashes } from 'vs/base/common/extpath'; +import { hasDriveLetter, isRootOrDriveLetter, toSlashes } from 'vs/base/common/extpath'; +import { Schemas } from 'vs/base/common/network'; import { posix, sep, win32 } from 'vs/base/common/path'; import { isMacintosh, isWindows, OperatingSystem, OS } from 'vs/base/common/platform'; -import { extUri, extUriIgnorePathCase } from 'vs/base/common/resources'; +import { basename, extUri, extUriIgnorePathCase } from 'vs/base/common/resources'; import { rtrim, startsWithIgnoreCase } from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; @@ -73,7 +74,7 @@ export function getPathLabel(resource: URI, formatting: IPathLabelFormatting): s // macOS/Linux: tildify with provided user home directory if (os !== OperatingSystem.Windows && tildifier?.userHome) { - const userHome = tildifier.userHome.fsPath; + let userHome = tildifier.userHome.fsPath; // This is a bit of a hack, but in order to figure out if the // resource is in the user home, we need to make sure to convert it @@ -138,6 +139,27 @@ function getRelativePathLabel(resource: URI, relativePathProvider: IRelativePath return relativePathLabel; } +export function getBaseLabel(resource: URI | string): string; +export function getBaseLabel(resource: URI | string | undefined): string | undefined; +export function getBaseLabel(resource: URI | string | undefined): string | undefined { + if (!resource) { + return undefined; + } + + if (typeof resource === 'string') { + resource = URI.file(resource); + } + + const base = basename(resource) || (resource.scheme === Schemas.file ? resource.fsPath : resource.path) /* can be empty string if '/' is passed in */; + + // convert c: => C: + if (isWindows && isRootOrDriveLetter(base)) { + return normalizeDriveLetter(base); + } + + return base; +} + export function normalizeDriveLetter(path: string, isWindowsOS: boolean = isWindows): string { if (hasDriveLetter(path, isWindowsOS)) { return path.charAt(0).toUpperCase() + path.slice(1); @@ -217,7 +239,7 @@ export function shorten(paths: string[], pathSeparator: string = sep): string[] // for every path let match = false; for (let pathIndex = 0; pathIndex < paths.length; pathIndex++) { - const originalPath = paths[pathIndex]; + let originalPath = paths[pathIndex]; if (originalPath === '') { shortenedPaths[pathIndex] = `.${pathSeparator}`; diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index 6bb098754a..e377bcf55d 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -131,7 +131,7 @@ export function dispose(disposables: Array): Array; export function dispose(disposables: ReadonlyArray): ReadonlyArray; export function dispose(arg: T | IterableIterator | undefined): any { if (Iterable.is(arg)) { - const errors: any[] = []; + let errors: any[] = []; for (const d of arg) { if (d) { diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index d50f2b5747..24cf310150 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -371,13 +371,13 @@ export class TernarySearchTree { if (keys) { const arr = keys.slice(0); shuffle(arr); - for (const k of arr) { + for (let k of arr) { this.set(k, (values)); } } else { const arr = (<[K, V][]>values).slice(0); shuffle(arr); - for (const entry of arr) { + for (let entry of arr) { this.set(entry[0], entry[1]); } } @@ -715,28 +715,22 @@ export class TernarySearchTree { yield* this._entries(this._root); } - private _entries(node: TernarySearchTreeNode | undefined): IterableIterator<[K, V]> { - const result: [K, V][] = []; - this._dfsEntries(node, result); - return result[Symbol.iterator](); - } - - private _dfsEntries(node: TernarySearchTreeNode | undefined, bucket: [K, V][]) { + private *_entries(node: TernarySearchTreeNode | undefined): IterableIterator<[K, V]> { // DFS if (!node) { return; } if (node.left) { - this._dfsEntries(node.left, bucket); + yield* this._entries(node.left); } if (node.value) { - bucket.push([node.key!, node.value]); + yield [node.key!, node.value]; } if (node.mid) { - this._dfsEntries(node.mid, bucket); + yield* this._entries(node.mid); } if (node.right) { - this._dfsEntries(node.right, bucket); + yield* this._entries(node.right); } } @@ -825,31 +819,31 @@ export class ResourceMap implements Map { if (typeof thisArg !== 'undefined') { clb = clb.bind(thisArg); } - for (const [_, entry] of this.map) { + for (let [_, entry] of this.map) { clb(entry.value, entry.uri, this); } } *values(): IterableIterator { - for (const entry of this.map.values()) { + for (let entry of this.map.values()) { yield entry.value; } } *keys(): IterableIterator { - for (const entry of this.map.values()) { + for (let entry of this.map.values()) { yield entry.uri; } } *entries(): IterableIterator<[URI, T]> { - for (const entry of this.map.values()) { + for (let entry of this.map.values()) { yield [entry.uri, entry.value]; } } *[Symbol.iterator](): IterableIterator<[URI, T]> { - for (const [, entry] of this.map) { + for (let [, entry] of this.map) { yield [entry.uri, entry.value]; } } diff --git a/src/vs/base/common/marked/cgmanifest.json b/src/vs/base/common/marked/cgmanifest.json index 60e11b4144..47100d82d7 100644 --- a/src/vs/base/common/marked/cgmanifest.json +++ b/src/vs/base/common/marked/cgmanifest.json @@ -6,11 +6,11 @@ "git": { "name": "marked", "repositoryUrl": "https://github.com/markedjs/marked", - "commitHash": "2002557d004139ca2208c910d9ca999829b65406" + "commitHash": "d1b7d521c41bcf915f81f0218b0e5acd607c1b72" } }, "license": "MIT", - "version": "4.0.16" + "version": "3.0.2" } ], "version": 1 diff --git a/src/vs/base/common/marked/marked.js b/src/vs/base/common/marked/marked.js index b7d8fe40e5..09c308378d 100644 --- a/src/vs/base/common/marked/marked.js +++ b/src/vs/base/common/marked/marked.js @@ -23,7 +23,6 @@ typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.marked = {})); })(this, (function (exports) { 'use strict'; - function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; @@ -142,10 +141,6 @@ return html; } var unescapeTest = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig; - /** - * @param {string} html - */ - function unescape(html) { // explicitly match decimal, hex, and named HTML entities return html.replace(unescapeTest, function (_, n) { @@ -160,13 +155,8 @@ }); } var caret = /(^|[^\[])\^/g; - /** - * @param {string | RegExp} regex - * @param {string} opt - */ - function edit(regex, opt) { - regex = typeof regex === 'string' ? regex : regex.source; + regex = regex.source || regex; opt = opt || ''; var obj = { replace: function replace(name, val) { @@ -183,12 +173,6 @@ } var nonWordAndColonTest = /[^\w:]/g; var originIndependentUrl = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i; - /** - * @param {boolean} sanitize - * @param {string} base - * @param {string} href - */ - function cleanUrl(sanitize, base, href) { if (sanitize) { var prot; @@ -220,11 +204,6 @@ var justDomain = /^[^:]+:\/*[^/]*$/; var protocol = /^([^:]+:)[\s\S]*$/; var domain = /^([^:]+:\/*[^/]*)[\s\S]*$/; - /** - * @param {string} base - * @param {string} href - */ - function resolveUrl(base, href) { if (!baseUrls[' ' + base]) { // we can ignore everything in base after the last slash of its path component, @@ -303,7 +282,7 @@ cells.shift(); } - if (cells.length > 0 && !cells[cells.length - 1].trim()) { + if (!cells[cells.length - 1].trim()) { cells.pop(); } @@ -321,15 +300,9 @@ } return cells; - } - /** - * Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). - * /c*$/ is vulnerable to REDOS. - * - * @param {string} str - * @param {string} c - * @param {boolean} invert Remove suffix of non-c chars instead. Default falsey. - */ + } // Remove trailing 'c's. Equivalent to str.replace(/c*$/, ''). + // /c*$/ is vulnerable to REDOS. + // invert: Remove suffix of non-c chars instead. Default falsey. function rtrim(str, c, invert) { var l = str.length; @@ -353,7 +326,7 @@ } } - return str.slice(0, l - suffLen); + return str.substr(0, l - suffLen); } function findClosingBracket(str, b) { if (str.indexOf(b[1]) === -1) { @@ -386,11 +359,6 @@ } } // copied from https://stackoverflow.com/a/5450113/806777 - /** - * @param {string} pattern - * @param {number} count - */ - function repeatString(pattern, count) { if (count < 1) { return ''; @@ -427,15 +395,15 @@ }; lexer.state.inLink = false; return token; + } else { + return { + type: 'image', + raw: raw, + href: href, + title: title, + text: escape(text) + }; } - - return { - type: 'image', - raw: raw, - href: href, - title: title, - text: escape(text) - }; } function indentCodeCompensation(raw, text) { @@ -478,11 +446,11 @@ var cap = this.rules.block.newline.exec(src); if (cap && cap[0].length > 0) { - return { - type: 'space', - raw: cap[0] - }; - } + return { + type: 'space', + raw: cap[0] + }; + } }; _proto.code = function code(src) { @@ -558,7 +526,7 @@ var cap = this.rules.block.blockquote.exec(src); if (cap) { - var text = cap[0].replace(/^ *>[ \t]?/gm, ''); + var text = cap[0].replace(/^ *> ?/gm, ''); return { type: 'blockquote', raw: cap[0], @@ -590,7 +558,7 @@ } // Get next list item - var itemRegex = new RegExp("^( {0,3}" + bull + ")((?:[\t ][^\\n]*)?(?:\\n|$))"); // Check if current bullet point can start a new List Item + var itemRegex = new RegExp("^( {0,3}" + bull + ")((?: [^\\n]*)?(?:\\n|$))"); // Check if current bullet point can start a new List Item while (src) { endEarly = false; @@ -631,37 +599,31 @@ } if (!endEarly) { - var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])((?: [^\\n]*)?(?:\\n|$))"); - var hrRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)"); // Check if following lines should be included in List Item + var nextBulletRegex = new RegExp("^ {0," + Math.min(3, indent - 1) + "}(?:[*+-]|\\d{1,9}[.)])"); // Check if following lines should be included in List Item while (src) { rawLine = src.split('\n', 1)[0]; line = rawLine; // Re-align to follow commonmark nesting rules - if (this.options.pedantic) { - line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); - } // End list item if found start of new bullet + if (this.options.pedantic) { + line = line.replace(/^ {1,4}(?=( {4})*[^ ])/g, ' '); + } // End list item if found start of new bullet - if (nextBulletRegex.test(line)) { - break; - } // Horizontal rule found - - - if (hrRegex.test(src)) { - break; + if (nextBulletRegex.test(line)) { + break; } - if (line.search(/[^ ]/) >= indent || !line.trim()) { + if (line.search(/[^ ]/) >= indent || !line.trim()) { // Dedent if possible - itemContents += '\n' + line.slice(indent); + itemContents += '\n' + line.slice(indent); } else if (!blankLine) { // Until blank line, item doesn't need indentation itemContents += '\n' + line; - } else { + } else { // Otherwise, improper indentation ends this item - break; - } + break; + } if (!blankLine && !line.trim()) { // Check if current line is blank @@ -795,7 +757,7 @@ }; }), align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), - rows: cap[3] && cap[3].trim() ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] + rows: cap[3] ? cap[3].replace(/\n[ \t]*$/, '').split('\n') : [] }; if (item.header.length === item.align.length) { @@ -831,7 +793,7 @@ for (j = 0; j < l; j++) { item.header[j].tokens = []; - this.lexer.inline(item.header[j].text, item.header[j].tokens); + this.lexer.inlineTokens(item.header[j].text, item.header[j].tokens); } // cell child tokens @@ -842,7 +804,7 @@ for (k = 0; k < row.length; k++) { row[k].tokens = []; - this.lexer.inline(row[k].text, row[k].tokens); + this.lexer.inlineTokens(row[k].text, row[k].tokens); } } @@ -1233,10 +1195,10 @@ newline: /^(?: *(?:\n|$))+/, code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/, fences: /^ {0,3}(`{3,}(?=[^`\n]*\n)|~{3,})([^\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?=\n|$)|$)/, - hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/, + hr: /^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/, heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/, blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/, - list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/, + list: /^( {0,3}bull)( [^\n]+?)?(?:\n|$)/, html: '^ {0,3}(?:' // optional indentation + '<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)' // (1) + '|comment[^\\n]*(\\n+|$)' // (2) @@ -1326,9 +1288,9 @@ emStrong: { lDelim: /^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/, // (1) and (2) can only be a Right Delimiter. (3) and (4) can only be Left. (5) and (6) can be either Left or Right. - // () Skip orphan inside strong () Consume to delim (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a - rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[^*]+(?=[^*])|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, - rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ + // () Skip orphan delim inside strong (1) #*** (2) a***#, a*** (3) #***a, ***a (4) ***# (5) #***# (6) a***a + rDelimAst: /^[^_*]*?\_\_[^_*]*?\*[^_*]*?(?=\_\_)|[punct_](\*+)(?=[\s]|$)|[^punct*_\s](\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|[^punct*_\s](\*+)(?=[^punct*_\s])/, + rDelimUnd: /^[^_*]*?\*\*[^_*]*?\_[^_*]*?(?=\*\*)|[punct*](\_+)(?=[\s]|$)|[^punct*_\s](\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/ // ^- Not allowed for _ }, code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/, @@ -1410,7 +1372,6 @@ /** * smartypants text replacement - * @param {string} text */ function smartypants(text) { @@ -1425,7 +1386,6 @@ } /** * mangle email addresses - * @param {string} text */ @@ -1516,7 +1476,7 @@ var _proto = Lexer.prototype; _proto.lex = function lex(src) { - src = src.replace(/\r\n|\r/g, '\n'); + src = src.replace(/\r\n|\r/g, '\n').replace(/\t/g, ' '); this.blockTokens(src, this.tokens); var next; @@ -1539,11 +1499,7 @@ } if (this.options.pedantic) { - src = src.replace(/\t/g, ' ').replace(/^ +$/gm, ''); - } else { - src = src.replace(/^( *)(\t+)/gm, function (_, leading, tabs) { - return leading + ' '.repeat(tabs.length); - }); + src = src.replace(/^ +$/gm, ''); } var token, lastToken, cutSrc, lastParagraphClipped; @@ -2003,35 +1959,23 @@ } return '
' + (escaped ? _code : escape(_code, true)) + '
\n'; - } - /** - * @param {string} quote - */ - ; + }; _proto.blockquote = function blockquote(quote) { - return "
\n" + quote + "
\n"; + return '
\n' + quote + '
\n'; }; _proto.html = function html(_html) { return _html; - } - /** - * @param {string} text - * @param {string} level - * @param {string} raw - * @param {any} slugger - */ - ; + }; _proto.heading = function heading(text, level, raw, slugger) { if (this.options.headerIds) { - var id = this.options.headerPrefix + slugger.slug(raw); - return "" + text + "\n"; + return '' + text + '\n'; } // ignore IDs - return "" + text + "\n"; + return '' + text + '\n'; }; _proto.hr = function hr() { @@ -2042,94 +1986,55 @@ var type = ordered ? 'ol' : 'ul', startatt = ordered && start !== 1 ? ' start="' + start + '"' : ''; return '<' + type + startatt + '>\n' + body + '\n'; - } - /** - * @param {string} text - */ - ; + }; _proto.listitem = function listitem(text) { - return "
  • " + text + "
  • \n"; + return '
  • ' + text + '
  • \n'; }; _proto.checkbox = function checkbox(checked) { return ' '; - } - /** - * @param {string} text - */ - ; + }; _proto.paragraph = function paragraph(text) { - return "

    " + text + "

    \n"; - } - /** - * @param {string} header - * @param {string} body - */ - ; + return '

    ' + text + '

    \n'; + }; _proto.table = function table(header, body) { - if (body) body = "" + body + ""; + if (body) body = '' + body + ''; return '\n' + '\n' + header + '\n' + body + '
    \n'; - } - /** - * @param {string} content - */ - ; + }; _proto.tablerow = function tablerow(content) { - return "\n" + content + "\n"; + return '\n' + content + '\n'; }; _proto.tablecell = function tablecell(content, flags) { var type = flags.header ? 'th' : 'td'; - var tag = flags.align ? "<" + type + " align=\"" + flags.align + "\">" : "<" + type + ">"; - return tag + content + ("\n"); - } - /** - * span level renderer - * @param {string} text - */ + var tag = flags.align ? '<' + type + ' align="' + flags.align + '">' : '<' + type + '>'; + return tag + content + '\n'; + } // span level renderer ; _proto.strong = function strong(text) { - return "" + text + ""; - } - /** - * @param {string} text - */ - ; + return '' + text + ''; + }; _proto.em = function em(text) { - return "" + text + ""; - } - /** - * @param {string} text - */ - ; + return '' + text + ''; + }; _proto.codespan = function codespan(text) { - return "" + text + ""; + return '' + text + ''; }; _proto.br = function br() { return this.options.xhtml ? '
    ' : '
    '; - } - /** - * @param {string} text - */ - ; + }; _proto.del = function del(text) { - return "" + text + ""; - } - /** - * @param {string} href - * @param {string} title - * @param {string} text - */ - ; + return '' + text + ''; + }; _proto.link = function link(href, title, text) { href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); @@ -2146,13 +2051,7 @@ out += '>' + text + ''; return out; - } - /** - * @param {string} href - * @param {string} title - * @param {string} text - */ - ; + }; _proto.image = function image(href, title, text) { href = cleanUrl(this.options.sanitize, this.options.baseUrl, href); @@ -2161,10 +2060,10 @@ return text; } - var out = "\""' : '>'; @@ -2234,10 +2133,6 @@ function Slugger() { this.seen = {}; } - /** - * @param {string} value - */ - var _proto = Slugger.prototype; @@ -2248,8 +2143,6 @@ } /** * Finds the next safe (unique) slug to use - * @param {string} originalSlug - * @param {boolean} isDryRun */ ; @@ -2275,9 +2168,8 @@ } /** * Convert string to unique id - * @param {object} [options] - * @param {boolean} [options.dryrun] Generates the next unique slug without - * updating the internal accumulator. + * @param {object} options + * @param {boolean} options.dryrun Generates the next unique slug without updating the internal accumulator. */ ; @@ -2974,7 +2866,6 @@ }; /** * Parse Inline - * @param {string} src */ @@ -3050,7 +2941,6 @@ exports.walkTokens = walkTokens; Object.defineProperty(exports, '__esModule', { value: true }); - })); // ESM-uncomment-begin diff --git a/src/vs/base/common/mime.ts b/src/vs/base/common/mime.ts index 6378548d9e..b43d99845c 100644 --- a/src/vs/base/common/mime.ts +++ b/src/vs/base/common/mime.ts @@ -5,14 +5,14 @@ import { extname } from 'vs/base/common/path'; -export const Mimes = Object.freeze({ - text: 'text/plain', - binary: 'application/octet-stream', - unknown: 'application/unknown', - markdown: 'text/markdown', - latex: 'text/latex', - uriList: 'text/uri-list', -}); +export namespace Mimes { + export const text = 'text/plain'; + export const binary = 'application/octet-stream'; + export const unknown = 'application/unknown'; + export const markdown = 'text/markdown'; + export const latex = 'text/latex'; + export const uriList = 'text/uri-list'; +} interface MapExtToMediaMimes { [index: string]: string; diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index a6c0747626..665b2cd3a5 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -103,11 +103,6 @@ export namespace Schemas { * Scheme used vs live share */ export const vsls = 'vsls'; - - /** - * Scheme used for the Source Control commit input's text document - */ - export const vscodeSourceControl = 'vscode-scm'; } export const connectionTokenCookieName = 'vscode-tkn'; @@ -121,7 +116,6 @@ class RemoteAuthoritiesImpl { private readonly _connectionTokens: { [authority: string]: string | undefined } = Object.create(null); private _preferredWebSchema: 'http' | 'https' = 'http'; private _delegate: ((uri: URI) => URI) | null = null; - private _remoteResourcesPath: string = `/${Schemas.vscodeRemoteResource}`; setPreferredWebSchema(schema: 'http' | 'https') { this._preferredWebSchema = schema; @@ -131,10 +125,6 @@ class RemoteAuthoritiesImpl { this._delegate = delegate; } - setServerRootPath(serverRootPath: string): void { - this._remoteResourcesPath = `${serverRootPath}/${Schemas.vscodeRemoteResource}`; - } - set(authority: string, host: string, port: number): void { this._hosts[authority] = host; this._ports[authority] = port; @@ -166,7 +156,7 @@ class RemoteAuthoritiesImpl { return URI.from({ scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource, authority: platform.isWeb && port === this._defaultWebPort ? `${host}` : `${host}:${port}`, // {{SQL CARBON EDIT}} addresses same-origin-policy violation in web mode when port number is in authority, but not in URI. - path: this._remoteResourcesPath, + path: `/vscode-remote-resource`, query }); } diff --git a/src/vs/base/common/objects.ts b/src/vs/base/common/objects.ts index b87b079948..24a5b41adf 100644 --- a/src/vs/base/common/objects.ts +++ b/src/vs/base/common/objects.ts @@ -75,7 +75,7 @@ function _cloneAndChange(obj: any, changer: (orig: any) => any, seen: Set): } seen.add(obj); const r2 = {}; - for (const i2 in obj) { + for (let i2 in obj) { if (_hasOwnProperty.call(obj, i2)) { (r2 as any)[i2] = _cloneAndChange(obj[i2], changer, seen); } @@ -186,7 +186,6 @@ export function safeStringify(obj: any): string { }); } -// {{SQL CARBON EDIT}} - define getOrDefault export function getOrDefault(obj: T, fn: (obj: T) => R | undefined, defaultValue: R): R { const result = fn(obj); return typeof result === 'undefined' ? defaultValue : result; diff --git a/src/vs/base/common/observable.ts b/src/vs/base/common/observable.ts deleted file mode 100644 index 850a642d73..0000000000 --- a/src/vs/base/common/observable.ts +++ /dev/null @@ -1,30 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export { - IObservable, - IObserver, - IReader, - ISettable, - ISettableObservable, - ITransaction, - observableValue, - transaction, -} from 'vs/base/common/observableImpl/base'; -export { derived } from 'vs/base/common/observableImpl/derived'; -export { - autorun, - autorunDelta, - autorunHandleChanges, - autorunWithStore, -} from 'vs/base/common/observableImpl/autorun'; -export * from 'vs/base/common/observableImpl/utils'; - -import { ConsoleObservableLogger, setLogger } from 'vs/base/common/observableImpl/logging'; - -const enableLogging = false; -if (enableLogging) { - setLogger(new ConsoleObservableLogger()); -} diff --git a/src/vs/base/common/observableImpl/autorun.ts b/src/vs/base/common/observableImpl/autorun.ts deleted file mode 100644 index ca250de13e..0000000000 --- a/src/vs/base/common/observableImpl/autorun.ts +++ /dev/null @@ -1,167 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { IReader, IObservable, IObserver } from 'vs/base/common/observableImpl/base'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; - -export function autorun(debugName: string, fn: (reader: IReader) => void): IDisposable { - return new AutorunObserver(debugName, fn, undefined); -} - -interface IChangeContext { - readonly changedObservable: IObservable; - readonly change: unknown; - - didChange(observable: IObservable): this is { change: TChange }; -} - -export function autorunHandleChanges( - debugName: string, - options: { - /** - * Returns if this change should cause a re-run of the autorun. - */ - handleChange: (context: IChangeContext) => boolean; - }, - fn: (reader: IReader) => void -): IDisposable { - return new AutorunObserver(debugName, fn, options.handleChange); -} - -export function autorunWithStore( - fn: (reader: IReader, store: DisposableStore) => void, - debugName: string -): IDisposable { - const store = new DisposableStore(); - const disposable = autorun( - debugName, - reader => { - store.clear(); - fn(reader, store); - } - ); - return toDisposable(() => { - disposable.dispose(); - store.dispose(); - }); -} - -export class AutorunObserver implements IObserver, IReader, IDisposable { - public needsToRun = true; - private updateCount = 0; - private disposed = false; - - /** - * The actual dependencies. - */ - private _dependencies = new Set>(); - public get dependencies() { - return this._dependencies; - } - - /** - * Dependencies that have to be removed when {@link runFn} ran through. - */ - private staleDependencies = new Set>(); - - constructor( - public readonly debugName: string, - private readonly runFn: (reader: IReader) => void, - private readonly _handleChange: ((context: IChangeContext) => boolean) | undefined - ) { - getLogger()?.handleAutorunCreated(this); - this.runIfNeeded(); - } - - public subscribeTo(observable: IObservable) { - // In case the run action disposes the autorun - if (this.disposed) { - return; - } - this._dependencies.add(observable); - if (!this.staleDependencies.delete(observable)) { - observable.addObserver(this); - } - } - - public handleChange(observable: IObservable, change: TChange): void { - const shouldReact = this._handleChange ? this._handleChange({ - changedObservable: observable, - change, - didChange: o => o === observable as any, - }) : true; - this.needsToRun = this.needsToRun || shouldReact; - - if (this.updateCount === 0) { - this.runIfNeeded(); - } - } - - public beginUpdate(): void { - this.updateCount++; - } - - public endUpdate(): void { - this.updateCount--; - if (this.updateCount === 0) { - this.runIfNeeded(); - } - } - - private runIfNeeded(): void { - if (!this.needsToRun) { - return; - } - // Assert: this.staleDependencies is an empty set. - const emptySet = this.staleDependencies; - this.staleDependencies = this._dependencies; - this._dependencies = emptySet; - - this.needsToRun = false; - - getLogger()?.handleAutorunTriggered(this); - - try { - this.runFn(this); - } finally { - // We don't want our observed observables to think that they are (not even temporarily) not being observed. - // Thus, we only unsubscribe from observables that are definitely not read anymore. - for (const o of this.staleDependencies) { - o.removeObserver(this); - } - this.staleDependencies.clear(); - } - } - - public dispose(): void { - this.disposed = true; - for (const o of this._dependencies) { - o.removeObserver(this); - } - this._dependencies.clear(); - } - - public toString(): string { - return `Autorun<${this.debugName}>`; - } -} - -export namespace autorun { - export const Observer = AutorunObserver; -} -export function autorunDelta( - name: string, - observable: IObservable, - handler: (args: { lastValue: T | undefined; newValue: T }) => void -): IDisposable { - let _lastValue: T | undefined; - return autorun(name, (reader) => { - const newValue = observable.read(reader); - const lastValue = _lastValue; - _lastValue = newValue; - handler({ lastValue, newValue }); - }); -} diff --git a/src/vs/base/common/observableImpl/base.ts b/src/vs/base/common/observableImpl/base.ts deleted file mode 100644 index 02448c47ff..0000000000 --- a/src/vs/base/common/observableImpl/base.ts +++ /dev/null @@ -1,244 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type { derived } from 'vs/base/common/observableImpl/derived'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; - -export interface IObservable { - readonly TChange: TChange; - - /** - * Reads the current value. - * - * Must not be called from {@link IObserver.handleChange}. - */ - get(): T; - - /** - * Adds an observer. - */ - addObserver(observer: IObserver): void; - removeObserver(observer: IObserver): void; - - /** - * Subscribes the reader to this observable and returns the current value of this observable. - */ - read(reader: IReader): T; - - map(fn: (value: T) => TNew): IObservable; - - readonly debugName: string; -} - -export interface IReader { - /** - * Reports an observable that was read. - * - * Is called by {@link IObservable.read}. - */ - subscribeTo(observable: IObservable): void; -} - -export interface IObserver { - /** - * Indicates that an update operation is about to begin. - * - * During an update, invariants might not hold for subscribed observables and - * change events might be delayed. - * However, all changes must be reported before all update operations are over. - */ - beginUpdate(observable: IObservable): void; - - /** - * Is called by a subscribed observable immediately after it notices a change. - * - * When {@link IObservable.get} returns and no change has been reported, - * there has been no change for that observable. - * - * Implementations must not call into other observables! - * The change should be processed when {@link IObserver.endUpdate} is called. - */ - handleChange(observable: IObservable, change: TChange): void; - - /** - * Indicates that an update operation has completed. - */ - endUpdate(observable: IObservable): void; -} - -export interface ISettable { - set(value: T, transaction: ITransaction | undefined, change: TChange): void; -} - -export interface ITransaction { - /** - * Calls `Observer.beginUpdate` immediately - * and `Observer.endUpdate` when the transaction is complete. - */ - updateObserver( - observer: IObserver, - observable: IObservable - ): void; -} - -let _derived: typeof derived; -/** - * @internal - * This is to allow splitting files. -*/ -export function _setDerived(derived: typeof _derived) { - _derived = derived; -} - -export abstract class ConvenientObservable implements IObservable { - get TChange(): TChange { return null!; } - - public abstract get(): T; - public abstract addObserver(observer: IObserver): void; - public abstract removeObserver(observer: IObserver): void; - - /** @sealed */ - public read(reader: IReader): T { - reader.subscribeTo(this); - return this.get(); - } - - /** @sealed */ - public map(fn: (value: T) => TNew): IObservable { - return _derived( - () => { - const name = getFunctionName(fn); - return name !== undefined ? name : `${this.debugName} (mapped)`; - }, - (reader) => fn(this.read(reader)) - ); - } - - public abstract get debugName(): string; -} - -export abstract class BaseObservable extends ConvenientObservable { - protected readonly observers = new Set(); - - /** @sealed */ - public addObserver(observer: IObserver): void { - const len = this.observers.size; - this.observers.add(observer); - if (len === 0) { - this.onFirstObserverAdded(); - } - } - - /** @sealed */ - public removeObserver(observer: IObserver): void { - const deleted = this.observers.delete(observer); - if (deleted && this.observers.size === 0) { - this.onLastObserverRemoved(); - } - } - - protected onFirstObserverAdded(): void { } - protected onLastObserverRemoved(): void { } -} - -export function transaction(fn: (tx: ITransaction) => void, getDebugName?: () => string): void { - const tx = new TransactionImpl(fn, getDebugName); - try { - getLogger()?.handleBeginTransaction(tx); - fn(tx); - } finally { - tx.finish(); - getLogger()?.handleEndTransaction(); - } -} - -export function getFunctionName(fn: Function): string | undefined { - const fnSrc = fn.toString(); - // Pattern: /** @description ... */ - const regexp = /\/\*\*\s*@description\s*([^*]*)\*\//; - const match = regexp.exec(fnSrc); - const result = match ? match[1] : undefined; - return result?.trim(); -} - -export class TransactionImpl implements ITransaction { - private updatingObservers: { observer: IObserver; observable: IObservable }[] | null = []; - - constructor(private readonly fn: Function, private readonly _getDebugName?: () => string) { } - - public getDebugName(): string | undefined { - if (this._getDebugName) { - return this._getDebugName(); - } - return getFunctionName(this.fn); - } - - public updateObserver( - observer: IObserver, - observable: IObservable - ): void { - this.updatingObservers!.push({ observer, observable }); - observer.beginUpdate(observable); - } - - public finish(): void { - const updatingObservers = this.updatingObservers!; - // Prevent anyone from updating observers from now on. - this.updatingObservers = null; - for (const { observer, observable } of updatingObservers) { - observer.endUpdate(observable); - } - } -} - -export interface ISettableObservable extends IObservable, ISettable { -} - -export function observableValue(name: string, initialValue: T): ISettableObservable { - return new ObservableValue(name, initialValue); -} - -export class ObservableValue - extends BaseObservable - implements ISettableObservable -{ - private value: T; - - constructor(public readonly debugName: string, initialValue: T) { - super(); - this.value = initialValue; - } - - public get(): T { - return this.value; - } - - public set(value: T, tx: ITransaction | undefined, change: TChange): void { - if (this.value === value) { - return; - } - - if (!tx) { - transaction((tx) => { - this.set(value, tx, change); - }, () => `Setting ${this.debugName}`); - return; - } - - const oldValue = this.value; - this.value = value; - getLogger()?.handleObservableChanged(this, { oldValue, newValue: value, change, didChange: true }); - - for (const observer of this.observers) { - tx.updateObserver(observer, this); - observer.handleChange(this, change); - } - } - - override toString(): string { - return `${this.debugName}: ${this.value}`; - } -} - diff --git a/src/vs/base/common/observableImpl/derived.ts b/src/vs/base/common/observableImpl/derived.ts deleted file mode 100644 index cf8237d59b..0000000000 --- a/src/vs/base/common/observableImpl/derived.ts +++ /dev/null @@ -1,167 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IReader, IObservable, BaseObservable, IObserver, _setDerived } from 'vs/base/common/observableImpl/base'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; - -export function derived(debugName: string | (() => string), computeFn: (reader: IReader) => T): IObservable { - return new Derived(debugName, computeFn); -} - -_setDerived(derived); - -export class Derived extends BaseObservable implements IReader, IObserver { - private hadValue = false; - private hasValue = false; - private value: T | undefined = undefined; - private updateCount = 0; - - private _dependencies = new Set>(); - public get dependencies(): ReadonlySet> { - return this._dependencies; - } - - /** - * Dependencies that have to be removed when {@link runFn} ran through. - */ - private staleDependencies = new Set>(); - - public override get debugName(): string { - return typeof this._debugName === 'function' ? this._debugName() : this._debugName; - } - - constructor( - private readonly _debugName: string | (() => string), - private readonly computeFn: (reader: IReader) => T - ) { - super(); - - getLogger()?.handleDerivedCreated(this); - } - - protected override onLastObserverRemoved(): void { - /** - * We are not tracking changes anymore, thus we have to assume - * that our cache is invalid. - */ - this.hasValue = false; - this.hadValue = false; - this.value = undefined; - for (const d of this._dependencies) { - d.removeObserver(this); - } - this._dependencies.clear(); - } - - public get(): T { - if (this.observers.size === 0) { - // Cache is not valid and don't refresh the cache. - // Observables should not be read in non-reactive contexts. - const result = this.computeFn(this); - // Clear new dependencies - this.onLastObserverRemoved(); - return result; - } - - if (this.updateCount > 0 && this.hasValue) { - // Refresh dependencies - for (const d of this._dependencies) { - // Maybe `.get()` triggers `handleChange`? - d.get(); - if (!this.hasValue) { - // The other dependencies will refresh on demand - break; - } - } - } - - if (!this.hasValue) { - const emptySet = this.staleDependencies; - this.staleDependencies = this._dependencies; - this._dependencies = emptySet; - - const oldValue = this.value; - try { - this.value = this.computeFn(this); - } finally { - // We don't want our observed observables to think that they are (not even temporarily) not being observed. - // Thus, we only unsubscribe from observables that are definitely not read anymore. - for (const o of this.staleDependencies) { - o.removeObserver(this); - } - this.staleDependencies.clear(); - } - - this.hasValue = true; - const didChange = this.hadValue && oldValue !== this.value; - getLogger()?.handleDerivedRecomputed(this, { - oldValue, - newValue: this.value, - change: undefined, - didChange - }); - if (didChange) { - for (const r of this.observers) { - r.handleChange(this, undefined); - } - } - } - return this.value!; - } - - // IObserver Implementation - public beginUpdate(): void { - if (this.updateCount === 0) { - for (const r of this.observers) { - r.beginUpdate(this); - } - } - this.updateCount++; - } - - public handleChange( - _observable: IObservable, - _change: TChange - ): void { - if (this.hasValue) { - this.hadValue = true; - this.hasValue = false; - } - - // Not in transaction: Recompute & inform observers immediately - if (this.updateCount === 0 && this.observers.size > 0) { - this.get(); - } - - // Otherwise, recompute in `endUpdate` or on demand. - } - - public endUpdate(): void { - this.updateCount--; - if (this.updateCount === 0) { - if (this.observers.size > 0) { - // Propagate invalidation - this.get(); - } - - for (const r of this.observers) { - r.endUpdate(this); - } - } - } - - // IReader Implementation - public subscribeTo(observable: IObservable) { - this._dependencies.add(observable); - // We are already added as observer for stale dependencies. - if (!this.staleDependencies.delete(observable)) { - observable.addObserver(this); - } - } - - override toString(): string { - return `LazyDerived<${this.debugName}>`; - } -} diff --git a/src/vs/base/common/observableImpl/logging.ts b/src/vs/base/common/observableImpl/logging.ts deleted file mode 100644 index ba0f10cf14..0000000000 --- a/src/vs/base/common/observableImpl/logging.ts +++ /dev/null @@ -1,312 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { AutorunObserver } from 'vs/base/common/observableImpl/autorun'; -import { IObservable, ObservableValue, TransactionImpl } from 'vs/base/common/observableImpl/base'; -import { Derived } from 'vs/base/common/observableImpl/derived'; -import { FromEventObservable } from 'vs/base/common/observableImpl/utils'; - -let globalObservableLogger: IObservableLogger | undefined; - -export function setLogger(logger: IObservableLogger): void { - globalObservableLogger = logger; -} - -export function getLogger(): IObservableLogger | undefined { - return globalObservableLogger; -} - -interface IChangeInformation { - oldValue: unknown; - newValue: unknown; - change: unknown; - didChange: boolean; -} - -export interface IObservableLogger { - handleObservableChanged(observable: ObservableValue, info: IChangeInformation): void; - handleFromEventObservableTriggered(observable: FromEventObservable, info: IChangeInformation): void; - - handleAutorunCreated(autorun: AutorunObserver): void; - handleAutorunTriggered(autorun: AutorunObserver): void; - - handleDerivedCreated(observable: Derived): void; - handleDerivedRecomputed(observable: Derived, info: IChangeInformation): void; - - handleBeginTransaction(transaction: TransactionImpl): void; - handleEndTransaction(): void; -} - -export class ConsoleObservableLogger implements IObservableLogger { - private indentation = 0; - - private textToConsoleArgs(text: ConsoleText): unknown[] { - return consoleTextToArgs([ - normalText(repeat('| ', this.indentation)), - text, - ]); - } - - private formatInfo(info: IChangeInformation): ConsoleText[] { - return info.didChange - ? [ - normalText(` `), - styled(formatValue(info.oldValue, 70), { - color: 'red', - strikeThrough: true, - }), - normalText(` `), - styled(formatValue(info.newValue, 60), { - color: 'green', - }), - ] - : [normalText(` (unchanged)`)]; - } - - handleObservableChanged(observable: IObservable, info: IChangeInformation): void { - console.log(...this.textToConsoleArgs([ - formatKind('observable value changed'), - styled(observable.debugName, { color: 'BlueViolet' }), - ...this.formatInfo(info), - ])); - } - - private readonly changedObservablesSets = new WeakMap>>(); - - formatChanges(changes: Set>): ConsoleText | undefined { - if (changes.size === 0) { - return undefined; - } - return styled( - ' (changed deps: ' + - [...changes].map((o) => o.debugName).join(', ') + - ')', - { color: 'gray' } - ); - } - - handleDerivedCreated(derived: Derived): void { - const existingHandleChange = derived.handleChange; - this.changedObservablesSets.set(derived, new Set()); - derived.handleChange = (observable, change) => { - this.changedObservablesSets.get(derived)!.add(observable); - return existingHandleChange.apply(derived, [observable, change]); - }; - } - - handleDerivedRecomputed(derived: Derived, info: IChangeInformation): void { - const changedObservables = this.changedObservablesSets.get(derived)!; - console.log(...this.textToConsoleArgs([ - formatKind('derived recomputed'), - styled(derived.debugName, { color: 'BlueViolet' }), - ...this.formatInfo(info), - this.formatChanges(changedObservables) - ])); - changedObservables.clear(); - } - - handleFromEventObservableTriggered(observable: FromEventObservable, info: IChangeInformation): void { - console.log(...this.textToConsoleArgs([ - formatKind('observable from event triggered'), - styled(observable.debugName, { color: 'BlueViolet' }), - ...this.formatInfo(info), - ])); - } - - handleAutorunCreated(autorun: AutorunObserver): void { - const existingHandleChange = autorun.handleChange; - this.changedObservablesSets.set(autorun, new Set()); - autorun.handleChange = (observable, change) => { - this.changedObservablesSets.get(autorun)!.add(observable); - return existingHandleChange.apply(autorun, [observable, change]); - }; - } - - handleAutorunTriggered(autorun: AutorunObserver): void { - const changedObservables = this.changedObservablesSets.get(autorun)!; - console.log(...this.textToConsoleArgs([ - formatKind('autorun'), - styled(autorun.debugName, { color: 'BlueViolet' }), - this.formatChanges(changedObservables) - ])); - changedObservables.clear(); - } - - handleBeginTransaction(transaction: TransactionImpl): void { - let transactionName = transaction.getDebugName(); - if (transactionName === undefined) { - transactionName = ''; - } - console.log(...this.textToConsoleArgs([ - formatKind('transaction'), - styled(transactionName, { color: 'BlueViolet' }), - ])); - this.indentation++; - } - - handleEndTransaction(): void { - this.indentation--; - } -} - -type ConsoleText = - | (ConsoleText | undefined)[] - | { text: string; style: string; data?: Record } - | { data: Record }; - -function consoleTextToArgs(text: ConsoleText): unknown[] { - const styles = new Array(); - const initial = {}; - const data = initial; - let firstArg = ''; - - function process(t: ConsoleText): void { - if ('length' in t) { - for (const item of t) { - if (item) { - process(item); - } - } - } else if ('text' in t) { - firstArg += `%c${t.text}`; - styles.push(t.style); - if (t.data) { - Object.assign(data, t.data); - } - } else if ('data' in t) { - Object.assign(data, t.data); - } - } - - process(text); - - const result = [firstArg, ...styles]; - if (Object.keys(data).length > 0) { - result.push(data); - } - - return result; -} - -function normalText(text: string): ConsoleText { - return styled(text, { color: 'black' }); -} - -function formatKind(kind: string): ConsoleText { - return styled(padStr(`${kind}: `, 10), { color: 'black', bold: true }); -} - -function styled( - text: string, - options: { color: string; strikeThrough?: boolean; bold?: boolean } = { - color: 'black', - } -): ConsoleText { - function objToCss(styleObj: Record): string { - return Object.entries(styleObj).reduce( - (styleString, [propName, propValue]) => { - return `${styleString}${propName}:${propValue};`; - }, - '' - ); - } - - const style: Record = { - color: options.color, - }; - if (options.strikeThrough) { - style['text-decoration'] = 'line-through'; - } - if (options.bold) { - style['font-weight'] = 'bold'; - } - - return { - text, - style: objToCss(style), - }; -} - -function formatValue(value: unknown, availableLen: number): string { - switch (typeof value) { - case 'number': - return '' + value; - case 'string': - if (value.length + 2 <= availableLen) { - return `"${value}"`; - } - return `"${value.substr(0, availableLen - 7)}"+...`; - - case 'boolean': - return value ? 'true' : 'false'; - case 'undefined': - return 'undefined'; - case 'object': - if (value === null) { - return 'null'; - } - if (Array.isArray(value)) { - return formatArray(value, availableLen); - } - return formatObject(value, availableLen); - case 'symbol': - return value.toString(); - case 'function': - return `[[Function${value.name ? ' ' + value.name : ''}]]`; - default: - return '' + value; - } -} - -function formatArray(value: unknown[], availableLen: number): string { - let result = '[ '; - let first = true; - for (const val of value) { - if (!first) { - result += ', '; - } - if (result.length - 5 > availableLen) { - result += '...'; - break; - } - first = false; - result += `${formatValue(val, availableLen - result.length)}`; - } - result += ' ]'; - return result; -} - -function formatObject(value: object, availableLen: number): string { - let result = '{ '; - let first = true; - for (const [key, val] of Object.entries(value)) { - if (!first) { - result += ', '; - } - if (result.length - 5 > availableLen) { - result += '...'; - break; - } - first = false; - result += `${key}: ${formatValue(val, availableLen - result.length)}`; - } - result += ' }'; - return result; -} - -function repeat(str: string, count: number): string { - let result = ''; - for (let i = 1; i <= count; i++) { - result += str; - } - return result; -} - -function padStr(str: string, length: number): string { - while (str.length < length) { - str += ' '; - } - return str; -} diff --git a/src/vs/base/common/observableImpl/utils.ts b/src/vs/base/common/observableImpl/utils.ts deleted file mode 100644 index 242594e7eb..0000000000 --- a/src/vs/base/common/observableImpl/utils.ts +++ /dev/null @@ -1,281 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { autorun } from 'vs/base/common/observableImpl/autorun'; -import { IObservable, BaseObservable, transaction, IReader, ITransaction, ConvenientObservable, IObserver, observableValue, getFunctionName } from 'vs/base/common/observableImpl/base'; -import { derived } from 'vs/base/common/observableImpl/derived'; -import { Event } from 'vs/base/common/event'; -import { getLogger } from 'vs/base/common/observableImpl/logging'; - -export function constObservable(value: T): IObservable { - return new ConstObservable(value); -} - -class ConstObservable extends ConvenientObservable { - constructor(private readonly value: T) { - super(); - } - - public override get debugName(): string { - return this.toString(); - } - - public get(): T { - return this.value; - } - public addObserver(observer: IObserver): void { - // NO OP - } - public removeObserver(observer: IObserver): void { - // NO OP - } - - override toString(): string { - return `Const: ${this.value}`; - } -} - - -export function observableFromPromise(promise: Promise): IObservable<{ value?: T }> { - const observable = observableValue<{ value?: T }>('promiseValue', {}); - promise.then((value) => { - observable.set({ value }, undefined); - }); - return observable; -} - -export function waitForState(observable: IObservable, predicate: (state: T) => state is TState): Promise; -export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise; -export function waitForState(observable: IObservable, predicate: (state: T) => boolean): Promise { - return new Promise(resolve => { - const d = autorun('waitForState', reader => { - const currentState = observable.read(reader); - if (predicate(currentState)) { - d.dispose(); - resolve(currentState); - } - }); - }); -} - -export function observableFromEvent( - event: Event, - getValue: (args: TArgs | undefined) => T -): IObservable { - return new FromEventObservable(event, getValue); -} - -export class FromEventObservable extends BaseObservable { - private value: T | undefined; - private hasValue = false; - private subscription: IDisposable | undefined; - - constructor( - private readonly event: Event, - private readonly getValue: (args: TArgs | undefined) => T - ) { - super(); - } - - private getDebugName(): string | undefined { - return getFunctionName(this.getValue); - } - - public get debugName(): string { - const name = this.getDebugName(); - return 'From Event' + (name ? `: ${name}` : ''); - } - - protected override onFirstObserverAdded(): void { - this.subscription = this.event(this.handleEvent); - } - - private readonly handleEvent = (args: TArgs | undefined) => { - const newValue = this.getValue(args); - - const didChange = this.value !== newValue; - - getLogger()?.handleFromEventObservableTriggered(this, { oldValue: this.value, newValue, change: undefined, didChange }); - - if (didChange) { - this.value = newValue; - - if (this.hasValue) { - transaction( - (tx) => { - for (const o of this.observers) { - tx.updateObserver(o, this); - o.handleChange(this, undefined); - } - }, - () => { - const name = this.getDebugName(); - return 'Event fired' + (name ? `: ${name}` : ''); - } - ); - } - this.hasValue = true; - } - }; - - protected override onLastObserverRemoved(): void { - this.subscription!.dispose(); - this.subscription = undefined; - this.hasValue = false; - this.value = undefined; - } - - public get(): T { - if (this.subscription) { - if (!this.hasValue) { - this.handleEvent(undefined); - } - return this.value!; - } else { - // no cache, as there are no subscribers to keep it updated - return this.getValue(undefined); - } - } -} - -export namespace observableFromEvent { - export const Observer = FromEventObservable; -} - -export function observableSignalFromEvent( - debugName: string, - event: Event -): IObservable { - return new FromEventObservableSignal(debugName, event); -} - -class FromEventObservableSignal extends BaseObservable { - private subscription: IDisposable | undefined; - - constructor( - public readonly debugName: string, - private readonly event: Event, - ) { - super(); - } - - protected override onFirstObserverAdded(): void { - this.subscription = this.event(this.handleEvent); - } - - private readonly handleEvent = () => { - transaction( - (tx) => { - for (const o of this.observers) { - tx.updateObserver(o, this); - o.handleChange(this, undefined); - } - }, - () => this.debugName - ); - }; - - protected override onLastObserverRemoved(): void { - this.subscription!.dispose(); - this.subscription = undefined; - } - - public override get(): void { - // NO OP - } -} - -export function debouncedObservable(observable: IObservable, debounceMs: number, disposableStore: DisposableStore): IObservable { - const debouncedObservable = observableValue('debounced', undefined); - - let timeout: any = undefined; - - disposableStore.add(autorun('debounce', reader => { - const value = observable.read(reader); - - if (timeout) { - clearTimeout(timeout); - } - timeout = setTimeout(() => { - transaction(tx => { - debouncedObservable.set(value, tx); - }); - }, debounceMs); - - })); - - return debouncedObservable; -} - -export function wasEventTriggeredRecently(event: Event, timeoutMs: number, disposableStore: DisposableStore): IObservable { - const observable = observableValue('triggeredRecently', false); - - let timeout: any = undefined; - - disposableStore.add(event(() => { - observable.set(true, undefined); - - if (timeout) { - clearTimeout(timeout); - } - timeout = setTimeout(() => { - observable.set(false, undefined); - }, timeoutMs); - })); - - return observable; -} - -/** - * This ensures the observable is kept up-to-date. - * This is useful when the observables `get` method is used. -*/ -export function keepAlive(observable: IObservable): IDisposable { - const o = new KeepAliveObserver(); - observable.addObserver(o); - return toDisposable(() => { - observable.removeObserver(o); - }); -} - -class KeepAliveObserver implements IObserver { - beginUpdate(observable: IObservable): void { - // NO OP - } - - handleChange(observable: IObservable, change: TChange): void { - // NO OP - } - - endUpdate(observable: IObservable): void { - // NO OP - } -} - -export function derivedObservableWithCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable { - let lastValue: T | undefined = undefined; - const observable = derived(name, reader => { - lastValue = computeFn(reader, lastValue); - return lastValue; - }); - return observable; -} - -export function derivedObservableWithWritableCache(name: string, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable & { clearCache(transaction: ITransaction): void } { - let lastValue: T | undefined = undefined; - const counter = observableValue('derivedObservableWithWritableCache.counter', 0); - const observable = derived(name, reader => { - counter.read(reader); - lastValue = computeFn(reader, lastValue); - return lastValue; - }); - return Object.assign(observable, { - clearCache: (transaction: ITransaction) => { - lastValue = undefined; - counter.set(counter.get() + 1, transaction); - }, - }); -} diff --git a/src/vs/base/common/observableValue.ts b/src/vs/base/common/observableValue.ts index 5d7130bb43..9c2722f472 100644 --- a/src/vs/base/common/observableValue.ts +++ b/src/vs/base/common/observableValue.ts @@ -5,28 +5,17 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable } from 'vs/base/common/lifecycle'; -//@ts-ignore -import type { IObservable } from 'vs/base/common/observable'; -/** - * @deprecated Use {@link IObservable} instead. - */ export interface IObservableValue { onDidChange: Event; readonly value: T; } -/** - * @deprecated Use {@link IObservable} instead. - */ export const staticObservableValue = (value: T): IObservableValue => ({ onDidChange: Event.None, value, }); -/** - * @deprecated Use {@link IObservable} instead. - */ export class MutableObservableValue extends Disposable implements IObservableValue { private readonly changeEmitter = this._register(new Emitter()); diff --git a/src/vs/base/common/platform.ts b/src/vs/base/common/platform.ts index e3b2cc6b66..7d59bd1fa2 100644 --- a/src/vs/base/common/platform.ts +++ b/src/vs/base/common/platform.ts @@ -2,7 +2,6 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; const LANGUAGE_DEFAULT = 'en'; @@ -68,6 +67,7 @@ const isElectronRenderer = isElectronProcess && nodeProcess?.type === 'renderer' interface INavigator { userAgent: string; + language: string; maxTouchPoints?: number; } declare const navigator: INavigator; @@ -80,17 +80,7 @@ if (typeof navigator === 'object' && !isElectronRenderer) { _isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0; _isLinux = _userAgent.indexOf('Linux') >= 0; _isWeb = true; - - const configuredLocale = nls.getConfiguredDefaultLocale( - // This call _must_ be done in the file that calls `nls.getConfiguredDefaultLocale` - // to ensure that the NLS AMD Loader plugin has been loaded and configured. - // This is because the loader plugin decides what the default locale is based on - // how it's able to resolve the strings. - nls.localize({ key: 'ensureLoaderPluginIsLoaded', comment: ['{Locked}'] }, '_') - ); - - _locale = configuredLocale || LANGUAGE_DEFAULT; - + _locale = navigator.language; _language = _locale; } @@ -205,8 +195,6 @@ export const locale = _locale; */ export const translationsConfigFile = _translationsConfigFile; -export const setTimeout0IsFaster = (typeof globals.postMessage === 'function' && !globals.importScripts); - /** * See https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#:~:text=than%204%2C%20then-,set%20timeout%20to%204,-. * @@ -214,12 +202,12 @@ export const setTimeout0IsFaster = (typeof globals.postMessage === 'function' && * that browsers set when the nesting level is > 5. */ export const setTimeout0 = (() => { - if (setTimeout0IsFaster) { + if (typeof globals.postMessage === 'function' && !globals.importScripts) { interface IQueueElement { id: number; callback: () => void; } - const pending: IQueueElement[] = []; + let pending: IQueueElement[] = []; globals.addEventListener('message', (e: MessageEvent) => { if (e.data && e.data.vscodeScheduleAsyncWork) { for (let i = 0, len = pending.length; i < len; i++) { diff --git a/src/vs/base/common/product.ts b/src/vs/base/common/product.ts index 2ce50e78fa..c01921a772 100644 --- a/src/vs/base/common/product.ts +++ b/src/vs/base/common/product.ts @@ -71,11 +71,9 @@ export interface IProductConfiguration { readonly extensionsGallery?: { readonly serviceUrl: string; readonly itemUrl: string; - readonly publisherUrl: string; readonly resourceUrlTemplate: string; readonly controlUrl: string; readonly recommendationsUrl: string; - readonly nlsBaseUrl: string; }; readonly extensionTips?: { [id: string]: string }; @@ -160,8 +158,6 @@ export interface IProductConfiguration { readonly 'configurationSync.store'?: ConfigurationSyncStore; - readonly 'editSessions.store'?: Omit; - readonly darwinUniversalAssetId?: string; } diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index b968ad9aca..b9297ac9ca 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -240,8 +240,7 @@ export class ExtUri implements IExtUri { const relativePath = paths.relative(originalFSPath(from), originalFSPath(to)); return isWindows ? extpath.toSlashes(relativePath) : relativePath; } - let fromPath = from.path || '/'; - const toPath = to.path || '/'; + let fromPath = from.path || '/', toPath = to.path || '/'; if (this._ignorePathCasing(from)) { // make casing of fromPath match toPath let i = 0; diff --git a/src/vs/base/common/scrollable.ts b/src/vs/base/common/scrollable.ts index 576d463636..0334b613bd 100644 --- a/src/vs/base/common/scrollable.ts +++ b/src/vs/base/common/scrollable.ts @@ -268,7 +268,9 @@ export class Scrollable extends Disposable { this._setState(newState, Boolean(this._smoothScrolling)); // Validate outstanding animated scroll position target - this._smoothScrolling?.acceptScrollDimensions(this._state); + if (this._smoothScrolling) { + this._smoothScrolling.acceptScrollDimensions(this._state); + } } /** diff --git a/src/vs/base/common/skipList.ts b/src/vs/base/common/skipList.ts index 7de346c676..11cc8e3790 100644 --- a/src/vs/base/common/skipList.ts +++ b/src/vs/base/common/skipList.ts @@ -135,7 +135,7 @@ export class SkipList implements Map { } private static _insert(list: SkipList, searchKey: K, value: V, comparator: Comparator) { - const update: Node[] = []; + let update: Node[] = []; let x = list._header; for (let i = list._level - 1; i >= 0; i--) { while (x.forward[i] && comparator(x.forward[i].key, searchKey) < 0) { @@ -150,7 +150,7 @@ export class SkipList implements Map { return false; } else { // insert - const lvl = SkipList._randomLevel(list); + let lvl = SkipList._randomLevel(list); if (lvl > list._level) { for (let i = list._level; i < lvl; i++) { update[i] = list._header; @@ -175,7 +175,7 @@ export class SkipList implements Map { } private static _delete(list: SkipList, searchKey: K, comparator: Comparator) { - const update: Node[] = []; + let update: Node[] = []; let x = list._header; for (let i = list._level - 1; i >= 0; i--) { while (x.forward[i] && comparator(x.forward[i].key, searchKey) < 0) { diff --git a/src/vs/base/common/strings.ts b/src/vs/base/common/strings.ts index 6d8d9e06fc..ac9bd17c11 100644 --- a/src/vs/base/common/strings.ts +++ b/src/vs/base/common/strings.ts @@ -279,7 +279,7 @@ export function lastNonWhitespaceIndex(str: string, startIndex: number = str.len * replace function is allowed to be async and return a Promise. */ export function replaceAsync(str: string, search: RegExp, replacer: (match: string, ...args: any[]) => Promise): Promise { - const parts: (string | Promise)[] = []; + let parts: (string | Promise)[] = []; let last = 0; for (const match of str.matchAll(search)) { @@ -309,8 +309,8 @@ export function compare(a: string, b: string): number { export function compareSubstring(a: string, b: string, aStart: number = 0, aEnd: number = a.length, bStart: number = 0, bEnd: number = b.length): number { for (; aStart < aEnd && bStart < bEnd; aStart++, bStart++) { - const codeA = a.charCodeAt(aStart); - const codeB = b.charCodeAt(bStart); + let codeA = a.charCodeAt(aStart); + let codeB = b.charCodeAt(bStart); if (codeA < codeB) { return -1; } else if (codeA > codeB) { @@ -378,10 +378,6 @@ export function compareSubstringIgnoreCase(a: string, b: string, aStart: number return 0; } -export function isAsciiDigit(code: number): boolean { - return code >= CharCode.Digit0 && code <= CharCode.Digit9; -} - export function isLowerAsciiLetter(code: number): boolean { return code >= CharCode.a && code <= CharCode.z; } @@ -408,8 +404,8 @@ export function startsWithIgnoreCase(str: string, candidate: string): boolean { */ export function commonPrefixLength(a: string, b: string): number { - const len = Math.min(a.length, b.length); - let i: number; + let i: number, + len = Math.min(a.length, b.length); for (i = 0; i < len; i++) { if (a.charCodeAt(i) !== b.charCodeAt(i)) { @@ -425,8 +421,8 @@ export function commonPrefixLength(a: string, b: string): number { */ export function commonSuffixLength(a: string, b: string): number { - const len = Math.min(a.length, b.length); - let i: number; + let i: number, + len = Math.min(a.length, b.length); const aLastIndex = a.length - 1; const bLastIndex = b.length - 1; diff --git a/src/vs/base/common/stripComments.js b/src/vs/base/common/stripComments.js index d580a397d9..3c9dd0c9d2 100644 --- a/src/vs/base/common/stripComments.js +++ b/src/vs/base/common/stripComments.js @@ -13,8 +13,7 @@ // Second group matches a single quoted string // Third group matches a multi line comment // Forth group matches a single line comment - // Fifth group matches a trailing comma - const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))|(,\s*[}\]])/g; + const regexp = /("[^"\\]*(?:\\.[^"\\]*)*")|('[^'\\]*(?:\\.[^'\\]*)*')|(\/\*[^\/\*]*(?:(?:\*|\/)[^\/\*]*)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; /** * @@ -22,8 +21,8 @@ * @returns {string} */ function stripComments(content) { - return content.replace(regexp, function (match, _m1, _m2, m3, m4, m5) { - // Only one of m1, m2, m3, m4, m5 matches + return content.replace(regexp, function (match, _m1, _m2, m3, m4) { + // Only one of m1, m2, m3, m4 matches if (m3) { // A block comment. Replace with nothing return ''; @@ -37,9 +36,6 @@ else { return ''; } - } else if (m5) { - // Remove the trailing comma - return match.substring(1); } else { // We match a string return match; diff --git a/src/vs/base/common/types.ts b/src/vs/base/common/types.ts index e073ea9c8b..a6dea79439 100644 --- a/src/vs/base/common/types.ts +++ b/src/vs/base/common/types.ts @@ -47,9 +47,18 @@ export function isObject(obj: unknown): obj is Object { * @returns whether the provided parameter is of type `Buffer` or Uint8Array dervived type */ export function isTypedArray(obj: unknown): obj is Object { - const TypedArray = Object.getPrototypeOf(Uint8Array); return typeof obj === 'object' - && obj instanceof TypedArray; + && (obj instanceof Uint8Array || + obj instanceof Uint16Array || + obj instanceof Uint32Array || + obj instanceof Float32Array || + obj instanceof Float64Array || + obj instanceof Int8Array || + obj instanceof Int16Array || + obj instanceof Int32Array || + obj instanceof BigInt64Array || + obj instanceof BigUint64Array || + obj instanceof Uint8ClampedArray); } /** @@ -145,7 +154,7 @@ export function isEmptyObject(obj: unknown): obj is object { return false; } - for (const key in obj) { + for (let key in obj) { if (hasOwnProperty.call(obj, key)) { return false; } @@ -229,7 +238,7 @@ export function createProxyObject(methodNames: string[], invok }; }; - const result = {} as T; + let result = {} as T; for (const methodName of methodNames) { (result)[methodName] = createProxyMethod(methodName); } diff --git a/src/vs/base/common/uriIpc.ts b/src/vs/base/common/uriIpc.ts index 04ca2ffb49..7acf449519 100644 --- a/src/vs/base/common/uriIpc.ts +++ b/src/vs/base/common/uriIpc.ts @@ -90,7 +90,7 @@ function _transformOutgoingURIs(obj: any, transformer: IURITransformer, depth: n } // walk object (or array) - for (const key in obj) { + for (let key in obj) { if (Object.hasOwnProperty.call(obj, key)) { const r = _transformOutgoingURIs(obj[key], transformer, depth + 1); if (r !== null) { @@ -126,7 +126,7 @@ function _transformIncomingURIs(obj: any, transformer: IURITransformer, revive: } // walk object (or array) - for (const key in obj) { + for (let key in obj) { if (Object.hasOwnProperty.call(obj, key)) { const r = _transformIncomingURIs(obj[key], transformer, revive, depth + 1); if (r !== null) { diff --git a/src/vs/base/common/worker/simpleWorker.ts b/src/vs/base/common/worker/simpleWorker.ts index a9a1b1ff1d..95acf8263d 100644 --- a/src/vs/base/common/worker/simpleWorker.ts +++ b/src/vs/base/common/worker/simpleWorker.ts @@ -181,7 +181,7 @@ class SimpleWorkerProtocol { return; } - const reply = this._pendingReplies[replyMessage.seq]; + let reply = this._pendingReplies[replyMessage.seq]; delete this._pendingReplies[replyMessage.seq]; if (replyMessage.err) { @@ -200,8 +200,8 @@ class SimpleWorkerProtocol { } private _handleRequestMessage(requestMessage: RequestMessage): void { - const req = requestMessage.req; - const result = this._handler.handleMessage(requestMessage.method, requestMessage.args); + let req = requestMessage.req; + let result = this._handler.handleMessage(requestMessage.method, requestMessage.args); result.then((r) => { this._send(new ReplyMessage(this._workerId, req, r, undefined)); }, (e) => { @@ -239,7 +239,7 @@ class SimpleWorkerProtocol { } private _send(msg: Message): void { - const transfer: ArrayBuffer[] = []; + let transfer: ArrayBuffer[] = []; if (msg.type === MessageType.Request) { for (let i = 0; i < msg.args.length; i++) { if (msg.args[i] instanceof ArrayBuffer) { @@ -283,7 +283,9 @@ export class SimpleWorkerClient extends Disp (err: any) => { // in Firefox, web workers fail lazily :( // we will reject the proxy - lazyProxyReject?.(err); + if (lazyProxyReject) { + lazyProxyReject(err); + } } )); @@ -406,7 +408,7 @@ function createProxyObject( }; }; - const result = {} as T; + let result = {} as T; for (const methodName of methodNames) { if (propertyIsDynamicEvent(methodName)) { (result)[methodName] = createProxyDynamicEvent(methodName); diff --git a/src/vs/base/node/id.ts b/src/vs/base/node/id.ts index e16801508c..e7ccc471c7 100644 --- a/src/vs/base/node/id.ts +++ b/src/vs/base/node/id.ts @@ -55,7 +55,7 @@ export const virtualMachineHint: { value(): number } = new class { let interfaceCount = 0; const interfaces = networkInterfaces(); - for (const name in interfaces) { + for (let name in interfaces) { const networkInterface = interfaces[name]; if (networkInterface) { for (const { mac, internal } of networkInterface) { diff --git a/src/vs/base/node/macAddress.ts b/src/vs/base/node/macAddress.ts index 7e6cf526ad..bca52855b8 100644 --- a/src/vs/base/node/macAddress.ts +++ b/src/vs/base/node/macAddress.ts @@ -18,7 +18,7 @@ function validateMacAddress(candidate: string): boolean { export function getMac(): string { const ifaces = networkInterfaces(); - for (const name in ifaces) { + for (let name in ifaces) { const networkInterface = ifaces[name]; if (networkInterface) { for (const { mac } of networkInterface) { diff --git a/src/vs/base/node/pfs.ts b/src/vs/base/node/pfs.ts index b4edc7d8af..164a3fbe80 100644 --- a/src/vs/base/node/pfs.ts +++ b/src/vs/base/node/pfs.ts @@ -390,9 +390,6 @@ interface IEnsuredWriteFileOptions extends IWriteFileOptions { } let canFlush = true; -export function configureFlushOnWrite(enabled: boolean): void { - canFlush = enabled; -} // Calls fs.writeFile() followed by a fs.sync() call to flush the changes to disk // We do this in cases where we want to make sure the data is really on disk and @@ -424,7 +421,7 @@ function doWriteFileAndFlush(path: string, data: string | Buffer | Uint8Array, o // In that case we disable flushing and warn to the console if (syncError) { console.warn('[node.js fs] fdatasync is now disabled for this session because it failed: ', syncError); - configureFlushOnWrite(false); + canFlush = false; } return fs.close(fd, closeError => callback(closeError)); @@ -458,7 +455,7 @@ export function writeFileSync(path: string, data: string | Buffer, options?: IWr fs.fdatasyncSync(fd); // https://github.com/microsoft/vscode/issues/9589 } catch (syncError) { console.warn('[node.js fs] fdatasyncSync is now disabled for this session because it failed: ', syncError); - configureFlushOnWrite(false); + canFlush = false; } } finally { fs.closeSync(fd); diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index 0e2f57739a..9831d195fc 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -474,7 +474,7 @@ export namespace win32 { // We have a simple file name. We get the path variable from the env // and try to find the executable on the path. - for (const pathEntry of paths) { + for (let pathEntry of paths) { // The path entry is absolute. let fullPath: string; if (path.isAbsolute(pathEntry)) { diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index 9d29195666..f1dd66a2e2 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -52,7 +52,6 @@ export function listProcesses(rootPid: number): Promise { const ISSUE_REPORTER_HINT = /--vscode-window-kind=issue-reporter/; const PROCESS_EXPLORER_HINT = /--vscode-window-kind=process-explorer/; const UTILITY_NETWORK_HINT = /--utility-sub-type=network/; - const UTILITY_EXTENSION_HOST_HINT = /--utility-sub-type=node.mojom.NodeService/; const WINDOWS_CRASH_REPORTER = /--crashes-directory/; const WINDOWS_PTY = /\\pipe\\winpty-control/; const WINDOWS_CONSOLE_HOST = /conhost\.exe/; @@ -94,10 +93,6 @@ export function listProcesses(rootPid: number): Promise { if (UTILITY_NETWORK_HINT.exec(cmd)) { return 'utility-network-service'; } - - if (UTILITY_EXTENSION_HOST_HINT.exec(cmd)) { - return 'extension-host'; - } } return matches[1]; } diff --git a/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts b/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts index 2cf545ae34..377b8899d9 100644 --- a/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts +++ b/src/vs/base/parts/contextmenu/electron-sandbox/contextmenu.ts @@ -15,7 +15,9 @@ export function popup(items: IContextMenuItem[], options?: IPopupOptions, onHide const onClickChannel = `vscode:onContextMenu${contextMenuId}`; const onClickChannelHandler = (event: unknown, itemId: number, context: IContextMenuEvent) => { const item = processedItems[itemId]; - item.click?.(context); + if (item.click) { + item.click(context); + } }; ipcRenderer.once(onClickChannel, onClickChannelHandler); @@ -26,7 +28,9 @@ export function popup(items: IContextMenuItem[], options?: IPopupOptions, onHide ipcRenderer.removeListener(onClickChannel, onClickChannelHandler); - onHide?.(); + if (onHide) { + onHide(); + } }); ipcRenderer.send(CONTEXT_MENU_CHANNEL, contextMenuId, items.map(item => createItem(item, processedItems)), onClickChannel, options); diff --git a/src/vs/base/parts/ipc/common/ipc.net.ts b/src/vs/base/parts/ipc/common/ipc.net.ts index d6833ae6ed..89c6409ac8 100644 --- a/src/vs/base/parts/ipc/common/ipc.net.ts +++ b/src/vs/base/parts/ipc/common/ipc.net.ts @@ -212,7 +212,7 @@ export class ChunkStream { return result; } - const result = VSBuffer.alloc(byteCount); + let result = VSBuffer.alloc(byteCount); let resultOffset = 0; let chunkIndex = 0; while (byteCount > 0) { @@ -675,8 +675,7 @@ class Queue { } public toArray(): T[] { - const result: T[] = []; - let resultLen = 0; + let result: T[] = [], resultLen = 0; let it = this._first; while (it) { result[resultLen++] = it.data; diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 69e3ecaefb..3f8db83855 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -640,14 +640,18 @@ export class ChannelClient implements IChannelClient, IDisposable { case RequestType.Promise: case RequestType.EventListen: { const msgLength = this.send([request.type, request.id, request.channelName, request.name], request.arg); - this.logger?.logOutgoing(msgLength, request.id, RequestInitiator.LocalSide, `${requestTypeToStr(request.type)}: ${request.channelName}.${request.name}`, request.arg); + if (this.logger) { + this.logger.logOutgoing(msgLength, request.id, RequestInitiator.LocalSide, `${requestTypeToStr(request.type)}: ${request.channelName}.${request.name}`, request.arg); + } return; } case RequestType.PromiseCancel: case RequestType.EventDispose: { const msgLength = this.send([request.type, request.id]); - this.logger?.logOutgoing(msgLength, request.id, RequestInitiator.LocalSide, requestTypeToStr(request.type)); + if (this.logger) { + this.logger.logOutgoing(msgLength, request.id, RequestInitiator.LocalSide, requestTypeToStr(request.type)); + } return; } } @@ -678,14 +682,18 @@ export class ChannelClient implements IChannelClient, IDisposable { switch (type) { case ResponseType.Initialize: - this.logger?.logIncoming(message.byteLength, 0, RequestInitiator.LocalSide, responseTypeToStr(type)); + if (this.logger) { + this.logger.logIncoming(message.byteLength, 0, RequestInitiator.LocalSide, responseTypeToStr(type)); + } return this.onResponse({ type: header[0] }); case ResponseType.PromiseSuccess: case ResponseType.PromiseError: case ResponseType.EventFire: case ResponseType.PromiseErrorObj: - this.logger?.logIncoming(message.byteLength, header[1], RequestInitiator.LocalSide, responseTypeToStr(type), body); + if (this.logger) { + this.logger.logIncoming(message.byteLength, header[1], RequestInitiator.LocalSide, responseTypeToStr(type), body); + } return this.onResponse({ type: header[0], id: header[1], data: body }); } } @@ -699,7 +707,9 @@ export class ChannelClient implements IChannelClient, IDisposable { const handler = this.handlers.get(response.id); - handler?.(response); + if (handler) { + handler(response); + } } @memoize @@ -806,7 +816,7 @@ export class IPCServer implements IChannelServer, I if (isFunction(routerOrClientFilter)) { // when no router is provided, we go random client picking - const connection = getRandomElement(that.connections.filter(routerOrClientFilter)); + let connection = getRandomElement(that.connections.filter(routerOrClientFilter)); connectionPromise = connection // if we found a client, let's call on it @@ -1171,7 +1181,7 @@ function prettyWithoutArrays(data: any): any { return data; } if (data && typeof data === 'object' && typeof data.toString === 'function') { - const result = data.toString(); + let result = data.toString(); if (result !== '[object Object]') { return result; } diff --git a/src/vs/base/parts/ipc/node/ipc.cp.ts b/src/vs/base/parts/ipc/node/ipc.cp.ts index 11751a790c..47e0b55426 100644 --- a/src/vs/base/parts/ipc/node/ipc.cp.ts +++ b/src/vs/base/parts/ipc/node/ipc.cp.ts @@ -26,7 +26,9 @@ export class Server extends IPCServer { super({ send: r => { try { - process.send?.((r.buffer).toString('base64')); + if (process.send) { + process.send((r.buffer).toString('base64')); + } } catch (e) { /* not much to do */ } }, onMessage: Event.fromNodeEventEmitter(process, 'message', msg => VSBuffer.wrap(Buffer.from(msg, 'base64'))) diff --git a/src/vs/base/parts/ipc/node/ipc.net.ts b/src/vs/base/parts/ipc/node/ipc.net.ts index 33331ff7e7..dc62e445e1 100644 --- a/src/vs/base/parts/ipc/node/ipc.net.ts +++ b/src/vs/base/parts/ipc/node/ipc.net.ts @@ -3,10 +3,9 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// import { createHash } from 'crypto'; -import type { Server as NetServer, Socket } from 'net'; -// import { tmpdir } from 'os'; -import type * as zlib from 'zlib'; +import { createHash } from 'crypto'; +import { createConnection, createServer, Server as NetServer, Socket } from 'net'; +import { tmpdir } from 'os'; import { VSBuffer } from 'vs/base/common/buffer'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, Event } from 'vs/base/common/event'; @@ -16,16 +15,7 @@ import { Platform, platform } from 'vs/base/common/platform'; import { generateUuid } from 'vs/base/common/uuid'; import { ClientConnectionEvent, IPCServer } from 'vs/base/parts/ipc/common/ipc'; import { ChunkStream, Client, ISocket, Protocol, SocketCloseEvent, SocketCloseEventType, SocketDiagnostics, SocketDiagnosticsEventType } from 'vs/base/parts/ipc/common/ipc.net'; - -// TODO@bpasero remove me once electron utility process has landed -function getNodeDependencies() { - return { - crypto: (require.__$__nodeRequire('crypto') as any) as typeof import('crypto'), - zlib: (require.__$__nodeRequire('zlib') as any) as typeof import('zlib'), - net: (require.__$__nodeRequire('net') as any) as typeof import('net'), - os: (require.__$__nodeRequire('os') as any) as typeof import('os') - }; -} +import * as zlib from 'zlib'; export class NodeSocket implements ISocket { @@ -590,7 +580,7 @@ class ZlibInflateStream extends Disposable { options: zlib.ZlibOptions ) { super(); - this._zlibInflate = getNodeDependencies().zlib.createInflateRaw(options); + this._zlibInflate = zlib.createInflateRaw(options); this._zlibInflate.on('error', (err) => { this._tracer.traceSocketEvent(SocketDiagnosticsEventType.zlibInflateError, { message: err?.message, code: (err)?.code }); this._onError.fire(err); @@ -641,7 +631,7 @@ class ZlibDeflateStream extends Disposable { ) { super(); - this._zlibDeflate = getNodeDependencies().zlib.createDeflateRaw({ + this._zlibDeflate = zlib.createDeflateRaw({ windowBits: 15 }); this._zlibDeflate.on('error', (err) => { @@ -679,13 +669,13 @@ function unmask(buffer: VSBuffer, mask: number): void { if (mask === 0) { return; } - const cnt = buffer.byteLength >>> 2; + let cnt = buffer.byteLength >>> 2; for (let i = 0; i < cnt; i++) { const v = buffer.readUInt32BE(i * 4); buffer.writeUInt32BE(v ^ mask, i * 4); } - const offset = cnt * 4; - const bytesLeft = buffer.byteLength - offset; + let offset = cnt * 4; + let bytesLeft = buffer.byteLength - offset; const m3 = (mask >>> 24) & 0b11111111; const m2 = (mask >>> 16) & 0b11111111; const m1 = (mask >>> 8) & 0b11111111; @@ -702,8 +692,7 @@ function unmask(buffer: VSBuffer, mask: number): void { // Read this before there's any chance it is overwritten // Related to https://github.com/microsoft/vscode/issues/30624 -// TODO@bpasero revert me once electron utility process has landed -export const XDG_RUNTIME_DIR = typeof process !== 'undefined' ? process.env['XDG_RUNTIME_DIR'] : undefined; +export const XDG_RUNTIME_DIR = process.env['XDG_RUNTIME_DIR']; const safeIpcPathLengths: { [platform: number]: number } = { [Platform.Linux]: 107, @@ -724,7 +713,7 @@ export function createRandomIPCHandle(): string { if (XDG_RUNTIME_DIR) { result = join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`); } else { - result = join(getNodeDependencies().os.tmpdir(), `vscode-ipc-${randomSuffix}.sock`); + result = join(tmpdir(), `vscode-ipc-${randomSuffix}.sock`); } // Validate length @@ -734,7 +723,7 @@ export function createRandomIPCHandle(): string { } export function createStaticIPCHandle(directoryPath: string, type: string, version: string): string { - const scope = getNodeDependencies().crypto.createHash('md5').update(directoryPath).digest('hex'); + const scope = createHash('md5').update(directoryPath).digest('hex'); // Windows: use named pipe if (process.platform === 'win32') { @@ -796,7 +785,7 @@ export function serve(port: number): Promise; export function serve(namedPipe: string): Promise; export function serve(hook: any): Promise { return new Promise((c, e) => { - const server = getNodeDependencies().net.createServer(); + const server = createServer(); server.on('error', e); server.listen(hook, () => { @@ -811,7 +800,7 @@ export function connect(port: number, clientId: string): Promise; export function connect(namedPipe: string, clientId: string): Promise; export function connect(hook: any, clientId: string): Promise { return new Promise((c, e) => { - const socket = getNodeDependencies().net.createConnection(hook, () => { + const socket = createConnection(hook, () => { socket.removeListener('error', e); c(Client.fromSocket(new NodeSocket(socket, `ipc-client${clientId}`), clientId)); }); diff --git a/src/vs/base/parts/quickinput/browser/media/quickInput.css b/src/vs/base/parts/quickinput/browser/media/quickInput.css index 6bcfb8e1e5..1cfc8bf506 100644 --- a/src/vs/base/parts/quickinput/browser/media/quickInput.css +++ b/src/vs/base/parts/quickinput/browser/media/quickInput.css @@ -6,10 +6,10 @@ .quick-input-widget { position: absolute; width: 600px; - z-index: 2550; + z-index: 2000; + padding: 0 1px 1px 1px; left: 50%; margin-left: -300px; - -webkit-app-region: no-drag; } .quick-input-titlebar { @@ -150,7 +150,6 @@ .quick-input-list { line-height: 22px; margin-top: 6px; - padding: 0px 1px 1px 1px; } .quick-input-widget.hidden-input .quick-input-list { diff --git a/src/vs/base/parts/quickinput/browser/quickInput.ts b/src/vs/base/parts/quickinput/browser/quickInput.ts index 8ca3721f8f..3be9cd4417 100644 --- a/src/vs/base/parts/quickinput/browser/quickInput.ts +++ b/src/vs/base/parts/quickinput/browser/quickInput.ts @@ -450,7 +450,6 @@ class QuickPick extends QuickInput implements IQuickPi private _matchOnDescription = false; private _matchOnDetail = false; private _matchOnLabel = true; - private _matchOnLabelMode: 'fuzzy' | 'contiguous' = 'fuzzy'; private _sortByLabel = true; private _autoFocusOnList = true; private _keepScrollPosition = false; @@ -596,15 +595,6 @@ class QuickPick extends QuickInput implements IQuickPi this.update(); } - get matchOnLabelMode() { - return this._matchOnLabelMode; - } - - set matchOnLabelMode(matchOnLabelMode: 'fuzzy' | 'contiguous') { - this._matchOnLabelMode = matchOnLabelMode; - this.update(); - } - get sortByLabel() { return this._sortByLabel; } @@ -989,22 +979,13 @@ class QuickPick extends QuickInput implements IQuickPi if (this.ui.inputBox.placeholder !== (this.placeholder || '')) { this.ui.inputBox.placeholder = (this.placeholder || ''); } - - let ariaLabel = this.ariaLabel; - if (!ariaLabel) { - ariaLabel = this.placeholder || QuickPick.DEFAULT_ARIA_LABEL; - // If we have a title, include it in the aria label. - if (this.title) { - ariaLabel += ` - ${this.title}`; - } - } + const ariaLabel = this.ariaLabel || this.placeholder || QuickPick.DEFAULT_ARIA_LABEL; if (this.ui.inputBox.ariaLabel !== ariaLabel) { this.ui.inputBox.ariaLabel = ariaLabel; } this.ui.list.matchOnDescription = this.matchOnDescription; this.ui.list.matchOnDetail = this.matchOnDetail; this.ui.list.matchOnLabel = this.matchOnLabel; - this.ui.list.matchOnLabelMode = this.matchOnLabelMode; this.ui.list.sortByLabel = this.sortByLabel; if (this.itemsUpdated) { this.itemsUpdated = false; @@ -1252,7 +1233,6 @@ export class QuickInputController extends Disposable { const checkAll = dom.append(headerContainer, $('input.quick-input-check-all')); checkAll.type = 'checkbox'; - checkAll.setAttribute('aria-label', localize('quickInput.checkAll', "Toggle all checkboxes")); this._register(dom.addStandardDisposableListener(checkAll, dom.EventType.CHANGE, e => { const checked = checkAll.checked; list.setAllVisibleChecked(checked); @@ -1417,7 +1397,9 @@ export class QuickInputController extends Disposable { return new Promise((doResolve, reject) => { let resolve = (result: R) => { resolve = doResolve; - options.onKeyMods?.(input.keyMods); + if (options.onKeyMods) { + options.onKeyMods(input.keyMods); + } doResolve(result); }; if (token.isCancellationRequested) { diff --git a/src/vs/base/parts/quickinput/browser/quickInputList.ts b/src/vs/base/parts/quickinput/browser/quickInputList.ts index 687eb13ad8..df4b425cc6 100644 --- a/src/vs/base/parts/quickinput/browser/quickInputList.ts +++ b/src/vs/base/parts/quickinput/browser/quickInputList.ts @@ -17,11 +17,10 @@ import { compareAnything } from 'vs/base/common/comparers'; import { memoize } from 'vs/base/common/decorators'; import { Emitter, Event } from 'vs/base/common/event'; import { IMatch } from 'vs/base/common/filters'; -import { IParsedLabelWithIcons, matchesFuzzyIconAware, parseLabelWithIcons } from 'vs/base/common/iconLabels'; +import { matchesFuzzyIconAware, parseLabelWithIcons } from 'vs/base/common/iconLabels'; import { KeyCode } from 'vs/base/common/keyCodes'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; -import { ltrim } from 'vs/base/common/strings'; import { withNullAsUndefined } from 'vs/base/common/types'; import { IQuickInputOptions } from 'vs/base/parts/quickinput/browser/quickInput'; import { getIconClass } from 'vs/base/parts/quickinput/browser/quickInputUtils'; @@ -36,7 +35,6 @@ interface IListElement { readonly index: number; readonly item: IQuickPickItem; readonly saneLabel: string; - readonly saneSortLabel: string; readonly saneMeta?: string; readonly saneAriaLabel: string; readonly saneDescription?: string; @@ -54,7 +52,6 @@ class ListElement implements IListElement, IDisposable { index!: number; item!: IQuickPickItem; saneLabel!: string; - saneSortLabel!: string; saneMeta!: string; saneAriaLabel!: string; saneDescription?: string; @@ -259,7 +256,6 @@ export class QuickInputList { matchOnDescription = false; matchOnDetail = false; matchOnLabel = true; - matchOnLabelMode: 'fuzzy' | 'contiguous' = 'fuzzy'; matchOnMeta = true; sortByLabel = true; private readonly _onChangedAllVisibleChecked = new Emitter(); @@ -444,7 +440,6 @@ export class QuickInputList { if (item.type !== 'separator') { const previous = index && inputElements[index - 1]; const saneLabel = item.label && item.label.replace(/\r?\n/g, ' '); - const saneSortLabel = parseLabelWithIcons(saneLabel).text.trim(); const saneMeta = item.meta && item.meta.replace(/\r?\n/g, ' '); const saneDescription = item.description && item.description.replace(/\r?\n/g, ' '); const saneDetail = item.detail && item.detail.replace(/\r?\n/g, ' '); @@ -459,7 +454,6 @@ export class QuickInputList { index, item, saneLabel, - saneSortLabel, saneMeta, saneAriaLabel, saneDescription, @@ -612,8 +606,6 @@ export class QuickInputList { this.list.layout(); return false; } - - const queryWithWhitespace = query; query = query.trim(); // Reset filtering @@ -632,12 +624,7 @@ export class QuickInputList { else { let currentSeparator: IQuickPickSeparator | undefined; this.elements.forEach(element => { - let labelHighlights: IMatch[] | undefined; - if (this.matchOnLabelMode === 'fuzzy') { - labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; - } else { - labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesContiguousIconAware(queryWithWhitespace, parseLabelWithIcons(element.saneLabel))) : undefined; - } + const labelHighlights = this.matchOnLabel ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel))) : undefined; const descriptionHighlights = this.matchOnDescription ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDescription || ''))) : undefined; const detailHighlights = this.matchOnDetail ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneDetail || ''))) : undefined; const metaHighlights = this.matchOnMeta ? withNullAsUndefined(matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneMeta || ''))) : undefined; @@ -735,43 +722,6 @@ export class QuickInputList { } } -export function matchesContiguousIconAware(query: string, target: IParsedLabelWithIcons): IMatch[] | null { - - const { text, iconOffsets } = target; - - // Return early if there are no icon markers in the word to match against - if (!iconOffsets || iconOffsets.length === 0) { - return matchesContiguous(query, text); - } - - // Trim the word to match against because it could have leading - // whitespace now if the word started with an icon - const wordToMatchAgainstWithoutIconsTrimmed = ltrim(text, ' '); - const leadingWhitespaceOffset = text.length - wordToMatchAgainstWithoutIconsTrimmed.length; - - // match on value without icon - const matches = matchesContiguous(query, wordToMatchAgainstWithoutIconsTrimmed); - - // Map matches back to offsets with icon and trimming - if (matches) { - for (const match of matches) { - const iconOffset = iconOffsets[match.start + leadingWhitespaceOffset] /* icon offsets at index */ + leadingWhitespaceOffset /* overall leading whitespace offset */; - match.start += iconOffset; - match.end += iconOffset; - } - } - - return matches; -} - -function matchesContiguous(word: string, wordToMatchAgainst: string): IMatch[] | null { - const matchIndex = wordToMatchAgainst.toLowerCase().indexOf(word.toLowerCase()); - if (matchIndex !== -1) { - return [{ start: matchIndex, end: matchIndex + word.length }]; - } - return null; -} - function compareEntries(elementA: ListElement, elementB: ListElement, lookFor: string): number { const labelHighlightsA = elementA.labelHighlights || []; @@ -788,7 +738,7 @@ function compareEntries(elementA: ListElement, elementB: ListElement, lookFor: s return 0; } - return compareAnything(elementA.saneSortLabel, elementB.saneSortLabel, lookFor); + return compareAnything(elementA.saneLabel, elementB.saneLabel, lookFor); } class QuickInputAccessibilityProvider implements IListAccessibilityProvider { @@ -798,9 +748,7 @@ class QuickInputAccessibilityProvider implements IListAccessibilityProvider extends IQuickInput { matchOnLabel: boolean; - /** - * The mode to filter label with. Fuzzy will use fuzzy searching and - * contiguous will make filter entries that do not contain the exact string - * (including whitespace). This defaults to `'fuzzy'`. - */ - matchOnLabelMode: 'fuzzy' | 'contiguous'; - sortByLabel: boolean; autoFocusOnList: boolean; diff --git a/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts b/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts index d968ba648e..a1a6962b4d 100644 --- a/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts +++ b/src/vs/base/parts/quickinput/test/browser/quickinput.test.ts @@ -6,26 +6,18 @@ import * as assert from 'assert'; import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IListOptions, List } from 'vs/base/browser/ui/list/listWidget'; -import { raceTimeout } from 'vs/base/common/async'; import { QuickInputController } from 'vs/base/parts/quickinput/browser/quickInput'; import { IQuickPick, IQuickPickItem } from 'vs/base/parts/quickinput/common/quickInput'; +import { flakySuite } from 'vs/base/test/common/testUtils'; -// Sets up an `onShow` listener to allow us to wait until the quick pick is shown (useful when triggering an `accept()` right after launching a quick pick) -// kick this off before you launch the picker and then await the promise returned after you launch the picker. -async function setupWaitTilShownListener(controller: QuickInputController): Promise { - const result = await raceTimeout(new Promise(resolve => { - const event = controller.onShow(_ => { - event.dispose(); - resolve(true); - }); - }), 2000); - - if (!result) { - throw new Error('Cancelled'); - } +// Simple promisify of setTimeout +function wait(delayMS: number) { + return new Promise(function (resolve) { + setTimeout(resolve, delayMS); + }); } -suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 +flakySuite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 let fixture: HTMLElement, controller: QuickInputController, quickpick: IQuickPick; function getScrollTop(): number { @@ -74,38 +66,30 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 test('pick - basecase', async () => { const item = { label: 'foo' }; - - const wait = setupWaitTilShownListener(controller); const pickPromise = controller.pick([item, { label: 'bar' }]); - await wait; - + // wait a bit to let the pick get set up. + await wait(200); controller.accept(); const pick = await pickPromise; - assert.strictEqual(pick, item); }); test('pick - activeItem is honored', async () => { const item = { label: 'foo' }; - - const wait = setupWaitTilShownListener(controller); const pickPromise = controller.pick([{ label: 'bar' }, item], { activeItem: item }); - await wait; - + // wait a bit to let the pick get set up. + await wait(200); controller.accept(); const pick = await pickPromise; - assert.strictEqual(pick, item); }); test('input - basecase', async () => { - const wait = setupWaitTilShownListener(controller); const inputPromise = controller.input({ value: 'foo' }); - await wait; - + // wait a bit to let the pick get set up. + await wait(200); controller.accept(); const value = await inputPromise; - assert.strictEqual(value, 'foo'); }); @@ -119,6 +103,8 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 quickpick.value = 'changed'; try { + // wait a bit to let the event play out. + await wait(200); assert.strictEqual(value, quickpick.value); } finally { quickpick.dispose(); @@ -137,7 +123,7 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 quickpick.activeItems = [items[items.length - 1]]; quickpick.show(); - const cursorTop = getScrollTop(); + let cursorTop = getScrollTop(); assert.notStrictEqual(cursorTop, 0); @@ -162,7 +148,7 @@ suite('QuickInput', () => { // https://github.com/microsoft/vscode/issues/147543 quickpick.activeItems = [items[items.length - 1]]; quickpick.show(); - const cursorTop = getScrollTop(); + let cursorTop = getScrollTop(); assert.notStrictEqual(cursorTop, 0); quickpick.keepScrollPosition = true; diff --git a/src/vs/base/parts/request/browser/request.ts b/src/vs/base/parts/request/browser/request.ts index 7184c4f65f..b4710e25a0 100644 --- a/src/vs/base/parts/request/browser/request.ts +++ b/src/vs/base/parts/request/browser/request.ts @@ -55,7 +55,7 @@ export function request(options: IRequestOptions, token: CancellationToken): Pro function setRequestHeaders(xhr: XMLHttpRequest, options: IRequestOptions): void { if (options.headers) { - outer: for (const k in options.headers) { + outer: for (let k in options.headers) { switch (k) { case 'User-Agent': case 'Accept-Encoding': diff --git a/src/vs/base/parts/sandbox/electron-browser/preload.js b/src/vs/base/parts/sandbox/electron-browser/preload.js index 4596427566..b229856517 100644 --- a/src/vs/base/parts/sandbox/electron-browser/preload.js +++ b/src/vs/base/parts/sandbox/electron-browser/preload.js @@ -145,7 +145,7 @@ /** * @param {string} channel * @param {any[]} args - * @returns {Promise | never} + * @returns {Promise | undefined} */ invoke(channel, ...args) { if (validateIPC(channel)) { @@ -156,7 +156,7 @@ /** * @param {string} channel * @param {(event: IpcRendererEvent, ...args: any[]) => void} listener - * @returns {IpcRenderer | never} + * @returns {IpcRenderer} */ on(channel, listener) { if (validateIPC(channel)) { @@ -169,7 +169,7 @@ /** * @param {string} channel * @param {(event: IpcRendererEvent, ...args: any[]) => void} listener - * @returns {IpcRenderer | never} + * @returns {IpcRenderer} */ once(channel, listener) { if (validateIPC(channel)) { @@ -182,7 +182,7 @@ /** * @param {string} channel * @param {(event: IpcRendererEvent, ...args: any[]) => void} listener - * @returns {IpcRenderer | never} + * @returns {IpcRenderer} */ removeListener(channel, listener) { if (validateIPC(channel)) { diff --git a/src/vs/base/parts/sandbox/electron-sandbox/globals.ts b/src/vs/base/parts/sandbox/electron-sandbox/globals.ts index 89567fc947..c8c975eeb5 100644 --- a/src/vs/base/parts/sandbox/electron-sandbox/globals.ts +++ b/src/vs/base/parts/sandbox/electron-sandbox/globals.ts @@ -36,10 +36,6 @@ export interface ISandboxNodeProcess extends INodeProcess { /** * The `process.pid` property returns the PID of the process. - * - * @deprecated this property will be removed once sandbox is enabled. - * - * TODO@bpasero remove this property when sandbox is on */ readonly pid: number; diff --git a/src/vs/base/parts/storage/common/storage.ts b/src/vs/base/parts/storage/common/storage.ts index ab30b16ddf..4024f471e9 100644 --- a/src/vs/base/parts/storage/common/storage.ts +++ b/src/vs/base/parts/storage/common/storage.ts @@ -357,9 +357,13 @@ export class InMemoryStorageDatabase implements IStorageDatabase { } async updateItems(request: IUpdateRequest): Promise { - request.insert?.forEach((value, key) => this.items.set(key, value)); + if (request.insert) { + request.insert.forEach((value, key) => this.items.set(key, value)); + } - request.delete?.forEach(key => this.items.delete(key)); + if (request.delete) { + request.delete.forEach(key => this.items.delete(key)); + } } async close(): Promise { } diff --git a/src/vs/base/parts/storage/node/storage.ts b/src/vs/base/parts/storage/node/storage.ts index 8258ddafd0..89dbbcf0bb 100644 --- a/src/vs/base/parts/storage/node/storage.ts +++ b/src/vs/base/parts/storage/node/storage.ts @@ -301,9 +301,9 @@ export class SQLiteStorageDatabase implements IStorageDatabase { return new Promise((resolve, reject) => { import('@vscode/sqlite3').then(sqlite3 => { const connection: IDatabaseConnection = { - db: new (this.logger.isTracing ? sqlite3.verbose().Database : sqlite3.Database)(path, (error: (Error & { code?: string }) | null) => { + db: new (this.logger.isTracing ? sqlite3.verbose().Database : sqlite3.Database)(path, error => { if (error) { - return (connection.db && error.code !== 'SQLITE_CANTOPEN' /* https://github.com/TryGhost/node-sqlite3/issues/1617 */) ? connection.db.close(() => reject(error)) : reject(error); + return connection.db ? connection.db.close(() => reject(error)) : reject(error); } // The following exec() statement serves two purposes: @@ -440,10 +440,14 @@ class SQLiteStorageDatabaseLogger { } trace(msg: string): void { - this.logTrace?.(msg); + if (this.logTrace) { + this.logTrace(msg); + } } error(error: string | Error): void { - this.logError?.(error); + if (this.logError) { + this.logError(error); + } } } diff --git a/src/vs/base/parts/storage/test/node/storage.test.ts b/src/vs/base/parts/storage/test/node/storage.test.ts index 68a304ed5f..788cfb47c7 100644 --- a/src/vs/base/parts/storage/test/node/storage.test.ts +++ b/src/vs/base/parts/storage/test/node/storage.test.ts @@ -123,7 +123,7 @@ flakySuite('Storage Library', function () { const database = new TestSQLiteStorageDatabase(join(testDir, 'storage.db')); const storage = new Storage(database); - const changes = new Set(); + let changes = new Set(); storage.onDidChangeStorage(key => { changes.add(key); }); @@ -223,7 +223,7 @@ flakySuite('Storage Library', function () { }); test('explicit flush', async () => { - const storage = new Storage(new SQLiteStorageDatabase(join(testDir, 'storage.db'))); + let storage = new Storage(new SQLiteStorageDatabase(join(testDir, 'storage.db'))); await storage.init(); storage.set('foo', 'bar'); @@ -243,7 +243,7 @@ flakySuite('Storage Library', function () { test('conflicting updates', () => { return runWithFakedTimers({}, async function () { - const storage = new Storage(new SQLiteStorageDatabase(join(testDir, 'storage.db'))); + let storage = new Storage(new SQLiteStorageDatabase(join(testDir, 'storage.db'))); await storage.init(); let changes = new Set(); @@ -623,7 +623,7 @@ flakySuite('SQLite Storage Library', function () { }); test('very large item value', async function () { - const storage = new SQLiteStorageDatabase(join(testdir, 'storage.db')); + let storage = new SQLiteStorageDatabase(join(testdir, 'storage.db')); const items = new Map(); items.set('colorthemedata', '{"id":"vs vscode-theme-defaults-themes-light_plus-json","label":"Light+ (default light)","settingsId":"Default Light+","selector":"vs.vscode-theme-defaults-themes-light_plus-json","themeTokenColors":[{"settings":{"foreground":"#000000ff","background":"#ffffffff"}},{"scope":["meta.embedded","source.groovy.embedded"],"settings":{"foreground":"#000000ff"}},{"scope":"emphasis","settings":{"fontStyle":"italic"}},{"scope":"strong","settings":{"fontStyle":"bold"}},{"scope":"meta.diff.header","settings":{"foreground":"#000080"}},{"scope":"comment","settings":{"foreground":"#008000"}},{"scope":"constant.language","settings":{"foreground":"#0000ff"}},{"scope":["constant.numeric"],"settings":{"foreground":"#098658"}},{"scope":"constant.regexp","settings":{"foreground":"#811f3f"}},{"name":"css tags in selectors, xml tags","scope":"entity.name.tag","settings":{"foreground":"#800000"}},{"scope":"entity.name.selector","settings":{"foreground":"#800000"}},{"scope":"entity.other.attribute-name","settings":{"foreground":"#ff0000"}},{"scope":["entity.other.attribute-name.class.css","entity.other.attribute-name.class.mixin.css","entity.other.attribute-name.id.css","entity.other.attribute-name.parent-selector.css","entity.other.attribute-name.pseudo-class.css","entity.other.attribute-name.pseudo-element.css","source.css.less entity.other.attribute-name.id","entity.other.attribute-name.attribute.scss","entity.other.attribute-name.scss"],"settings":{"foreground":"#800000"}},{"scope":"invalid","settings":{"foreground":"#cd3131"}},{"scope":"markup.underline","settings":{"fontStyle":"underline"}},{"scope":"markup.bold","settings":{"fontStyle":"bold","foreground":"#000080"}},{"scope":"markup.heading","settings":{"fontStyle":"bold","foreground":"#800000"}},{"scope":"markup.italic","settings":{"fontStyle":"italic"}},{"scope":"markup.inserted","settings":{"foreground":"#098658"}},{"scope":"markup.deleted","settings":{"foreground":"#a31515"}},{"scope":"markup.changed","settings":{"foreground":"#0451a5"}},{"scope":["punctuation.definition.quote.begin.markdown","punctuation.definition.list.begin.markdown"],"settings":{"foreground":"#0451a5"}},{"scope":"markup.inline.raw","settings":{"foreground":"#800000"}},{"name":"brackets of XML/HTML tags","scope":"punctuation.definition.tag","settings":{"foreground":"#800000"}},{"scope":"meta.preprocessor","settings":{"foreground":"#0000ff"}},{"scope":"meta.preprocessor.string","settings":{"foreground":"#a31515"}},{"scope":"meta.preprocessor.numeric","settings":{"foreground":"#098658"}},{"scope":"meta.structure.dictionary.key.python","settings":{"foreground":"#0451a5"}},{"scope":"storage","settings":{"foreground":"#0000ff"}},{"scope":"storage.type","settings":{"foreground":"#0000ff"}},{"scope":"storage.modifier","settings":{"foreground":"#0000ff"}},{"scope":"string","settings":{"foreground":"#a31515"}},{"scope":["string.comment.buffered.block.pug","string.quoted.pug","string.interpolated.pug","string.unquoted.plain.in.yaml","string.unquoted.plain.out.yaml","string.unquoted.block.yaml","string.quoted.single.yaml","string.quoted.double.xml","string.quoted.single.xml","string.unquoted.cdata.xml","string.quoted.double.html","string.quoted.single.html","string.unquoted.html","string.quoted.single.handlebars","string.quoted.double.handlebars"],"settings":{"foreground":"#0000ff"}},{"scope":"string.regexp","settings":{"foreground":"#811f3f"}},{"name":"String interpolation","scope":["punctuation.definition.template-expression.begin","punctuation.definition.template-expression.end","punctuation.section.embedded"],"settings":{"foreground":"#0000ff"}},{"name":"Reset JavaScript string interpolation expression","scope":["meta.template.expression"],"settings":{"foreground":"#000000"}},{"scope":["support.constant.property-value","support.constant.font-name","support.constant.media-type","support.constant.media","constant.other.color.rgb-value","constant.other.rgb-value","support.constant.color"],"settings":{"foreground":"#0451a5"}},{"scope":["support.type.vendored.property-name","support.type.property-name","variable.css","variable.scss","variable.other.less","source.coffee.embedded"],"settings":{"foreground":"#ff0000"}},{"scope":["support.type.property-name.json"],"settings":{"foreground":"#0451a5"}},{"scope":"keyword","settings":{"foreground":"#0000ff"}},{"scope":"keyword.control","settings":{"foreground":"#0000ff"}},{"scope":"keyword.operator","settings":{"foreground":"#000000"}},{"scope":["keyword.operator.new","keyword.operator.expression","keyword.operator.cast","keyword.operator.sizeof","keyword.operator.instanceof","keyword.operator.logical.python"],"settings":{"foreground":"#0000ff"}},{"scope":"keyword.other.unit","settings":{"foreground":"#098658"}},{"scope":["punctuation.section.embedded.begin.php","punctuation.section.embedded.end.php"],"settings":{"foreground":"#800000"}},{"scope":"support.function.git-rebase","settings":{"foreground":"#0451a5"}},{"scope":"constant.sha.git-rebase","settings":{"foreground":"#098658"}},{"name":"coloring of the Java import and package identifiers","scope":["storage.modifier.import.java","variable.language.wildcard.java","storage.modifier.package.java"],"settings":{"foreground":"#000000"}},{"name":"this.self","scope":"variable.language","settings":{"foreground":"#0000ff"}},{"name":"Function declarations","scope":["entity.name.function","support.function","support.constant.handlebars"],"settings":{"foreground":"#795E26"}},{"name":"Types declaration and references","scope":["meta.return-type","support.class","support.type","entity.name.type","entity.name.class","storage.type.numeric.go","storage.type.byte.go","storage.type.boolean.go","storage.type.string.go","storage.type.uintptr.go","storage.type.error.go","storage.type.rune.go","storage.type.cs","storage.type.generic.cs","storage.type.modifier.cs","storage.type.variable.cs","storage.type.annotation.java","storage.type.generic.java","storage.type.java","storage.type.object.array.java","storage.type.primitive.array.java","storage.type.primitive.java","storage.type.token.java","storage.type.groovy","storage.type.annotation.groovy","storage.type.parameters.groovy","storage.type.generic.groovy","storage.type.object.array.groovy","storage.type.primitive.array.groovy","storage.type.primitive.groovy"],"settings":{"foreground":"#267f99"}},{"name":"Types declaration and references, TS grammar specific","scope":["meta.type.cast.expr","meta.type.new.expr","support.constant.math","support.constant.dom","support.constant.json","entity.other.inherited-class"],"settings":{"foreground":"#267f99"}},{"name":"Control flow keywords","scope":"keyword.control","settings":{"foreground":"#AF00DB"}},{"name":"Variable and parameter name","scope":["variable","meta.definition.variable.name","support.variable","entity.name.variable"],"settings":{"foreground":"#001080"}},{"name":"Object keys, TS grammar specific","scope":["meta.object-literal.key"],"settings":{"foreground":"#001080"}},{"name":"CSS property value","scope":["support.constant.property-value","support.constant.font-name","support.constant.media-type","support.constant.media","constant.other.color.rgb-value","constant.other.rgb-value","support.constant.color"],"settings":{"foreground":"#0451a5"}},{"name":"Regular expression groups","scope":["punctuation.definition.group.regexp","punctuation.definition.group.assertion.regexp","punctuation.definition.character-class.regexp","punctuation.character.set.begin.regexp","punctuation.character.set.end.regexp","keyword.operator.negation.regexp","support.other.parenthesis.regexp"],"settings":{"foreground":"#d16969"}},{"scope":["constant.character.character-class.regexp","constant.other.character-class.set.regexp","constant.other.character-class.regexp","constant.character.set.regexp"],"settings":{"foreground":"#811f3f"}},{"scope":"keyword.operator.quantifier.regexp","settings":{"foreground":"#000000"}},{"scope":["keyword.operator.or.regexp","keyword.control.anchor.regexp"],"settings":{"foreground":"#ff0000"}},{"scope":"constant.character","settings":{"foreground":"#0000ff"}},{"scope":"constant.character.escape","settings":{"foreground":"#ff0000"}},{"scope":"token.info-token","settings":{"foreground":"#316bcd"}},{"scope":"token.warn-token","settings":{"foreground":"#cd9731"}},{"scope":"token.error-token","settings":{"foreground":"#cd3131"}},{"scope":"token.debug-token","settings":{"foreground":"#800080"}}],"extensionData":{"extensionId":"vscode.theme-defaults","extensionPublisher":"vscode","extensionName":"theme-defaults","extensionIsBuiltin":true},"colorMap":{"editor.background":"#ffffff","editor.foreground":"#000000","editor.inactiveSelectionBackground":"#e5ebf1","editorIndentGuide.background":"#d3d3d3","editorIndentGuide.activeBackground":"#939393","editor.selectionHighlightBackground":"#add6ff4d","editorSuggestWidget.background":"#f3f3f3","activityBarBadge.background":"#007acc","sideBarTitle.foreground":"#6f6f6f","list.hoverBackground":"#e8e8e8","input.placeholderForeground":"#767676","settings.textInputBorder":"#cecece","settings.numberInputBorder":"#cecece"}}'); @@ -670,57 +670,56 @@ flakySuite('SQLite Storage Library', function () { }); test('multiple concurrent writes execute in sequence', async () => { - return runWithFakedTimers({}, async () => { - class TestStorage extends Storage { - getStorage(): IStorageDatabase { - return this.database; - } + + class TestStorage extends Storage { + getStorage(): IStorageDatabase { + return this.database; } + } - const storage = new TestStorage(new SQLiteStorageDatabase(join(testdir, 'storage.db'))); + const storage = new TestStorage(new SQLiteStorageDatabase(join(testdir, 'storage.db'))); - await storage.init(); + await storage.init(); - storage.set('foo', 'bar'); - storage.set('some/foo/path', 'some/bar/path'); + storage.set('foo', 'bar'); + storage.set('some/foo/path', 'some/bar/path'); - await timeout(2); + await timeout(2); - storage.set('foo1', 'bar'); - storage.set('some/foo1/path', 'some/bar/path'); + storage.set('foo1', 'bar'); + storage.set('some/foo1/path', 'some/bar/path'); - await timeout(2); + await timeout(2); - storage.set('foo2', 'bar'); - storage.set('some/foo2/path', 'some/bar/path'); + storage.set('foo2', 'bar'); + storage.set('some/foo2/path', 'some/bar/path'); - await timeout(2); + await timeout(2); - storage.delete('foo1'); - storage.delete('some/foo1/path'); + storage.delete('foo1'); + storage.delete('some/foo1/path'); - await timeout(2); + await timeout(2); - storage.delete('foo4'); - storage.delete('some/foo4/path'); + storage.delete('foo4'); + storage.delete('some/foo4/path'); - await timeout(5); + await timeout(5); - storage.set('foo3', 'bar'); - await storage.set('some/foo3/path', 'some/bar/path'); + storage.set('foo3', 'bar'); + await storage.set('some/foo3/path', 'some/bar/path'); - const items = await storage.getStorage().getItems(); - strictEqual(items.get('foo'), 'bar'); - strictEqual(items.get('some/foo/path'), 'some/bar/path'); - strictEqual(items.has('foo1'), false); - strictEqual(items.has('some/foo1/path'), false); - strictEqual(items.get('foo2'), 'bar'); - strictEqual(items.get('some/foo2/path'), 'some/bar/path'); - strictEqual(items.get('foo3'), 'bar'); - strictEqual(items.get('some/foo3/path'), 'some/bar/path'); + const items = await storage.getStorage().getItems(); + strictEqual(items.get('foo'), 'bar'); + strictEqual(items.get('some/foo/path'), 'some/bar/path'); + strictEqual(items.has('foo1'), false); + strictEqual(items.has('some/foo1/path'), false); + strictEqual(items.get('foo2'), 'bar'); + strictEqual(items.get('some/foo2/path'), 'some/bar/path'); + strictEqual(items.get('foo3'), 'bar'); + strictEqual(items.get('some/foo3/path'), 'some/bar/path'); - await storage.close(); - }); + await storage.close(); }); test('lots of INSERT & DELETE (below inline max)', async () => { @@ -774,18 +773,4 @@ flakySuite('SQLite Storage Library', function () { await storage.close(); }); - - test('invalid path does not hang', async () => { - const storage = new SQLiteStorageDatabase(join(testdir, 'nonexist', 'storage.db')); - - let error; - try { - await storage.getItems(); - await storage.close(); - } catch (e) { - error = e; - } - - ok(error); - }); }); diff --git a/src/vs/base/test/browser/actionbar.test.ts b/src/vs/base/test/browser/actionbar.test.ts index ddb9b65e6d..f9c22ec75e 100644 --- a/src/vs/base/test/browser/actionbar.test.ts +++ b/src/vs/base/test/browser/actionbar.test.ts @@ -10,15 +10,15 @@ import { Action, Separator } from 'vs/base/common/actions'; suite('Actionbar', () => { test('prepareActions()', function () { - const a1 = new Separator(); - const a2 = new Separator(); - const a3 = new Action('a3'); - const a4 = new Separator(); - const a5 = new Separator(); - const a6 = new Action('a6'); - const a7 = new Separator(); + let a1 = new Separator(); + let a2 = new Separator(); + let a3 = new Action('a3'); + let a4 = new Separator(); + let a5 = new Separator(); + let a6 = new Action('a6'); + let a7 = new Separator(); - const actions = prepareActions([a1, a2, a3, a4, a5, a6, a7]); + let actions = prepareActions([a1, a2, a3, a4, a5, a6, a7]); assert.strictEqual(actions.length, 3); // duplicate separators get removed assert(actions[0] === a3); assert(actions[1] === a5); @@ -29,8 +29,8 @@ suite('Actionbar', () => { const container = document.createElement('div'); const actionbar = new ActionBar(container); - const a1 = new Action('a1'); - const a2 = new Action('a2'); + let a1 = new Action('a1'); + let a2 = new Action('a2'); actionbar.push(a1); assert.strictEqual(actionbar.hasAction(a1), true); diff --git a/src/vs/base/test/browser/dom.test.ts b/src/vs/base/test/browser/dom.test.ts index 5296b529a8..e6f0831f85 100644 --- a/src/vs/base/test/browser/dom.test.ts +++ b/src/vs/base/test/browser/dom.test.ts @@ -4,12 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { $, h, multibyteAwareBtoa } from 'vs/base/browser/dom'; +import * as dom from 'vs/base/browser/dom'; +const $ = dom.$; suite('dom', () => { test.skip('hasClass', () => { // {{SQL CARBON EDIT}} skip test - const element = document.createElement('div'); + let element = document.createElement('div'); element.className = 'foobar boo far'; assert(element.classList.contains('foobar')); @@ -54,7 +55,7 @@ suite('dom', () => { }); test.skip('removeClass should consider hyphens', function () { // {{SQL CARBON EDIT}} skip test - const element = document.createElement('div'); + let element = document.createElement('div'); element.classList.add('foo-bar'); element.classList.add('bar'); @@ -72,9 +73,9 @@ suite('dom', () => { }); test('multibyteAwareBtoa', () => { - assert.ok(multibyteAwareBtoa('hello world').length > 0); - assert.ok(multibyteAwareBtoa('平仮名').length > 0); - assert.ok(multibyteAwareBtoa(new Array(100000).fill('vs').join('')).length > 0); // https://github.com/microsoft/vscode/issues/112013 + assert.ok(dom.multibyteAwareBtoa('hello world').length > 0); + assert.ok(dom.multibyteAwareBtoa('平仮名').length > 0); + assert.ok(dom.multibyteAwareBtoa(new Array(100000).fill('vs').join('')).length > 0); // https://github.com/microsoft/vscode/issues/112013 }); suite('$', () => { @@ -112,7 +113,7 @@ suite('dom', () => { test('should build nodes with children', () => { let div = $('div', undefined, $('span', { id: 'demospan' })); - const firstChild = div.firstChild as HTMLElement; + let firstChild = div.firstChild as HTMLElement; assert.strictEqual(firstChild.tagName, 'SPAN'); assert.strictEqual(firstChild.id, 'demospan'); @@ -122,158 +123,10 @@ suite('dom', () => { }); test('should build nodes with text children', () => { - const div = $('div', undefined, 'foobar'); - const firstChild = div.firstChild as HTMLElement; + let div = $('div', undefined, 'foobar'); + let firstChild = div.firstChild as HTMLElement; assert.strictEqual(firstChild.tagName, undefined); assert.strictEqual(firstChild.textContent, 'foobar'); }); }); - - suite('h', () => { - test('should build simple nodes', () => { - const div = h('div'); - assert(div.root instanceof HTMLElement); - assert.strictEqual(div.root.tagName, 'DIV'); - - const span = h('span'); - assert(span.root instanceof HTMLElement); - assert.strictEqual(span.root.tagName, 'SPAN'); - - const img = h('img'); - assert(img.root instanceof HTMLElement); - assert.strictEqual(img.root.tagName, 'IMG'); - }); - - test('should handle ids and classes', () => { - const divId = h('div#myid'); - assert.strictEqual(divId.root.tagName, 'DIV'); - assert.strictEqual(divId.root.id, 'myid'); - - const divClass = h('div.a'); - assert.strictEqual(divClass.root.tagName, 'DIV'); - assert.strictEqual(divClass.root.classList.length, 1); - assert(divClass.root.classList.contains('a')); - - const divClasses = h('div.a.b.c'); - assert.strictEqual(divClasses.root.tagName, 'DIV'); - assert.strictEqual(divClasses.root.classList.length, 3); - assert(divClasses.root.classList.contains('a')); - assert(divClasses.root.classList.contains('b')); - assert(divClasses.root.classList.contains('c')); - - const divAll = h('div#myid.a.b.c'); - assert.strictEqual(divAll.root.tagName, 'DIV'); - assert.strictEqual(divAll.root.id, 'myid'); - assert.strictEqual(divAll.root.classList.length, 3); - assert(divAll.root.classList.contains('a')); - assert(divAll.root.classList.contains('b')); - assert(divAll.root.classList.contains('c')); - - const spanId = h('span#myid'); - assert.strictEqual(spanId.root.tagName, 'SPAN'); - assert.strictEqual(spanId.root.id, 'myid'); - - const spanClass = h('span.a'); - assert.strictEqual(spanClass.root.tagName, 'SPAN'); - assert.strictEqual(spanClass.root.classList.length, 1); - assert(spanClass.root.classList.contains('a')); - - const spanClasses = h('span.a.b.c'); - assert.strictEqual(spanClasses.root.tagName, 'SPAN'); - assert.strictEqual(spanClasses.root.classList.length, 3); - assert(spanClasses.root.classList.contains('a')); - assert(spanClasses.root.classList.contains('b')); - assert(spanClasses.root.classList.contains('c')); - - const spanAll = h('span#myid.a.b.c'); - assert.strictEqual(spanAll.root.tagName, 'SPAN'); - assert.strictEqual(spanAll.root.id, 'myid'); - assert.strictEqual(spanAll.root.classList.length, 3); - assert(spanAll.root.classList.contains('a')); - assert(spanAll.root.classList.contains('b')); - assert(spanAll.root.classList.contains('c')); - }); - - test('should implicitly handle ids and classes', () => { - const divId = h('#myid'); - assert.strictEqual(divId.root.tagName, 'DIV'); - assert.strictEqual(divId.root.id, 'myid'); - - const divClass = h('.a'); - assert.strictEqual(divClass.root.tagName, 'DIV'); - assert.strictEqual(divClass.root.classList.length, 1); - assert(divClass.root.classList.contains('a')); - - const divClasses = h('.a.b.c'); - assert.strictEqual(divClasses.root.tagName, 'DIV'); - assert.strictEqual(divClasses.root.classList.length, 3); - assert(divClasses.root.classList.contains('a')); - assert(divClasses.root.classList.contains('b')); - assert(divClasses.root.classList.contains('c')); - - const divAll = h('#myid.a.b.c'); - assert.strictEqual(divAll.root.tagName, 'DIV'); - assert.strictEqual(divAll.root.id, 'myid'); - assert.strictEqual(divAll.root.classList.length, 3); - assert(divAll.root.classList.contains('a')); - assert(divAll.root.classList.contains('b')); - assert(divAll.root.classList.contains('c')); - }); - - test('should handle @ identifiers', () => { - const implicit = h('@el'); - assert.strictEqual(implicit.root, implicit.el); - assert.strictEqual(implicit.el.tagName, 'DIV'); - - const explicit = h('div@el'); - assert.strictEqual(explicit.root, explicit.el); - assert.strictEqual(explicit.el.tagName, 'DIV'); - - const implicitId = h('#myid@el'); - assert.strictEqual(implicitId.root, implicitId.el); - assert.strictEqual(implicitId.el.tagName, 'DIV'); - assert.strictEqual(implicitId.root.id, 'myid'); - - const explicitId = h('div#myid@el'); - assert.strictEqual(explicitId.root, explicitId.el); - assert.strictEqual(explicitId.el.tagName, 'DIV'); - assert.strictEqual(explicitId.root.id, 'myid'); - - const implicitClass = h('.a@el'); - assert.strictEqual(implicitClass.root, implicitClass.el); - assert.strictEqual(implicitClass.el.tagName, 'DIV'); - assert.strictEqual(implicitClass.root.classList.length, 1); - assert(implicitClass.root.classList.contains('a')); - - const explicitClass = h('div.a@el'); - assert.strictEqual(explicitClass.root, explicitClass.el); - assert.strictEqual(explicitClass.el.tagName, 'DIV'); - assert.strictEqual(explicitClass.root.classList.length, 1); - assert(explicitClass.root.classList.contains('a')); - }); - }); - - test('should recurse', () => { - const result = h('div.code-view', [ - h('div.title@title'), - h('div.container', [ - h('div.gutter@gutterDiv'), - h('span@editor'), - ]), - ]); - - assert.strictEqual(result.root.tagName, 'DIV'); - assert.strictEqual(result.root.className, 'code-view'); - assert.strictEqual(result.root.childElementCount, 2); - assert.strictEqual(result.root.firstElementChild, result.title); - assert.strictEqual(result.title.tagName, 'DIV'); - assert.strictEqual(result.title.className, 'title'); - assert.strictEqual(result.title.childElementCount, 0); - assert.strictEqual(result.gutterDiv.tagName, 'DIV'); - assert.strictEqual(result.gutterDiv.className, 'gutter'); - assert.strictEqual(result.gutterDiv.childElementCount, 0); - assert.strictEqual(result.editor.tagName, 'SPAN'); - assert.strictEqual(result.editor.className, ''); - assert.strictEqual(result.editor.childElementCount, 0); - }); }); diff --git a/src/vs/base/test/browser/formattedTextRenderer.test.ts b/src/vs/base/test/browser/formattedTextRenderer.test.ts index 3960a6aa25..a420133ed2 100644 --- a/src/vs/base/test/browser/formattedTextRenderer.test.ts +++ b/src/vs/base/test/browser/formattedTextRenderer.test.ts @@ -19,7 +19,7 @@ suite('FormattedTextRenderer', () => { }); test('render simple element', () => { - const result: HTMLElement = renderText('testing'); + let result: HTMLElement = renderText('testing'); assert.strictEqual(result.nodeType, document.ELEMENT_NODE); assert.strictEqual(result.textContent, 'testing'); @@ -27,7 +27,7 @@ suite('FormattedTextRenderer', () => { }); test('render element with class', () => { - const result: HTMLElement = renderText('testing', { + let result: HTMLElement = renderText('testing', { className: 'testClass' }); assert.strictEqual(result.nodeType, document.ELEMENT_NODE); @@ -55,18 +55,18 @@ suite('FormattedTextRenderer', () => { }); test('no formatting', () => { - const result: HTMLElement = renderFormattedText('this is just a string'); + let result: HTMLElement = renderFormattedText('this is just a string'); assert.strictEqual(result.innerHTML, 'this is just a string'); }); test('preserve newlines', () => { - const result: HTMLElement = renderFormattedText('line one\nline two'); + let result: HTMLElement = renderFormattedText('line one\nline two'); assert.strictEqual(result.innerHTML, 'line one
    line two'); }); test('action', () => { let callbackCalled = false; - const result: HTMLElement = renderFormattedText('[[action]]', { + let result: HTMLElement = renderFormattedText('[[action]]', { actionHandler: { callback(content) { assert.strictEqual(content, '0'); @@ -77,7 +77,7 @@ suite('FormattedTextRenderer', () => { }); assert.strictEqual(result.innerHTML, 'action'); - const event: MouseEvent = document.createEvent('MouseEvent'); + let event: MouseEvent = document.createEvent('MouseEvent'); event.initEvent('click', true, true); result.firstChild!.dispatchEvent(event); assert.strictEqual(callbackCalled, true); @@ -85,7 +85,7 @@ suite('FormattedTextRenderer', () => { test('fancy action', () => { let callbackCalled = false; - const result: HTMLElement = renderFormattedText('__**[[action]]**__', { + let result: HTMLElement = renderFormattedText('__**[[action]]**__', { actionHandler: { callback(content) { assert.strictEqual(content, '0'); @@ -96,7 +96,7 @@ suite('FormattedTextRenderer', () => { }); assert.strictEqual(result.innerHTML, 'action'); - const event: MouseEvent = document.createEvent('MouseEvent'); + let event: MouseEvent = document.createEvent('MouseEvent'); event.initEvent('click', true, true); result.firstChild!.firstChild!.firstChild!.dispatchEvent(event); assert.strictEqual(callbackCalled, true); @@ -104,7 +104,7 @@ suite('FormattedTextRenderer', () => { test('fancier action', () => { let callbackCalled = false; - const result: HTMLElement = renderFormattedText('``__**[[action]]**__``', { + let result: HTMLElement = renderFormattedText('``__**[[action]]**__``', { renderCodeSegments: true, actionHandler: { callback(content) { @@ -116,14 +116,14 @@ suite('FormattedTextRenderer', () => { }); assert.strictEqual(result.innerHTML, 'action'); - const event: MouseEvent = document.createEvent('MouseEvent'); + let event: MouseEvent = document.createEvent('MouseEvent'); event.initEvent('click', true, true); result.firstChild!.firstChild!.firstChild!.firstChild!.dispatchEvent(event); assert.strictEqual(callbackCalled, true); }); test('escaped formatting', () => { - const result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*'); + let result: HTMLElement = renderFormattedText('\\*\\*bold\\*\\*'); assert.strictEqual(result.children.length, 0); assert.strictEqual(result.innerHTML, '**bold**'); }); diff --git a/src/vs/base/test/browser/markdownRenderer.test.ts b/src/vs/base/test/browser/markdownRenderer.test.ts index 2cb9d63d33..11fd8c2e99 100644 --- a/src/vs/base/test/browser/markdownRenderer.test.ts +++ b/src/vs/base/test/browser/markdownRenderer.test.ts @@ -92,7 +92,7 @@ suite('MarkdownRenderer', () => { codeBlockRenderer: simpleCodeBlockRenderer }); result.dispose(); - setTimeout(resolve, 50); + setTimeout(resolve, 250); }); }); @@ -111,8 +111,8 @@ suite('MarkdownRenderer', () => { setTimeout(() => { result.dispose(); resolveCodeBlockRendering(document.createElement('code')); - setTimeout(resolve, 50); - }, 50); + setTimeout(resolve, 250); + }, 250); }); }); }); @@ -123,7 +123,7 @@ suite('MarkdownRenderer', () => { const mds = new MarkdownString(undefined, { supportThemeIcons: true }); mds.appendText('$(zap) $(not a theme icon) $(add)'); - const result: HTMLElement = renderMarkdown(mds).element; + let result: HTMLElement = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `

    $(zap) $(not a theme icon) $(add)

    `); }); @@ -131,7 +131,7 @@ suite('MarkdownRenderer', () => { const mds = new MarkdownString(undefined, { supportThemeIcons: true }); mds.appendMarkdown('$(zap) $(not a theme icon) $(add)'); - const result: HTMLElement = renderMarkdown(mds).element; + let result: HTMLElement = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `

    $(not a theme icon)

    `); }); @@ -139,7 +139,7 @@ suite('MarkdownRenderer', () => { const mds = new MarkdownString(undefined, { supportThemeIcons: true }); mds.appendMarkdown('\\$(zap) $(not a theme icon) $(add)'); - const result: HTMLElement = renderMarkdown(mds).element; + let result: HTMLElement = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `

    $(zap) $(not a theme icon)

    `); }); @@ -147,8 +147,8 @@ suite('MarkdownRenderer', () => { const mds = new MarkdownString(undefined, { supportThemeIcons: true }); mds.appendMarkdown(`[$(zap)-link](#link)`); - const result: HTMLElement = renderMarkdown(mds).element; - assert.strictEqual(result.innerHTML, `

    -link

    `); + let result: HTMLElement = renderMarkdown(mds).element; + assert.strictEqual(result.innerHTML, `

    -link

    `); }); test('render icon in table', () => { @@ -158,7 +158,7 @@ suite('MarkdownRenderer', () => { |--------|----------------------| | $(zap) | [$(zap)-link](#link) |`); - const result: HTMLElement = renderMarkdown(mds).element; + let result: HTMLElement = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, ` @@ -168,19 +168,11 @@ suite('MarkdownRenderer', () => { - +
    -link-link
    `); }); - - test('render icon in without href (#152170)', () => { - const mds = new MarkdownString(undefined, { supportThemeIcons: true, supportHtml: true }); - mds.appendMarkdown(`$(sync)`); - - const result: HTMLElement = renderMarkdown(mds).element; - assert.strictEqual(result.innerHTML, `

    `); - }); }); suite('ThemeIcons Support Off', () => { @@ -189,7 +181,7 @@ suite('MarkdownRenderer', () => { const mds = new MarkdownString(undefined, { supportThemeIcons: false }); mds.appendText('$(zap) $(not a theme icon) $(add)'); - const result: HTMLElement = renderMarkdown(mds).element; + let result: HTMLElement = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `

    $(zap) $(not a theme icon) $(add)

    `); }); @@ -197,7 +189,7 @@ suite('MarkdownRenderer', () => { const mds = new MarkdownString(undefined, { supportThemeIcons: false }); mds.appendMarkdown('\\$(zap) $(not a theme icon) $(add)'); - const result: HTMLElement = renderMarkdown(mds).element; + let result: HTMLElement = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `

    $(zap) $(not a theme icon) $(add)

    `); }); }); @@ -219,25 +211,6 @@ suite('MarkdownRenderer', () => { assert.ok(data.documentUri.toString().startsWith('file:///c%3A/')); }); - test('Should not render command links by default', () => { - const md = new MarkdownString(`[command1](command:doFoo) command2`, { - supportHtml: true - }); - - const result: HTMLElement = renderMarkdown(md).element; - assert.strictEqual(result.innerHTML, `

    command1 command2

    `); - }); - - test('Should render command links in trusted strings', () => { - const md = new MarkdownString(`[command1](command:doFoo) command2`, { - isTrusted: true, - supportHtml: true, - }); - - const result: HTMLElement = renderMarkdown(md).element; - assert.strictEqual(result.innerHTML, `

    command1 command2

    `); - }); - suite('PlaintextMarkdownRender', () => { test('test code, blockquote, heading, list, listitem, paragraph, table, tablerow, tablecell, strong, em, br, del, text are rendered plaintext', () => { diff --git a/src/vs/base/test/browser/ui/grid/grid.test.ts b/src/vs/base/test/browser/ui/grid/grid.test.ts index 3df348529e..9659118eef 100644 --- a/src/vs/base/test/browser/ui/grid/grid.test.ts +++ b/src/vs/base/test/browser/ui/grid/grid.test.ts @@ -785,26 +785,26 @@ suite('SerializableGrid', function () { }); test('sanitizeGridNodeDescriptor', () => { - const nodeDescriptor: GridNodeDescriptor = { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{}, {}] }] }; - const nodeDescriptorCopy = deepClone(nodeDescriptor); + const nodeDescriptor = { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{}, {}] }] }; + const nodeDescriptorCopy = deepClone(nodeDescriptor); sanitizeGridNodeDescriptor(nodeDescriptorCopy, true); assert.deepStrictEqual(nodeDescriptorCopy, { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{ size: 0.5 }, { size: 0.5 }] }] }); }); test('createSerializedGrid', () => { - const gridDescriptor = { orientation: Orientation.VERTICAL, groups: [{ size: 0.2, data: 'a' }, { size: 0.2, data: 'b' }, { size: 0.6, groups: [{ data: 'c' }, { data: 'd' }] }] }; + const gridDescriptor = { orientation: Orientation.VERTICAL, groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{}, {}] }] }; const serializedGrid = createSerializedGrid(gridDescriptor); assert.deepStrictEqual(serializedGrid, { root: { type: 'branch', size: undefined, data: [ - { type: 'leaf', size: 0.2, data: 'a' }, - { type: 'leaf', size: 0.2, data: 'b' }, + { type: 'leaf', size: 0.2, data: null }, + { type: 'leaf', size: 0.2, data: null }, { type: 'branch', size: 0.6, data: [ - { type: 'leaf', size: 0.5, data: 'c' }, - { type: 'leaf', size: 0.5, data: 'd' } + { type: 'leaf', size: 0.5, data: null }, + { type: 'leaf', size: 0.5, data: null } ] } ] @@ -842,30 +842,6 @@ suite('SerializableGrid', function () { grid.removeView(views[2]); }); - test('from', () => { - const createView = (): ISerializableView => ({ - element: document.createElement('div'), - layout: () => null, - minimumWidth: 0, - maximumWidth: Number.POSITIVE_INFINITY, - minimumHeight: 0, - maximumHeight: Number.POSITIVE_INFINITY, - onDidChange: Event.None, - toJSON: () => ({}) - }); - - const a = createView(); - const b = createView(); - const c = createView(); - const d = createView(); - - const gridDescriptor = { orientation: Orientation.VERTICAL, groups: [{ size: 0.2, data: a }, { size: 0.2, data: b }, { size: 0.6, groups: [{ data: c }, { data: d }] }] }; - const grid = SerializableGrid.from(gridDescriptor); - - assert.deepStrictEqual(nodesToArrays(grid.getViews()), [a, b, [c, d]]); - grid.dispose(); - }); - test('serialize should store visibility and previous size', function () { const view1 = new TestSerializableView('view1', 50, Number.MAX_VALUE, 50, Number.MAX_VALUE); const grid = new SerializableGrid(view1); diff --git a/src/vs/base/test/browser/ui/list/listWidget.test.ts b/src/vs/base/test/browser/ui/list/listWidget.test.ts deleted file mode 100644 index 42d587052d..0000000000 --- a/src/vs/base/test/browser/ui/list/listWidget.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list'; -import { List } from 'vs/base/browser/ui/list/listWidget'; -import { range } from 'vs/base/common/arrays'; -import { timeout } from 'vs/base/common/async'; - -suite('ListWidget', function () { - test('Page up and down', async function () { - const element = document.createElement('div'); - element.style.height = '200px'; - element.style.width = '200px'; - - const delegate: IListVirtualDelegate = { - getHeight() { return 20; }, - getTemplateId() { return 'template'; } - }; - - let templatesCount = 0; - - const renderer: IListRenderer = { - templateId: 'template', - renderTemplate() { templatesCount++; }, - renderElement() { }, - disposeTemplate() { templatesCount--; } - }; - - const listWidget = new List('test', element, delegate, [renderer]); - - listWidget.layout(200); - assert.strictEqual(templatesCount, 0, 'no templates have been allocated'); - listWidget.splice(0, 0, range(100)); - listWidget.focusFirst(); - - listWidget.focusNextPage(); - assert.strictEqual(listWidget.getFocus()[0], 9, 'first page down moves focus to element at bottom'); - - // scroll to next page is async - listWidget.focusNextPage(); - await timeout(0); - assert.strictEqual(listWidget.getFocus()[0], 19, 'page down to next page'); - - listWidget.focusPreviousPage(); - assert.strictEqual(listWidget.getFocus()[0], 10, 'first page up moves focus to element at top'); - - // scroll to previous page is async - listWidget.focusPreviousPage(); - await timeout(0); - assert.strictEqual(listWidget.getFocus()[0], 0, 'page down to previous page'); - - listWidget.dispose(); - }); - - test('Page up and down with item taller than viewport #149502', async function () { - const element = document.createElement('div'); - element.style.height = '200px'; - element.style.width = '200px'; - - const delegate: IListVirtualDelegate = { - getHeight() { return 200; }, - getTemplateId() { return 'template'; } - }; - - let templatesCount = 0; - - const renderer: IListRenderer = { - templateId: 'template', - renderTemplate() { templatesCount++; }, - renderElement() { }, - disposeTemplate() { templatesCount--; } - }; - - const listWidget = new List('test', element, delegate, [renderer]); - - listWidget.layout(200); - assert.strictEqual(templatesCount, 0, 'no templates have been allocated'); - listWidget.splice(0, 0, range(100)); - listWidget.focusFirst(); - assert.strictEqual(listWidget.getFocus()[0], 0, 'initial focus is first element'); - - // scroll to next page is async - listWidget.focusNextPage(); - await timeout(0); - assert.strictEqual(listWidget.getFocus()[0], 1, 'page down to next page'); - - // scroll to previous page is async - listWidget.focusPreviousPage(); - await timeout(0); - assert.strictEqual(listWidget.getFocus()[0], 0, 'page up to next page'); - - listWidget.dispose(); - }); -}); diff --git a/src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts b/src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts index d8d8b9ff60..d2f4dd6b1e 100644 --- a/src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts +++ b/src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts @@ -8,7 +8,7 @@ import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState'; suite('ScrollbarState', () => { test('inflates slider size', () => { - const actual = new ScrollbarState(0, 14, 0, 339, 42423, 32787); + let actual = new ScrollbarState(0, 14, 0, 339, 42423, 32787); assert.strictEqual(actual.getArrowSize(), 0); assert.strictEqual(actual.getScrollPosition(), 32787); @@ -34,7 +34,7 @@ suite('ScrollbarState', () => { }); test('inflates slider size with arrows', () => { - const actual = new ScrollbarState(12, 14, 0, 339, 42423, 32787); + let actual = new ScrollbarState(12, 14, 0, 339, 42423, 32787); assert.strictEqual(actual.getArrowSize(), 12); assert.strictEqual(actual.getScrollPosition(), 32787); diff --git a/src/vs/base/test/browser/ui/splitview/splitview.test.ts b/src/vs/base/test/browser/ui/splitview/splitview.test.ts index cf269fbfb5..508634b99b 100644 --- a/src/vs/base/test/browser/ui/splitview/splitview.test.ts +++ b/src/vs/base/test/browser/ui/splitview/splitview.test.ts @@ -271,7 +271,7 @@ suite('Splitview', () => { splitview.addView(view2, Sizing.Distribute); splitview.addView(view3, Sizing.Distribute); - const sashes = getSashes(splitview); + let sashes = getSashes(splitview); assert.strictEqual(sashes.length, 2, 'there are two sashes'); assert.strictEqual(sashes[0].state, SashState.Enabled, 'first sash is enabled'); assert.strictEqual(sashes[1].state, SashState.Enabled, 'second sash is enabled'); diff --git a/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts b/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts index b7b943b05a..82b054d3d1 100644 --- a/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts +++ b/src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts @@ -8,7 +8,6 @@ import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree'; import { IAsyncDataSource, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree'; import { timeout } from 'vs/base/common/async'; -import { Iterable } from 'vs/base/common/iterator'; interface Element { id: string; @@ -102,7 +101,7 @@ suite('AsyncDataTree', function () { await tree.setInput(model.root); assert.strictEqual(container.querySelectorAll('.monaco-list-row').length, 1); - const twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement; + let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement; assert(!twistie.classList.contains('collapsible')); assert(!twistie.classList.contains('collapsed')); @@ -436,60 +435,4 @@ suite('AsyncDataTree', function () { assert.deepStrictEqual(Array.from(container.querySelectorAll('.monaco-list-row')).map(e => e.textContent), ['a', 'b2']); }); - - test('issue #121567', async () => { - const container = document.createElement('div'); - - const calls: Element[] = []; - const dataSource = new class implements IAsyncDataSource { - hasChildren(element: Element): boolean { - return !!element.children && element.children.length > 0; - } - async getChildren(element: Element) { - calls.push(element); - return element.children ?? Iterable.empty(); - } - }; - - const model = new Model({ - id: 'root', - children: [{ - id: 'a', children: [{ - id: 'aa' - }] - }] - }); - const a = model.get('a'); - - const tree = new AsyncDataTree('test', container, new VirtualDelegate(), [new Renderer()], dataSource, { identityProvider: new IdentityProvider() }); - tree.layout(200); - - await tree.setInput(model.root); - assert.strictEqual(calls.length, 1, 'There should be a single getChildren call for the root'); - assert(tree.isCollapsible(a), 'a is collapsible'); - assert(tree.isCollapsed(a), 'a is collapsed'); - - await tree.updateChildren(a, false); - assert.strictEqual(calls.length, 1, 'There should be no changes to the calls list, since a was collapsed'); - assert(tree.isCollapsible(a), 'a is collapsible'); - assert(tree.isCollapsed(a), 'a is collapsed'); - - const children = a.children; - a.children = []; - await tree.updateChildren(a, false); - assert.strictEqual(calls.length, 1, 'There should still be no changes to the calls list, since a was collapsed'); - assert(!tree.isCollapsible(a), 'a is no longer collapsible'); - assert(tree.isCollapsed(a), 'a is collapsed'); - - a.children = children; - await tree.updateChildren(a, false); - assert.strictEqual(calls.length, 1, 'There should still be no changes to the calls list, since a was collapsed'); - assert(tree.isCollapsible(a), 'a is collapsible again'); - assert(tree.isCollapsed(a), 'a is collapsed'); - - await tree.expand(a); - assert.strictEqual(calls.length, 2, 'Finally, there should be a getChildren call for a'); - assert(tree.isCollapsible(a), 'a is still collapsible'); - assert(!tree.isCollapsed(a), 'a is expanded'); - }); }); diff --git a/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts b/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts index e2f6b6b9d0..656a924a9c 100644 --- a/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts +++ b/src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts @@ -400,7 +400,7 @@ suite('IndexTreeModel', () => { const deleteCount = Math.ceil(Math.random() * (list.length - spliceIndex)); const insertCount = Math.floor(Math.random() * maxInserts + 1); - const inserts: ITreeElement[] = []; + let inserts: ITreeElement[] = []; for (let i = 0; i < insertCount; i++) { const element = elementCounter++; inserts.push({ element, children: [] }); diff --git a/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts b/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts index 951d781f1e..556f5f8764 100644 --- a/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts +++ b/src/vs/base/test/browser/ui/tree/objectTreeModel.test.ts @@ -172,7 +172,7 @@ suite('ObjectTreeModel', function () { }); test('sorter', () => { - const compare: (a: string, b: string) => number = (a, b) => a < b ? -1 : 1; + let compare: (a: string, b: string) => number = (a, b) => a < b ? -1 : 1; const list: ITreeNode[] = []; const model = new ObjectTreeModel('test', toList(list), { sorter: { compare(a, b) { return compare(a, b); } } }); diff --git a/src/vs/base/test/common/arrays.test.ts b/src/vs/base/test/common/arrays.test.ts index 8d442e813f..a7f395ccd5 100644 --- a/src/vs/base/test/common/arrays.test.ts +++ b/src/vs/base/test/common/arrays.test.ts @@ -6,19 +6,6 @@ import * as assert from 'assert'; import * as arrays from 'vs/base/common/arrays'; suite('Arrays', () => { - - test('removeFastWithoutKeepingOrder', () => { - const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; - arrays.removeFastWithoutKeepingOrder(array, 1); - assert.deepStrictEqual(array, [1, 69, 5, 7, 55, 59, 60, 61, 64]); - - arrays.removeFastWithoutKeepingOrder(array, 0); - assert.deepStrictEqual(array, [64, 69, 5, 7, 55, 59, 60, 61]); - - arrays.removeFastWithoutKeepingOrder(array, 7); - assert.deepStrictEqual(array, [64, 69, 5, 7, 55, 59, 60]); - }); - test('findFirst', () => { const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; @@ -48,10 +35,10 @@ suite('Arrays', () => { function assertMedian(expexted: number, data: number[], nth: number = Math.floor(data.length / 2)) { const compare = (a: number, b: number) => a - b; - const actual1 = arrays.quickSelect(nth, data, compare); + let actual1 = arrays.quickSelect(nth, data, compare); assert.strictEqual(actual1, expexted); - const actual2 = data.slice().sort(compare)[nth]; + let actual2 = data.slice().sort(compare)[nth]; assert.strictEqual(actual2, expexted); } @@ -153,24 +140,7 @@ suite('Arrays', () => { assert.strictEqual(arrays.binarySearch(array, 0, compare), ~0); assert.strictEqual(arrays.binarySearch(array, 6, compare), ~3); assert.strictEqual(arrays.binarySearch(array, 70, compare), ~10); - }); - test('binarySearch2', () => { - function compareTo(key: number) { - return (index: number) => { - return array[index] - key; - }; - } - const array = [1, 4, 5, 7, 55, 59, 60, 61, 64, 69]; - - assert.strictEqual(arrays.binarySearch2(10, compareTo(1)), 0); - assert.strictEqual(arrays.binarySearch2(10, compareTo(5)), 2); - - // insertion point - assert.strictEqual(arrays.binarySearch2(10, compareTo(0)), ~0); - assert.strictEqual(arrays.binarySearch2(10, compareTo(6)), ~3); - assert.strictEqual(arrays.binarySearch2(10, compareTo(70)), ~10); - assert.strictEqual(arrays.binarySearch2(2, compareTo(5)), ~2); }); test('distinct', () => { @@ -244,7 +214,7 @@ suite('Arrays', () => { } test('coalesce', () => { - const a: Array = arrays.coalesce([null, 1, null, 2, 3]); + let a: Array = arrays.coalesce([null, 1, null, 2, 3]); assert.strictEqual(a.length, 3); assert.strictEqual(a[0], 1); assert.strictEqual(a[1], 2); @@ -294,7 +264,7 @@ suite('Arrays', () => { assert.strictEqual(a[1], 2); assert.strictEqual(a[2], 3); - const b: number[] = []; + let b: number[] = []; b[10] = 1; b[20] = 2; b[30] = 3; @@ -304,7 +274,7 @@ suite('Arrays', () => { assert.strictEqual(b[1], 2); assert.strictEqual(b[2], 3); - const sparse: number[] = []; + let sparse: number[] = []; sparse[0] = 1; sparse[1] = 1; sparse[17] = 1; diff --git a/src/vs/base/test/common/async.test.ts b/src/vs/base/test/common/async.test.ts index ab22911bba..45ce194da5 100644 --- a/src/vs/base/test/common/async.test.ts +++ b/src/vs/base/test/common/async.test.ts @@ -15,11 +15,11 @@ suite('Async', () => { suite('cancelablePromise', function () { test('set token, don\'t wait for inner promise', function () { let canceled = 0; - const promise = async.createCancelablePromise(token => { + let promise = async.createCancelablePromise(token => { token.onCancellationRequested(_ => { canceled += 1; }); return new Promise(resolve => { /*never*/ }); }); - const result = promise.then(_ => assert.ok(false), err => { + let result = promise.then(_ => assert.ok(false), err => { assert.strictEqual(canceled, 1); assert.ok(isCancellationError(err)); }); @@ -30,11 +30,11 @@ suite('Async', () => { test('cancel despite inner promise being resolved', function () { let canceled = 0; - const promise = async.createCancelablePromise(token => { + let promise = async.createCancelablePromise(token => { token.onCancellationRequested(_ => { canceled += 1; }); return Promise.resolve(1234); }); - const result = promise.then(_ => assert.ok(false), err => { + let result = promise.then(_ => assert.ok(false), err => { assert.strictEqual(canceled, 1); assert.ok(isCancellationError(err)); }); @@ -88,11 +88,11 @@ suite('Async', () => { }); test('get inner result', async function () { - const promise = async.createCancelablePromise(token => { + let promise = async.createCancelablePromise(token => { return async.timeout(12).then(_ => 1234); }); - const result = await promise; + let result = await promise; assert.strictEqual(result, 1234); }); }); @@ -100,11 +100,11 @@ suite('Async', () => { suite('Throttler', function () { test('non async', function () { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const throttler = new async.Throttler(); + let throttler = new async.Throttler(); return Promise.all([ throttler.queue(factory).then((result) => { assert.strictEqual(result, 1); }), @@ -117,9 +117,9 @@ suite('Async', () => { test('async', () => { let count = 0; - const factory = () => async.timeout(0).then(() => ++count); + let factory = () => async.timeout(0).then(() => ++count); - const throttler = new async.Throttler(); + let throttler = new async.Throttler(); return Promise.all([ throttler.queue(factory).then((result) => { assert.strictEqual(result, 1); }), @@ -139,13 +139,13 @@ suite('Async', () => { }); test('last factory should be the one getting called', function () { - const factoryFactory = (n: number) => () => { + let factoryFactory = (n: number) => () => { return async.timeout(0).then(() => n); }; - const throttler = new async.Throttler(); + let throttler = new async.Throttler(); - const promises: Promise[] = []; + let promises: Promise[] = []; promises.push(throttler.queue(factoryFactory(1)).then((n) => { assert.strictEqual(n, 1); })); promises.push(throttler.queue(factoryFactory(2)).then((n) => { assert.strictEqual(n, 3); })); @@ -158,12 +158,12 @@ suite('Async', () => { suite('Delayer', function () { test('simple', () => { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const delayer = new async.Delayer(0); - const promises: Promise[] = []; + let delayer = new async.Delayer(0); + let promises: Promise[] = []; assert(!delayer.isTriggered()); @@ -183,12 +183,12 @@ suite('Async', () => { test('microtask delay simple', () => { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const delayer = new async.Delayer(async.MicrotaskDelay); - const promises: Promise[] = []; + let delayer = new async.Delayer(async.MicrotaskDelay); + let promises: Promise[] = []; assert(!delayer.isTriggered()); @@ -223,11 +223,11 @@ suite('Async', () => { test('simple cancel', function () { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const delayer = new async.Delayer(0); + let delayer = new async.Delayer(0); assert(!delayer.isTriggered()); @@ -246,11 +246,11 @@ suite('Async', () => { test('simple cancel microtask', function () { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const delayer = new async.Delayer(async.MicrotaskDelay); + let delayer = new async.Delayer(async.MicrotaskDelay); assert(!delayer.isTriggered()); @@ -269,12 +269,12 @@ suite('Async', () => { test('cancel should cancel all calls to trigger', function () { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const delayer = new async.Delayer(0); - const promises: Promise[] = []; + let delayer = new async.Delayer(0); + let promises: Promise[] = []; assert(!delayer.isTriggered()); @@ -296,11 +296,11 @@ suite('Async', () => { test('trigger, cancel, then trigger again', function () { let count = 0; - const factory = () => { + let factory = () => { return Promise.resolve(++count); }; - const delayer = new async.Delayer(0); + let delayer = new async.Delayer(0); let promises: Promise[] = []; assert(!delayer.isTriggered()); @@ -346,12 +346,12 @@ suite('Async', () => { }); test('last task should be the one getting called', function () { - const factoryFactory = (n: number) => () => { + let factoryFactory = (n: number) => () => { return Promise.resolve(n); }; - const delayer = new async.Delayer(0); - const promises: Promise[] = []; + let delayer = new async.Delayer(0); + let promises: Promise[] = []; assert(!delayer.isTriggered()); @@ -371,7 +371,7 @@ suite('Async', () => { suite('sequence', () => { test('simple', () => { - const factoryFactory = (n: number) => () => { + let factoryFactory = (n: number) => () => { return Promise.resolve(n); }; @@ -394,7 +394,7 @@ suite('Async', () => { suite('Limiter', () => { test('sync', function () { - const factoryFactory = (n: number) => () => { + let factoryFactory = (n: number) => () => { return Promise.resolve(n); }; @@ -418,7 +418,7 @@ suite('Async', () => { }); test('async', function () { - const factoryFactory = (n: number) => () => async.timeout(0).then(() => n); + let factoryFactory = (n: number) => () => async.timeout(0).then(() => n); let limiter = new async.Limiter(1); let promises: Promise[] = []; @@ -440,15 +440,15 @@ suite('Async', () => { test('assert degree of paralellism', function () { let activePromises = 0; - const factoryFactory = (n: number) => () => { + let factoryFactory = (n: number) => () => { activePromises++; assert(activePromises < 6); return async.timeout(0).then(() => { activePromises--; return n; }); }; - const limiter = new async.Limiter(5); + let limiter = new async.Limiter(5); - const promises: Promise[] = []; + let promises: Promise[] = []; [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(n => promises.push(limiter.queue(factoryFactory(n)))); return Promise.all(promises).then((res) => { @@ -460,13 +460,13 @@ suite('Async', () => { suite('Queue', () => { test('simple', function () { - const queue = new async.Queue(); + let queue = new async.Queue(); let syncPromise = false; - const f1 = () => Promise.resolve(true).then(() => syncPromise = true); + let f1 = () => Promise.resolve(true).then(() => syncPromise = true); let asyncPromise = false; - const f2 = () => async.timeout(10).then(() => asyncPromise = true); + let f2 = () => async.timeout(10).then(() => asyncPromise = true); assert.strictEqual(queue.size, 0); @@ -483,15 +483,15 @@ suite('Async', () => { }); test('order is kept', function () { - const queue = new async.Queue(); + let queue = new async.Queue(); - const res: number[] = []; + let res: number[] = []; - const f1 = () => Promise.resolve(true).then(() => res.push(1)); - const f2 = () => async.timeout(10).then(() => res.push(2)); - const f3 = () => Promise.resolve(true).then(() => res.push(3)); - const f4 = () => async.timeout(20).then(() => res.push(4)); - const f5 = () => async.timeout(0).then(() => res.push(5)); + let f1 = () => Promise.resolve(true).then(() => res.push(1)); + let f2 = () => async.timeout(10).then(() => res.push(2)); + let f3 = () => Promise.resolve(true).then(() => res.push(3)); + let f4 = () => async.timeout(20).then(() => res.push(4)); + let f5 = () => async.timeout(0).then(() => res.push(5)); queue.queue(f1); queue.queue(f2); @@ -507,16 +507,16 @@ suite('Async', () => { }); test('errors bubble individually but not cause stop', function () { - const queue = new async.Queue(); + let queue = new async.Queue(); - const res: number[] = []; + let res: number[] = []; let error = false; - const f1 = () => Promise.resolve(true).then(() => res.push(1)); - const f2 = () => async.timeout(10).then(() => res.push(2)); - const f3 = () => Promise.resolve(true).then(() => Promise.reject(new Error('error'))); - const f4 = () => async.timeout(20).then(() => res.push(4)); - const f5 = () => async.timeout(0).then(() => res.push(5)); + let f1 = () => Promise.resolve(true).then(() => res.push(1)); + let f2 = () => async.timeout(10).then(() => res.push(2)); + let f3 = () => Promise.resolve(true).then(() => Promise.reject(new Error('error'))); + let f4 = () => async.timeout(20).then(() => res.push(4)); + let f5 = () => async.timeout(0).then(() => res.push(5)); queue.queue(f1); queue.queue(f2); @@ -532,15 +532,15 @@ suite('Async', () => { }); test('order is kept (chained)', function () { - const queue = new async.Queue(); + let queue = new async.Queue(); - const res: number[] = []; + let res: number[] = []; - const f1 = () => Promise.resolve(true).then(() => res.push(1)); - const f2 = () => async.timeout(10).then(() => res.push(2)); - const f3 = () => Promise.resolve(true).then(() => res.push(3)); - const f4 = () => async.timeout(20).then(() => res.push(4)); - const f5 = () => async.timeout(0).then(() => res.push(5)); + let f1 = () => Promise.resolve(true).then(() => res.push(1)); + let f2 = () => async.timeout(10).then(() => res.push(2)); + let f3 = () => Promise.resolve(true).then(() => res.push(3)); + let f4 = () => async.timeout(20).then(() => res.push(4)); + let f5 = () => async.timeout(0).then(() => res.push(5)); return queue.queue(f1).then(() => { return queue.queue(f2).then(() => { @@ -560,16 +560,16 @@ suite('Async', () => { }); test('events', async function () { - const queue = new async.Queue(); + let queue = new async.Queue(); let drained = false; const onDrained = Event.toPromise(queue.onDrained).then(() => drained = true); - const res: number[] = []; + let res: number[] = []; - const f1 = () => async.timeout(10).then(() => res.push(2)); - const f2 = () => async.timeout(20).then(() => res.push(4)); - const f3 = () => async.timeout(0).then(() => res.push(5)); + let f1 = () => async.timeout(10).then(() => res.push(2)); + let f2 = () => async.timeout(20).then(() => res.push(4)); + let f3 = () => async.timeout(0).then(() => res.push(5)); const q1 = queue.queue(f1); const q2 = queue.queue(f2); @@ -589,7 +589,7 @@ suite('Async', () => { suite('ResourceQueue', () => { test('simple', async function () { - const queue = new async.ResourceQueue(); + let queue = new async.ResourceQueue(); await queue.whenDrained(); // returns immediately since empty @@ -651,7 +651,7 @@ suite('Async', () => { }); test('error case', async () => { - const expectedError = new Error('fail'); + let expectedError = new Error('fail'); try { await async.retry(() => { return Promise.reject(expectedError); @@ -727,13 +727,13 @@ suite('Async', () => { // next finishes after async.timeout let firstDone = false; - const firstRes = sequentializer.setNext(() => async.timeout(2).then(() => { firstDone = true; return; })); + let firstRes = sequentializer.setNext(() => async.timeout(2).then(() => { firstDone = true; return; })); let secondDone = false; - const secondRes = sequentializer.setNext(() => async.timeout(3).then(() => { secondDone = true; return; })); + let secondRes = sequentializer.setNext(() => async.timeout(3).then(() => { secondDone = true; return; })); let thirdDone = false; - const thirdRes = sequentializer.setNext(() => async.timeout(4).then(() => { thirdDone = true; return; })); + let thirdRes = sequentializer.setNext(() => async.timeout(4).then(() => { thirdDone = true; return; })); await Promise.all([firstRes, secondRes, thirdRes]); assert.ok(pendingDone); @@ -1177,7 +1177,7 @@ suite('Async', () => { }); test('do not accept too much work', async () => { - const handled: number[] = []; + let handled: number[] = []; const handler = (units: readonly number[]) => handled.push(...units); const worker = new async.ThrottledWorker({ @@ -1203,7 +1203,7 @@ suite('Async', () => { }); test('do not accept too much work (account for max chunk size', async () => { - const handled: number[] = []; + let handled: number[] = []; const handler = (units: readonly number[]) => handled.push(...units); const worker = new async.ThrottledWorker({ @@ -1222,7 +1222,7 @@ suite('Async', () => { }); test('disposed', async () => { - const handled: number[] = []; + let handled: number[] = []; const handler = (units: readonly number[]) => handled.push(...units); const worker = new async.ThrottledWorker({ diff --git a/src/vs/base/test/common/buffer.test.ts b/src/vs/base/test/common/buffer.test.ts index 08cb744384..ef7c1254d3 100644 --- a/src/vs/base/test/common/buffer.test.ts +++ b/src/vs/base/test/common/buffer.test.ts @@ -40,7 +40,7 @@ suite('Buffer', () => { test('bufferWriteableStream - basics (no error)', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -50,7 +50,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -70,7 +70,7 @@ suite('Buffer', () => { test('bufferWriteableStream - basics (error)', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -80,7 +80,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -105,7 +105,7 @@ suite('Buffer', () => { await timeout(0); stream.end(VSBuffer.fromString('World')); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -115,7 +115,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -134,12 +134,12 @@ suite('Buffer', () => { await timeout(0); stream.error(new Error()); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -170,12 +170,12 @@ suite('Buffer', () => { ended = true; }); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -189,7 +189,7 @@ suite('Buffer', () => { test('bufferWriteableStream - nothing happens after end()', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -233,7 +233,7 @@ suite('Buffer', () => { test('bufferWriteableStream - pause/resume (simple)', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -243,7 +243,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -270,7 +270,7 @@ suite('Buffer', () => { test('bufferWriteableStream - pause/resume (pause after first write)', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -280,7 +280,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -310,7 +310,7 @@ suite('Buffer', () => { test('bufferWriteableStream - pause/resume (error)', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -320,7 +320,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); @@ -348,7 +348,7 @@ suite('Buffer', () => { test('bufferWriteableStream - destroy', async () => { const stream = newWriteableBufferStream(); - const chunks: VSBuffer[] = []; + let chunks: VSBuffer[] = []; stream.on('data', data => { chunks.push(data); }); @@ -358,7 +358,7 @@ suite('Buffer', () => { ended = true; }); - const errors: Error[] = []; + let errors: Error[] = []; stream.on('error', error => { errors.push(error); }); diff --git a/src/vs/base/test/common/cancellation.test.ts b/src/vs/base/test/common/cancellation.test.ts index 8d516aa2c9..ec9fac91fd 100644 --- a/src/vs/base/test/common/cancellation.test.ts +++ b/src/vs/base/test/common/cancellation.test.ts @@ -27,7 +27,7 @@ suite('CancellationToken', function () { test('cancel happens only once', function () { - const source = new CancellationTokenSource(); + let source = new CancellationTokenSource(); assert.strictEqual(source.token.isCancellationRequested, false); let cancelCount = 0; @@ -47,7 +47,7 @@ suite('CancellationToken', function () { let count = 0; - const source = new CancellationTokenSource(); + let source = new CancellationTokenSource(); source.token.onCancellationRequested(function () { count += 1; }); @@ -84,7 +84,7 @@ suite('CancellationToken', function () { let count = 0; - const source = new CancellationTokenSource(); + let source = new CancellationTokenSource(); source.token.onCancellationRequested(function () { count += 1; }); @@ -98,7 +98,7 @@ suite('CancellationToken', function () { let count = 0; - const source = new CancellationTokenSource(); + let source = new CancellationTokenSource(); source.token.onCancellationRequested(function () { count += 1; }); @@ -110,8 +110,8 @@ suite('CancellationToken', function () { test('parent cancels child', function () { - const parent = new CancellationTokenSource(); - const child = new CancellationTokenSource(parent.token); + let parent = new CancellationTokenSource(); + let child = new CancellationTokenSource(parent.token); let count = 0; child.token.onCancellationRequested(() => count += 1); diff --git a/src/vs/base/test/common/collections.test.ts b/src/vs/base/test/common/collections.test.ts index 653eab91b4..b194909720 100644 --- a/src/vs/base/test/common/collections.test.ts +++ b/src/vs/base/test/common/collections.test.ts @@ -8,17 +8,41 @@ import * as collections from 'vs/base/common/collections'; suite('Collections', () => { + test('forEach', () => { + collections.forEach({}, () => assert(false)); + collections.forEach(Object.create(null), () => assert(false)); + + let count = 0; + collections.forEach({ toString: 123 }, () => count++); + assert.strictEqual(count, 1); + + count = 0; + let dict = Object.create(null); + dict['toString'] = 123; + collections.forEach(dict, () => count++); + assert.strictEqual(count, 1); + + collections.forEach(dict, () => false); + + collections.forEach(dict, (x, remove) => remove()); + assert.strictEqual(dict['toString'], undefined); + + // don't iterate over properties that are not on the object itself + let test = Object.create({ 'derived': true }); + collections.forEach(test, () => assert(false)); + }); + test('groupBy', () => { const group1 = 'a', group2 = 'b'; const value1 = 1, value2 = 2, value3 = 3; - const source = [ + let source = [ { key: group1, value: value1 }, { key: group1, value: value2 }, { key: group2, value: value3 }, ]; - const grouped = collections.groupBy(source, x => x.key); + let grouped = collections.groupBy(source, x => x.key); // Group 1 assert.strictEqual(grouped[group1].length, 2); diff --git a/src/vs/base/test/common/color.test.ts b/src/vs/base/test/common/color.test.ts index 9b885236ef..429ab7c804 100644 --- a/src/vs/base/test/common/color.test.ts +++ b/src/vs/base/test/common/color.test.ts @@ -9,7 +9,7 @@ import { Color, HSLA, HSVA, RGBA } from 'vs/base/common/color'; suite('Color', () => { test('isLighterColor', () => { - const color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); + let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); assert.ok(color1.isLighterThan(color2)); @@ -18,7 +18,7 @@ suite('Color', () => { }); test('getLighterColor', () => { - const color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); + let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); assert.deepStrictEqual(color1.hsla, Color.getLighterColor(color1, color2).hsla); assert.deepStrictEqual(new HSLA(0, 0, 0.916, 1), Color.getLighterColor(color2, color1).hsla); @@ -29,14 +29,14 @@ suite('Color', () => { }); test('isDarkerColor', () => { - const color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); + let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); assert.ok(color2.isDarkerThan(color1)); }); test('getDarkerColor', () => { - const color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); + let color1 = new Color(new HSLA(60, 1, 0.5, 1)), color2 = new Color(new HSLA(0, 0, 0.753, 1)); assert.deepStrictEqual(color2.hsla, Color.getDarkerColor(color2, color1).hsla); assert.deepStrictEqual(new HSLA(60, 1, 0.392, 1), Color.getDarkerColor(color1, color2).hsla); diff --git a/src/vs/base/test/common/diff/diff.test.ts b/src/vs/base/test/common/diff/diff.test.ts index a6eec89f52..661d96b984 100644 --- a/src/vs/base/test/common/diff/diff.test.ts +++ b/src/vs/base/test/common/diff/diff.test.ts @@ -25,8 +25,8 @@ function maskBasedSubstring(str: string, mask: boolean[]): string { } function assertAnswer(originalStr: string, modifiedStr: string, changes: IDiffChange[], answerStr: string, onlyLength: boolean = false): void { - const originalMask = createArray(originalStr.length, true); - const modifiedMask = createArray(modifiedStr.length, true); + let originalMask = createArray(originalStr.length, true); + let modifiedMask = createArray(modifiedStr.length, true); let i, j, change; for (i = 0; i < changes.length; i++) { @@ -45,8 +45,8 @@ function assertAnswer(originalStr: string, modifiedStr: string, changes: IDiffCh } } - const originalAnswer = maskBasedSubstring(originalStr, originalMask); - const modifiedAnswer = maskBasedSubstring(modifiedStr, modifiedMask); + let originalAnswer = maskBasedSubstring(originalStr, originalMask); + let modifiedAnswer = maskBasedSubstring(modifiedStr, modifiedMask); if (onlyLength) { assert.strictEqual(originalAnswer.length, answerStr.length); @@ -58,8 +58,8 @@ function assertAnswer(originalStr: string, modifiedStr: string, changes: IDiffCh } function lcsInnerTest(originalStr: string, modifiedStr: string, answerStr: string, onlyLength: boolean = false): void { - const diff = new LcsDiff(new StringDiffSequence(originalStr), new StringDiffSequence(modifiedStr)); - const changes = diff.ComputeDiff(false).changes; + let diff = new LcsDiff(new StringDiffSequence(originalStr), new StringDiffSequence(modifiedStr)); + let changes = diff.ComputeDiff(false).changes; assertAnswer(originalStr, modifiedStr, changes, answerStr, onlyLength); } @@ -98,8 +98,8 @@ suite('Diff', () => { suite('Diff - Ported from VS', () => { test('using continue processing predicate to quit early', function () { - const left = 'abcdef'; - const right = 'abxxcyyydzzzzezzzzzzzzzzzzzzzzzzzzf'; + let left = 'abcdef'; + let right = 'abxxcyyydzzzzezzzzzzzzzzzzzzzzzzzzf'; // We use a long non-matching portion at the end of the right-side string, so the backwards tracking logic // doesn't get there first. @@ -155,7 +155,7 @@ suite('Diff - Ported from VS', () => { diff = new LcsDiff(new StringDiffSequence(left), new StringDiffSequence(right), function (leftIndex, longestMatchSoFar) { assert(longestMatchSoFar <= 2); // We never see a match of length > 2 - const hitYet = hitSecondMatch; + let hitYet = hitSecondMatch; hitSecondMatch = longestMatchSoFar > 1; // Continue processing as long as there hasn't been a match made. return !hitYet; diff --git a/src/vs/base/test/common/event.test.ts b/src/vs/base/test/common/event.test.ts index a979625dee..6a78700532 100644 --- a/src/vs/base/test/common/event.test.ts +++ b/src/vs/base/test/common/event.test.ts @@ -8,8 +8,7 @@ import { CancellationToken } from 'vs/base/common/cancellation'; import { errorHandler, setUnexpectedErrorHandler } from 'vs/base/common/errors'; import { AsyncEmitter, DebounceEmitter, Emitter, Event, EventBufferer, EventMultiplexer, IWaitUntil, MicrotaskEmitter, PauseableEmitter, Relay } from 'vs/base/common/event'; import { DisposableStore, IDisposable, isDisposable, setDisposableTracker, toDisposable } from 'vs/base/common/lifecycle'; -import { observableValue, transaction } from 'vs/base/common/observable'; -import { DisposableTracker, ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { DisposableTracker } from 'vs/base/test/common/utils'; namespace Samples { @@ -50,7 +49,7 @@ suite('Event utils dispose', function () { const actualInstances = tracker.getTrackedDisposables(); assert.strictEqual(actualInstances.length, expected.length); - for (const item of actualInstances) { + for (let item of actualInstances) { assert.ok(instances.has(item)); } @@ -77,7 +76,7 @@ suite('Event utils dispose', function () { assertDisposablesCount(1); // snaphot only listen when `evens` is being listened on let all = 0; - const leaked = evens(n => all += n); + let leaked = evens(n => all += n); assert.ok(isDisposable(leaked)); assertDisposablesCount(3); @@ -93,7 +92,7 @@ suite('Event utils dispose', function () { assertDisposablesCount(1); // debounce only listens when `debounce` is being listened on let all = 0; - const leaked = debounced(n => all += n); + let leaked = debounced(n => all += n); assert.ok(isDisposable(leaked)); assertDisposablesCount(3); @@ -112,9 +111,9 @@ suite('Event', function () { test('Emitter plain', function () { - const doc = new Samples.Document3(); + let doc = new Samples.Document3(); - const subscription = doc.onDidChange(counter.onEvent, counter); + let subscription = doc.onDidChange(counter.onEvent, counter); doc.setText('far'); doc.setText('boo'); @@ -128,9 +127,9 @@ suite('Event', function () { test('Emitter, bucket', function () { - const bucket: IDisposable[] = []; - const doc = new Samples.Document3(); - const subscription = doc.onDidChange(counter.onEvent, counter, bucket); + let bucket: IDisposable[] = []; + let doc = new Samples.Document3(); + let subscription = doc.onDidChange(counter.onEvent, counter, bucket); doc.setText('far'); doc.setText('boo'); @@ -150,9 +149,9 @@ suite('Event', function () { test('Emitter, store', function () { - const bucket = new DisposableStore(); - const doc = new Samples.Document3(); - const subscription = doc.onDidChange(counter.onEvent, counter, bucket); + let bucket = new DisposableStore(); + let doc = new Samples.Document3(); + let subscription = doc.onDidChange(counter.onEvent, counter, bucket); doc.setText('far'); doc.setText('boo'); @@ -172,7 +171,7 @@ suite('Event', function () { let firstCount = 0; let lastCount = 0; - const a = new Emitter({ + let a = new Emitter({ onFirstListenerAdd() { firstCount += 1; }, onLastListenerRemove() { lastCount += 1; } }); @@ -198,7 +197,7 @@ suite('Event', function () { setUnexpectedErrorHandler(() => null); try { - const a = new Emitter(); + let a = new Emitter(); let hit = false; a.event(function () { // eslint-disable-next-line no-throw-literal @@ -222,9 +221,9 @@ suite('Event', function () { } const context = {}; - const emitter = new Emitter(); - const reg1 = emitter.event(listener, context); - const reg2 = emitter.event(listener, context); + let emitter = new Emitter(); + let reg1 = emitter.event(listener, context); + let reg2 = emitter.event(listener, context); emitter.fire(undefined); assert.strictEqual(counter, 2); @@ -239,9 +238,9 @@ suite('Event', function () { }); test('Debounce Event', function (done: () => void) { - const doc = new Samples.Document3(); + let doc = new Samples.Document3(); - const onDocDidChange = Event.debounce(doc.onDidChange, (prev: string[] | undefined, cur) => { + let onDocDidChange = Event.debounce(doc.onDidChange, (prev: string[] | undefined, cur) => { if (!prev) { prev = [cur]; } else if (prev.indexOf(cur) < 0) { @@ -271,7 +270,7 @@ suite('Event', function () { test('Debounce Event - leading', async function () { const emitter = new Emitter(); - const debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true); + let debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true); let calls = 0; debounced(() => { @@ -287,7 +286,7 @@ suite('Event', function () { test('Debounce Event - leading', async function () { const emitter = new Emitter(); - const debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true); + let debounced = Event.debounce(emitter.event, (l, e) => e, 0, /*leading=*/true); let calls = 0; debounced(() => { @@ -304,9 +303,9 @@ suite('Event', function () { test('Debounce Event - leading reset', async function () { const emitter = new Emitter(); - const debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0, /*leading=*/true); + let debounced = Event.debounce(emitter.event, (l, e) => l ? l + 1 : 1, 0, /*leading=*/true); - const calls: number[] = []; + let calls: number[] = []; debounced((e) => calls.push(e)); emitter.fire(1); @@ -397,7 +396,7 @@ suite('AsyncEmitter', function () { bar: number; } - const emitter = new AsyncEmitter(); + let emitter = new AsyncEmitter(); emitter.event(e => { assert.strictEqual(e.foo, true); @@ -416,7 +415,7 @@ suite('AsyncEmitter', function () { } let globalState = 0; - const emitter = new AsyncEmitter(); + let emitter = new AsyncEmitter(); emitter.event(e => { e.waitUntil(timeout(10).then(_ => { @@ -440,9 +439,9 @@ suite('AsyncEmitter', function () { interface E extends IWaitUntil { foo: number; } - const events: number[] = []; + let events: number[] = []; let done = false; - const emitter = new AsyncEmitter(); + let emitter = new AsyncEmitter(); // e1 emitter.event(e => { @@ -474,7 +473,7 @@ suite('AsyncEmitter', function () { } let globalState = 0; - const emitter = new AsyncEmitter(); + let emitter = new AsyncEmitter(); emitter.event(e => { globalState += 1; @@ -625,33 +624,6 @@ suite('PausableEmitter', function () { }); }); -suite('Event utils - ensureNoDisposablesAreLeakedInTestSuite', function () { - ensureNoDisposablesAreLeakedInTestSuite(); - - test('fromObservable', function () { - - const obs = observableValue('test', 12); - const event = Event.fromObservable(obs); - - const values: number[] = []; - const d = event(n => { values.push(n); }); - - obs.set(3, undefined); - obs.set(13, undefined); - obs.set(3, undefined); - obs.set(33, undefined); - obs.set(1, undefined); - - transaction(tx => { - obs.set(334, tx); - obs.set(99, tx); - }); - - assert.deepStrictEqual(values, ([3, 13, 3, 33, 1, 99])); - d.dispose(); - }); -}); - suite('Event utils', () => { suite('EventBufferer', () => { @@ -1061,7 +1033,7 @@ suite('Event utils', () => { const event = eventEmitter.event; let i = 0; - const log = new Array(); + let log = new Array(); const disposable = Event.runAndSubscribeWithStore(event, (e, disposables) => { const idx = i++; log.push({ label: 'handleEvent', data: e || null, idx }); diff --git a/src/vs/base/test/common/filters.test.ts b/src/vs/base/test/common/filters.test.ts index 3c66087c54..4b6c0feee1 100644 --- a/src/vs/base/test/common/filters.test.ts +++ b/src/vs/base/test/common/filters.test.ts @@ -6,7 +6,7 @@ import * as assert from 'assert'; import { anyScore, createMatches, fuzzyScore, fuzzyScoreGraceful, fuzzyScoreGracefulAggressive, FuzzyScorer, IFilter, IMatch, matchesCamelCase, matchesContiguousSubString, matchesPrefix, matchesStrictPrefix, matchesSubString, matchesWords, or } from 'vs/base/common/filters'; function filterOk(filter: IFilter, word: string, wordToMatchAgainst: string, highlights?: { start: number; end: number }[]) { - const r = filter(word, wordToMatchAgainst); + let r = filter(word, wordToMatchAgainst); assert(r, `${word} didn't match ${wordToMatchAgainst}`); if (highlights) { assert.deepStrictEqual(r, highlights); @@ -21,7 +21,7 @@ suite('Filters', () => { test('or', () => { let filter: IFilter; let counters: number[]; - const newFilter = function (i: number, r: boolean): IFilter { + let newFilter = function (i: number, r: boolean): IFilter { return function (): IMatch[] { counters[i]++; return r as any; }; }; @@ -223,10 +223,10 @@ suite('Filters', () => { }); function assertMatches(pattern: string, word: string, decoratedWord: string | undefined, filter: FuzzyScorer, opts: { patternPos?: number; wordPos?: number; firstMatchCanBeWeak?: boolean } = {}) { - const r = filter(pattern, pattern.toLowerCase(), opts.patternPos || 0, word, word.toLowerCase(), opts.wordPos || 0, { firstMatchCanBeWeak: opts.firstMatchCanBeWeak ?? false, boostFullMatch: true }); + let r = filter(pattern, pattern.toLowerCase(), opts.patternPos || 0, word, word.toLowerCase(), opts.wordPos || 0, { firstMatchCanBeWeak: opts.firstMatchCanBeWeak ?? false, boostFullMatch: true }); assert.ok(!decoratedWord === !r); if (r) { - const matches = createMatches(r); + let matches = createMatches(r); let actualWord = ''; let pos = 0; for (const match of matches) { @@ -403,8 +403,8 @@ suite('Filters', () => { }); test('Cannot set property \'1\' of undefined, #26511', function () { - const word = new Array(123).join('a'); - const pattern = new Array(120).join('a'); + let word = new Array(123).join('a'); + let pattern = new Array(120).join('a'); fuzzyScore(pattern, pattern.toLowerCase(), 0, word, word.toLowerCase(), 0); assert.ok(true); // must not explode }); @@ -559,18 +559,18 @@ suite('Filters', () => { }); test('configurable full match boost', function () { - const prefix = 'create'; - const a = 'createModelServices'; - const b = 'create'; + let prefix = 'create'; + let a = 'createModelServices'; + let b = 'create'; - const aBoost = fuzzyScore(prefix, prefix, 0, a, a.toLowerCase(), 0, { boostFullMatch: true, firstMatchCanBeWeak: true }); - const bBoost = fuzzyScore(prefix, prefix, 0, b, b.toLowerCase(), 0, { boostFullMatch: true, firstMatchCanBeWeak: true }); + let aBoost = fuzzyScore(prefix, prefix, 0, a, a.toLowerCase(), 0, { boostFullMatch: true, firstMatchCanBeWeak: true }); + let bBoost = fuzzyScore(prefix, prefix, 0, b, b.toLowerCase(), 0, { boostFullMatch: true, firstMatchCanBeWeak: true }); assert.ok(aBoost); assert.ok(bBoost); assert.ok(aBoost[0] < bBoost[0]); - const aScore = fuzzyScore(prefix, prefix, 0, a, a.toLowerCase(), 0, { boostFullMatch: false, firstMatchCanBeWeak: true }); - const bScore = fuzzyScore(prefix, prefix, 0, b, b.toLowerCase(), 0, { boostFullMatch: false, firstMatchCanBeWeak: true }); + let aScore = fuzzyScore(prefix, prefix, 0, a, a.toLowerCase(), 0, { boostFullMatch: false, firstMatchCanBeWeak: true }); + let bScore = fuzzyScore(prefix, prefix, 0, b, b.toLowerCase(), 0, { boostFullMatch: false, firstMatchCanBeWeak: true }); assert.ok(aScore); assert.ok(bScore); assert.ok(aScore[0] === bScore[0]); diff --git a/src/vs/base/test/common/fuzzyScorer.test.ts b/src/vs/base/test/common/fuzzyScorer.test.ts index ceb701fd14..182a42d9bb 100644 --- a/src/vs/base/test/common/fuzzyScorer.test.ts +++ b/src/vs/base/test/common/fuzzyScorer.test.ts @@ -119,7 +119,7 @@ suite('Fuzzy Scorer', () => { scores.push(_doScore(target, '4', true)); // no match // Assert scoring order - const sortedScores = scores.concat().sort((a, b) => b[0] - a[0]); + let sortedScores = scores.concat().sort((a, b) => b[0] - a[0]); assert.deepStrictEqual(scores, sortedScores); // Assert scoring positions @@ -228,7 +228,7 @@ suite('Fuzzy Scorer', () => { test('scoreItem - multiple', function () { const resource = URI.file('/xyz/some/path/someFile123.txt'); - const res1 = scoreItem(resource, 'xyz some', true, ResourceAccessor); + let res1 = scoreItem(resource, 'xyz some', true, ResourceAccessor); assert.ok(res1.score); assert.strictEqual(res1.labelMatch?.length, 1); assert.strictEqual(res1.labelMatch![0].start, 0); @@ -237,7 +237,7 @@ suite('Fuzzy Scorer', () => { assert.strictEqual(res1.descriptionMatch![0].start, 1); assert.strictEqual(res1.descriptionMatch![0].end, 4); - const res2 = scoreItem(resource, 'some xyz', true, ResourceAccessor); + let res2 = scoreItem(resource, 'some xyz', true, ResourceAccessor); assert.ok(res2.score); assert.strictEqual(res1.score, res2.score); assert.strictEqual(res2.labelMatch?.length, 1); @@ -247,7 +247,7 @@ suite('Fuzzy Scorer', () => { assert.strictEqual(res2.descriptionMatch![0].start, 1); assert.strictEqual(res2.descriptionMatch![0].end, 4); - const res3 = scoreItem(resource, 'some xyz file file123', true, ResourceAccessor); + let res3 = scoreItem(resource, 'some xyz file file123', true, ResourceAccessor); assert.ok(res3.score); assert.ok(res3.score > res2.score); assert.strictEqual(res3.labelMatch?.length, 1); @@ -257,7 +257,7 @@ suite('Fuzzy Scorer', () => { assert.strictEqual(res3.descriptionMatch![0].start, 1); assert.strictEqual(res3.descriptionMatch![0].end, 4); - const res4 = scoreItem(resource, 'path z y', true, ResourceAccessor); + let res4 = scoreItem(resource, 'path z y', true, ResourceAccessor); assert.ok(res4.score); assert.ok(res4.score < res2.score); assert.strictEqual(res4.labelMatch?.length, 0); @@ -271,11 +271,11 @@ suite('Fuzzy Scorer', () => { test('scoreItem - multiple with cache yields different results', function () { const resource = URI.file('/xyz/some/path/someFile123.txt'); const cache = {}; - const res1 = scoreItem(resource, 'xyz sm', true, ResourceAccessor, cache); + let res1 = scoreItem(resource, 'xyz sm', true, ResourceAccessor, cache); assert.ok(res1.score); // from the cache's perspective this should be a totally different query - const res2 = scoreItem(resource, 'xyz "sm"', true, ResourceAccessor, cache); + let res2 = scoreItem(resource, 'xyz "sm"', true, ResourceAccessor, cache); assert.ok(!res2.score); }); @@ -576,7 +576,7 @@ suite('Fuzzy Scorer', () => { const resourceC = URI.file('/unrelated/the/path/other/fileC.txt'); // Resource A part of path - const query = 'somepath'; + let query = 'somepath'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceA); @@ -595,7 +595,7 @@ suite('Fuzzy Scorer', () => { const resourceC = URI.file('/unrelated/the/path/other/fileC.txt'); // Resource A part of path - const query = 'file'; + let query = 'file'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceA); @@ -614,7 +614,7 @@ suite('Fuzzy Scorer', () => { const resourceC = URI.file('/unrelated/some/path/other/fileC.txt'); // Resource A part of path - const query = 'somepath'; + let query = 'somepath'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceA); @@ -632,9 +632,9 @@ suite('Fuzzy Scorer', () => { const resourceB = URI.file('config/test.js'); const resourceC = URI.file('config/test/t2.js'); - const query = 'co/te'; + let query = 'co/te'; - const res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); + let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); assert.strictEqual(res[1], resourceA); assert.strictEqual(res[2], resourceC); @@ -644,9 +644,9 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('parts/quick/arrow-left-dark.svg'); const resourceB = URI.file('parts/quickopen/quickopen.ts'); - const query = 'partsquick'; + let query = 'partsquick'; - const res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); + let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); assert.strictEqual(res[1], resourceA); }); @@ -670,7 +670,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('config/test/openthisAnythingHandler.js'); const resourceB = URI.file('config/test/openthisisnotsorelevantforthequeryAnyHand.js'); - const query = 'AH'; + let query = 'AH'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -685,7 +685,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('config/test/examasdaple.js'); const resourceB = URI.file('config/test/exampleasdaasd.ts'); - const query = 'xp'; + let query = 'xp'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -700,7 +700,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('config/test/examasdaple/file.js'); const resourceB = URI.file('config/test/exampleasdaasd/file.ts'); - const query = 'xp'; + let query = 'xp'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -715,7 +715,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('config/example/thisfile.ts'); const resourceB = URI.file('config/24234243244/example/file.js'); - const query = 'exfile'; + let query = 'exfile'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -754,7 +754,7 @@ suite('Fuzzy Scorer', () => { const resourceB = URI.file('app/containers/Services/NetworkData/ServiceDetails/ServiceDistribution/index.js'); const resourceC = URI.file('app/containers/Services/NetworkData/ServiceDetailTabs/ServiceTabs/StatVideo/index.js'); - const query = 'StatVideoindex'; + let query = 'StatVideoindex'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceC); @@ -767,7 +767,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('src/build-helper/store/redux.ts'); const resourceB = URI.file('src/repository/store/redux.ts'); - const query = 'reproreduxts'; + let query = 'reproreduxts'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -781,7 +781,7 @@ suite('Fuzzy Scorer', () => { const resourceB = URI.file('photobook/src/components/ApprovalPageHeader/index.js'); const resourceC = URI.file('photobook/src/canvasComponents/BookPage/index.js'); - const query = 'bookpageIndex'; + let query = 'bookpageIndex'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceC); @@ -794,7 +794,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('ui/src/utils/constants.js'); const resourceB = URI.file('ui/src/ui/Icons/index.js'); - const query = isWindows ? 'ui\\icons' : 'ui/icons'; + let query = isWindows ? 'ui\\icons' : 'ui/icons'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -807,7 +807,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('ui/src/components/IDInput/index.js'); const resourceB = URI.file('ui/src/ui/Input/index.js'); - const query = isWindows ? 'ui\\input\\index' : 'ui/input/index'; + let query = isWindows ? 'ui\\input\\index' : 'ui/input/index'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -820,7 +820,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('django/contrib/sites/locale/ga/LC_MESSAGES/django.mo'); const resourceB = URI.file('django/core/signals.py'); - const query = 'djancosig'; + let query = 'djancosig'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -834,7 +834,7 @@ suite('Fuzzy Scorer', () => { const resourceB = URI.file('adsys/protected/framework/smarty/sysplugins/smarty_internal_config.php'); const resourceC = URI.file('duowanVideo/wap/protected/config.php'); - const query = 'protectedconfig.php'; + let query = 'protectedconfig.php'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceA); @@ -851,7 +851,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('pkg/search/gradient/testdata/constraint_attrMatchString.yml'); const resourceB = URI.file('cmd/gradient/main.go'); - const query = 'gradientmain'; + let query = 'gradientmain'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -864,7 +864,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('alpha-beta-cappa.txt'); const resourceB = URI.file('abc.txt'); - const query = 'abc'; + let query = 'abc'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -877,7 +877,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('xerxes-yak-zubba/index.js'); const resourceB = URI.file('xyz/index.js'); - const query = 'xyz'; + let query = 'xyz'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -890,7 +890,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('AssymblyInfo.cs'); const resourceB = URI.file('IAsynchronousTask.java'); - const query = 'async'; + let query = 'async'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -903,7 +903,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('static/app/source/angluar/-admin/-organization/-settings/layout/layout.js'); const resourceB = URI.file('static/app/source/angular/-admin/-project/-settings/_settings/settings.js'); - const query = 'partisettings'; + let query = 'partisettings'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -916,7 +916,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('Trilby.TrilbyTV.Web.Portal/Views/Systems/Index.cshtml'); const resourceB = URI.file('Trilby.TrilbyTV.Web.Portal/Areas/Admins/Views/Tips/Index.cshtml'); - const query = 'tipsindex.cshtml'; + let query = 'tipsindex.cshtml'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -929,7 +929,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('editor/core/components/tests/list-view-spec.js'); const resourceB = URI.file('editor/core/components/list-view.js'); - const query = 'listview'; + let query = 'listview'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -943,7 +943,7 @@ suite('Fuzzy Scorer', () => { const resourceB = URI.file('src/vs/workbench/contrib/files/browser/views/explorerView.ts'); const resourceC = URI.file('src/vs/workbench/contrib/files/browser/views/explorerViewer.ts'); - const query = 'filesexplorerview.ts'; + let query = 'filesexplorerview.ts'; let res = [resourceA, resourceB, resourceC].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -956,7 +956,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('lists.php'); const resourceB = URI.file('lib/Lists.php'); - const query = 'Lists.php'; + let query = 'Lists.php'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceB); @@ -1039,7 +1039,7 @@ suite('Fuzzy Scorer', () => { const resourceA = URI.file('test/smoke/src/main.ts'); const resourceB = URI.file('src/vs/editor/common/services/semantikTokensProviderStyling.ts'); - const query = 'smoke main.ts'; + let query = 'smoke main.ts'; let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor)); assert.strictEqual(res[0], resourceA); @@ -1120,7 +1120,7 @@ suite('Fuzzy Scorer', () => { assert.strictEqual(query.values?.[1].normalized, 'World'); assert.strictEqual(query.values?.[1].normalizedLowercase, 'World'.toLowerCase()); - const restoredQuery = pieceToQuery(query.values!); + let restoredQuery = pieceToQuery(query.values!); assert.strictEqual(restoredQuery.original, query.original); assert.strictEqual(restoredQuery.values?.length, query.values?.length); assert.strictEqual(restoredQuery.containsPathSeparator, query.containsPathSeparator); diff --git a/src/vs/base/test/common/glob.test.ts b/src/vs/base/test/common/glob.test.ts index 2c009b3fef..3253a1bdb8 100644 --- a/src/vs/base/test/common/glob.test.ts +++ b/src/vs/base/test/common/glob.test.ts @@ -203,7 +203,7 @@ suite('Glob', () => { }); test('file / folder match', function () { - const p = '**/node_modules/**'; + let p = '**/node_modules/**'; assertGlobMatch(p, 'node_modules'); assertGlobMatch(p, 'node_modules/'); @@ -469,8 +469,8 @@ suite('Glob', () => { }); test('expression support (single)', function () { - const siblings = ['test.html', 'test.txt', 'test.ts', 'test.js']; - const hasSibling = (name: string) => siblings.indexOf(name) !== -1; + let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js']; + let hasSibling = (name: string) => siblings.indexOf(name) !== -1; // { "**/*.js": { "when": "$(basename).ts" } } let expression: glob.IExpression = { @@ -505,11 +505,11 @@ suite('Glob', () => { }); test('expression support (multiple)', function () { - const siblings = ['test.html', 'test.txt', 'test.ts', 'test.js']; - const hasSibling = (name: string) => siblings.indexOf(name) !== -1; + let siblings = ['test.html', 'test.txt', 'test.ts', 'test.js']; + let hasSibling = (name: string) => siblings.indexOf(name) !== -1; // { "**/*.js": { "when": "$(basename).ts" } } - const expression: glob.IExpression = { + let expression: glob.IExpression = { '**/*.js': { when: '$(basename).ts' }, '**/*.as': true, '**/*.foo': false, @@ -632,7 +632,7 @@ suite('Glob', () => { }); test('cached properly', function () { - const p = '**/*.js'; + let p = '**/*.js'; assertGlobMatch(p, 'foo.js'); assertGlobMatch(p, 'testing/foo.js'); @@ -692,7 +692,7 @@ suite('Glob', () => { }); test('invalid glob', function () { - const p = '**/*(.js'; + let p = '**/*(.js'; assertNoGlobMatch(p, 'foo.js'); }); @@ -710,13 +710,13 @@ suite('Glob', () => { }); test('expression with disabled glob', function () { - const expr = { '**/*.js': false }; + let expr = { '**/*.js': false }; assert.strictEqual(glob.match(expr, 'foo.js'), null); }); test('expression with two non-trivia globs', function () { - const expr = { + let expr = { '**/*.j?': true, '**/*.t?': true }; @@ -726,7 +726,7 @@ suite('Glob', () => { }); test('expression with non-trivia glob (issue 144458)', function () { - const pattern = '**/p*'; + let pattern = '**/p*'; assert.strictEqual(glob.match(pattern, 'foo/barp'), false); assert.strictEqual(glob.match(pattern, 'foo/bar/ap'), false); @@ -751,19 +751,19 @@ suite('Glob', () => { }); test('expression with empty glob', function () { - const expr = { '': true }; + let expr = { '': true }; assert.strictEqual(glob.match(expr, 'foo.js'), null); }); test('expression with other falsy value', function () { - const expr = { '**/*.js': 0 } as any; + let expr = { '**/*.js': 0 } as any; assert.strictEqual(glob.match(expr, 'foo.js'), '**/*.js'); }); test('expression with two basename globs', function () { - const expr = { + let expr = { '**/bar': true, '**/baz': true }; @@ -776,14 +776,14 @@ suite('Glob', () => { }); test('expression with two basename globs and a siblings expression', function () { - const expr = { + let expr = { '**/bar': true, '**/baz': true, '**/*.js': { when: '$(basename).ts' } }; - const siblings = ['foo.ts', 'foo.js', 'foo', 'bar']; - const hasSibling = (name: string) => siblings.indexOf(name) !== -1; + let siblings = ['foo.ts', 'foo.js', 'foo', 'bar']; + let hasSibling = (name: string) => siblings.indexOf(name) !== -1; assert.strictEqual(glob.match(expr, 'bar', hasSibling), '**/bar'); assert.strictEqual(glob.match(expr, 'foo', hasSibling), null); @@ -798,7 +798,7 @@ suite('Glob', () => { }); test('expression with multipe basename globs', function () { - const expr = { + let expr = { '**/bar': true, '{**/baz,**/foo}': true }; @@ -838,9 +838,9 @@ suite('Glob', () => { assert.strictEqual(glob.parse('{**/baz,**/foo}')('baz/bar', 'bar'), false); assert.strictEqual(glob.parse('{**/baz,**/foo}')('baz/foo', 'foo'), true); - const expr = { '**/*.js': { when: '$(basename).ts' } }; - const siblings = ['foo.ts', 'foo.js']; - const hasSibling = (name: string) => siblings.indexOf(name) !== -1; + let expr = { '**/*.js': { when: '$(basename).ts' } }; + let siblings = ['foo.ts', 'foo.js']; + let hasSibling = (name: string) => siblings.indexOf(name) !== -1; assert.strictEqual(glob.parse(expr)('bar/baz.js', 'baz.js', hasSibling), null); assert.strictEqual(glob.parse(expr)('bar/foo.js', 'foo.js', hasSibling), '**/*.js'); @@ -990,7 +990,7 @@ suite('Glob', () => { ]); const siblings = ['baz', 'baz.zip', 'nope']; - const hasSibling = (name: string) => siblings.indexOf(name) !== -1; + let hasSibling = (name: string) => siblings.indexOf(name) !== -1; testOptimizationForPaths({ '**/foo/123/**': { when: '$(basename).zip' }, '**/bar/123/**': true @@ -1020,14 +1020,14 @@ suite('Glob', () => { test('relative pattern - glob star', function () { if (isWindows) { - const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: '**/*.cs' }; + let p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: '**/*.cs' }; assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs'); assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\bar\\Program.cs'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.ts'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\Program.cs'); assertNoGlobMatch(p, 'C:\\other\\DNXConsoleApp\\foo\\Program.ts'); } else { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: '**/*.cs' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: '**/*.cs' }; assertGlobMatch(p, '/DNXConsoleApp/foo/Program.cs'); assertGlobMatch(p, '/DNXConsoleApp/foo/bar/Program.cs'); assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.ts'); @@ -1038,14 +1038,14 @@ suite('Glob', () => { test('relative pattern - single star', function () { if (isWindows) { - const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: '*.cs' }; + let p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: '*.cs' }; assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\bar\\Program.cs'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.ts'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\Program.cs'); assertNoGlobMatch(p, 'C:\\other\\DNXConsoleApp\\foo\\Program.ts'); } else { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: '*.cs' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: '*.cs' }; assertGlobMatch(p, '/DNXConsoleApp/foo/Program.cs'); assertNoGlobMatch(p, '/DNXConsoleApp/foo/bar/Program.cs'); assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.ts'); @@ -1056,11 +1056,11 @@ suite('Glob', () => { test('relative pattern - single star with path', function () { if (isWindows) { - const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'something/*.cs' }; + let p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'something/*.cs' }; assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\something\\Program.cs'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs'); } else { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' }; assertGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs'); assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs'); } @@ -1068,11 +1068,11 @@ suite('Glob', () => { test('relative pattern - single star alone', function () { if (isWindows) { - const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo\\something\\Program.cs', pattern: '*' }; + let p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo\\something\\Program.cs', pattern: '*' }; assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\something\\Program.cs'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs'); } else { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo/something/Program.cs', pattern: '*' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo/something/Program.cs', pattern: '*' }; assertGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs'); assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs'); } @@ -1080,13 +1080,13 @@ suite('Glob', () => { test('relative pattern - ignores case on macOS/Windows', function () { if (isWindows) { - const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'something/*.cs' }; + let p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'something/*.cs' }; assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\something\\Program.cs'.toLowerCase()); } else if (isMacintosh) { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' }; assertGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs'.toLowerCase()); } else if (isLinux) { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'something/*.cs' }; assertNoGlobMatch(p, '/DNXConsoleApp/foo/something/Program.cs'.toLowerCase()); } }); @@ -1097,27 +1097,27 @@ suite('Glob', () => { test('relative pattern - #57475', function () { if (isWindows) { - const p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'styles/style.css' }; + let p: glob.IRelativePattern = { base: 'C:\\DNXConsoleApp\\foo', pattern: 'styles/style.css' }; assertGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\styles\\style.css'); assertNoGlobMatch(p, 'C:\\DNXConsoleApp\\foo\\Program.cs'); } else { - const p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'styles/style.css' }; + let p: glob.IRelativePattern = { base: '/DNXConsoleApp/foo', pattern: 'styles/style.css' }; assertGlobMatch(p, '/DNXConsoleApp/foo/styles/style.css'); assertNoGlobMatch(p, '/DNXConsoleApp/foo/Program.cs'); } }); test('URI match', () => { - const p = 'scheme:/**/*.md'; + let p = 'scheme:/**/*.md'; assertGlobMatch(p, URI.file('super/duper/long/some/file.md').with({ scheme: 'scheme' }).toString()); }); test('expression fails when siblings use promises (https://github.com/microsoft/vscode/issues/146294)', async function () { - const siblings = ['test.html', 'test.txt', 'test.ts']; - const hasSibling = (name: string) => Promise.resolve(siblings.indexOf(name) !== -1); + let siblings = ['test.html', 'test.txt', 'test.ts']; + let hasSibling = (name: string) => Promise.resolve(siblings.indexOf(name) !== -1); // { "**/*.js": { "when": "$(basename).ts" } } - const expression: glob.IExpression = { + let expression: glob.IExpression = { '**/test.js': { when: '$(basename).js' }, '**/*.js': { when: '$(basename).ts' } }; diff --git a/src/vs/base/test/common/history.test.ts b/src/vs/base/test/common/history.test.ts index 929d7a7631..1252c81f8f 100644 --- a/src/vs/base/test/common/history.test.ts +++ b/src/vs/base/test/common/history.test.ts @@ -148,7 +148,7 @@ suite('History Navigator', () => { }); function toArray(historyNavigator: HistoryNavigator): Array { - const result: Array = []; + let result: Array = []; historyNavigator.first(); if (historyNavigator.current()) { do { diff --git a/src/vs/base/test/common/iconLabels.test.ts b/src/vs/base/test/common/iconLabels.test.ts index 9f6c5795a9..8bde354333 100644 --- a/src/vs/base/test/common/iconLabels.test.ts +++ b/src/vs/base/test/common/iconLabels.test.ts @@ -13,7 +13,7 @@ export interface IIconFilter { } function filterOk(filter: IIconFilter, word: string, target: IParsedLabelWithIcons, highlights?: { start: number; end: number }[]) { - const r = filter(word, target); + let r = filter(word, target); assert(r); if (highlights) { assert.deepStrictEqual(r, highlights); diff --git a/src/vs/base/test/common/json.test.ts b/src/vs/base/test/common/json.test.ts index 8f66b752a3..f4081e0292 100644 --- a/src/vs/base/test/common/json.test.ts +++ b/src/vs/base/test/common/json.test.ts @@ -7,7 +7,7 @@ import { createScanner, Node, parse, ParseError, ParseErrorCode, ParseOptions, p import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages'; function assertKinds(text: string, ...kinds: SyntaxKind[]): void { - const scanner = createScanner(text); + let scanner = createScanner(text); let kind: SyntaxKind; while ((kind = scanner.scan()) !== SyntaxKind.EOF) { assert.strictEqual(kind, kinds.shift()); @@ -15,15 +15,15 @@ function assertKinds(text: string, ...kinds: SyntaxKind[]): void { assert.strictEqual(kinds.length, 0); } function assertScanError(text: string, expectedKind: SyntaxKind, scanError: ScanError): void { - const scanner = createScanner(text); + let scanner = createScanner(text); scanner.scan(); assert.strictEqual(scanner.getToken(), expectedKind); assert.strictEqual(scanner.getTokenError(), scanError); } function assertValidParse(input: string, expected: any, options?: ParseOptions): void { - const errors: ParseError[] = []; - const actual = parse(input, errors, options); + let errors: ParseError[] = []; + let actual = parse(input, errors, options); if (errors.length !== 0) { assert(false, getParseErrorMessage(errors[0].error)); @@ -32,21 +32,21 @@ function assertValidParse(input: string, expected: any, options?: ParseOptions): } function assertInvalidParse(input: string, expected: any, options?: ParseOptions): void { - const errors: ParseError[] = []; - const actual = parse(input, errors, options); + let errors: ParseError[] = []; + let actual = parse(input, errors, options); assert(errors.length > 0); assert.deepStrictEqual(actual, expected); } function assertTree(input: string, expected: any, expectedErrors: number[] = [], options?: ParseOptions): void { - const errors: ParseError[] = []; - const actual = parseTree(input, errors, options); + let errors: ParseError[] = []; + let actual = parseTree(input, errors, options); assert.deepStrictEqual(errors.map(e => e.error, expected), expectedErrors); - const checkParent = (node: Node) => { + let checkParent = (node: Node) => { if (node.children) { - for (const child of node.children) { + for (let child of node.children) { assert.strictEqual(node, child.parent); delete (child).parent; // delete to avoid recursion in deep equal checkParent(child); @@ -216,7 +216,7 @@ suite('JSON', () => { }); test('parse: disallow commments', () => { - const options = { disallowComments: true }; + let options = { disallowComments: true }; assertValidParse('[ 1, 2, null, "foo" ]', [1, 2, null, 'foo'], options); assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} }, options); diff --git a/src/vs/base/test/common/jsonEdit.test.ts b/src/vs/base/test/common/jsonEdit.test.ts index d14326cbef..a308efb6ca 100644 --- a/src/vs/base/test/common/jsonEdit.test.ts +++ b/src/vs/base/test/common/jsonEdit.test.ts @@ -12,7 +12,7 @@ suite('JSON - edits', () => { assert(edits); let lastEditOffset = content.length; for (let i = edits.length - 1; i >= 0; i--) { - const edit = edits[i]; + let edit = edits[i]; assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length); assert(typeof edit.content === 'string'); assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered @@ -22,7 +22,7 @@ suite('JSON - edits', () => { assert.strictEqual(content, expected); } - const formatterOptions: FormattingOptions = { + let formatterOptions: FormattingOptions = { insertSpaces: true, tabSize: 2, eol: '\n' @@ -119,74 +119,74 @@ suite('JSON - edits', () => { }); test('insert item at 0', () => { - const content = '[\n 2,\n 3\n]'; - const edits = setProperty(content, [0], 1, formatterOptions); + let content = '[\n 2,\n 3\n]'; + let edits = setProperty(content, [0], 1, formatterOptions); assertEdit(content, edits, '[\n 1,\n 2,\n 3\n]'); }); test('insert item at 0 in empty array', () => { - const content = '[\n]'; - const edits = setProperty(content, [0], 1, formatterOptions); + let content = '[\n]'; + let edits = setProperty(content, [0], 1, formatterOptions); assertEdit(content, edits, '[\n 1\n]'); }); test('insert item at an index', () => { - const content = '[\n 1,\n 3\n]'; - const edits = setProperty(content, [1], 2, formatterOptions); + let content = '[\n 1,\n 3\n]'; + let edits = setProperty(content, [1], 2, formatterOptions); assertEdit(content, edits, '[\n 1,\n 2,\n 3\n]'); }); test('insert item at an index im empty array', () => { - const content = '[\n]'; - const edits = setProperty(content, [1], 1, formatterOptions); + let content = '[\n]'; + let edits = setProperty(content, [1], 1, formatterOptions); assertEdit(content, edits, '[\n 1\n]'); }); test('insert item at end index', () => { - const content = '[\n 1,\n 2\n]'; - const edits = setProperty(content, [2], 3, formatterOptions); + let content = '[\n 1,\n 2\n]'; + let edits = setProperty(content, [2], 3, formatterOptions); assertEdit(content, edits, '[\n 1,\n 2,\n 3\n]'); }); test('insert item at end to empty array', () => { - const content = '[\n]'; - const edits = setProperty(content, [-1], 'bar', formatterOptions); + let content = '[\n]'; + let edits = setProperty(content, [-1], 'bar', formatterOptions); assertEdit(content, edits, '[\n "bar"\n]'); }); test('insert item at end', () => { - const content = '[\n 1,\n 2\n]'; - const edits = setProperty(content, [-1], 'bar', formatterOptions); + let content = '[\n 1,\n 2\n]'; + let edits = setProperty(content, [-1], 'bar', formatterOptions); assertEdit(content, edits, '[\n 1,\n 2,\n "bar"\n]'); }); test('remove item in array with one item', () => { - const content = '[\n 1\n]'; - const edits = setProperty(content, [0], undefined, formatterOptions); + let content = '[\n 1\n]'; + let edits = setProperty(content, [0], undefined, formatterOptions); assertEdit(content, edits, '[]'); }); test('remove item in the middle of the array', () => { - const content = '[\n 1,\n 2,\n 3\n]'; - const edits = setProperty(content, [1], undefined, formatterOptions); + let content = '[\n 1,\n 2,\n 3\n]'; + let edits = setProperty(content, [1], undefined, formatterOptions); assertEdit(content, edits, '[\n 1,\n 3\n]'); }); test('remove last item in the array', () => { - const content = '[\n 1,\n 2,\n "bar"\n]'; - const edits = setProperty(content, [2], undefined, formatterOptions); + let content = '[\n 1,\n 2,\n "bar"\n]'; + let edits = setProperty(content, [2], undefined, formatterOptions); assertEdit(content, edits, '[\n 1,\n 2\n]'); }); test('remove last item in the array if ends with comma', () => { - const content = '[\n 1,\n "foo",\n "bar",\n]'; - const edits = setProperty(content, [2], undefined, formatterOptions); + let content = '[\n 1,\n "foo",\n "bar",\n]'; + let edits = setProperty(content, [2], undefined, formatterOptions); assertEdit(content, edits, '[\n 1,\n "foo"\n]'); }); test('remove last item in the array if there is a comment in the beginning', () => { - const content = '// This is a comment\n[\n 1,\n "foo",\n "bar"\n]'; - const edits = setProperty(content, [2], undefined, formatterOptions); + let content = '// This is a comment\n[\n 1,\n "foo",\n "bar"\n]'; + let edits = setProperty(content, [2], undefined, formatterOptions); assertEdit(content, edits, '// This is a comment\n[\n 1,\n "foo"\n]'); }); diff --git a/src/vs/base/test/common/jsonFormatter.test.ts b/src/vs/base/test/common/jsonFormatter.test.ts index ad17e96770..677dd24a92 100644 --- a/src/vs/base/test/common/jsonFormatter.test.ts +++ b/src/vs/base/test/common/jsonFormatter.test.ts @@ -20,7 +20,7 @@ suite('JSON - formatter', () => { let lastEditOffset = content.length; for (let i = edits.length - 1; i >= 0; i--) { - const edit = edits[i]; + let edit = edits[i]; assert(edit.offset >= 0 && edit.length >= 0 && edit.offset + edit.length <= content.length); assert(typeof edit.content === 'string'); assert(lastEditOffset >= edit.offset + edit.length); // make sure all edits are ordered diff --git a/src/vs/base/test/common/labels.test.ts b/src/vs/base/test/common/labels.test.ts index 22755f5b84..c9c0bb4cf8 100644 --- a/src/vs/base/test/common/labels.test.ts +++ b/src/vs/base/test/common/labels.test.ts @@ -139,6 +139,20 @@ suite('Labels', () => { assert.strictEqual(labels.template(t, { dirty: '* ', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), '* somefile.txt - monaco - Visual Studio Code'); }); + (isWindows ? test.skip : test)('getBaseLabel - unix', () => { + assert.strictEqual(labels.getBaseLabel('/some/folder/file.txt'), 'file.txt'); + assert.strictEqual(labels.getBaseLabel('/some/folder'), 'folder'); + assert.strictEqual(labels.getBaseLabel('/'), '/'); + }); + + (!isWindows ? test.skip : test)('getBaseLabel - windows', () => { + assert.strictEqual(labels.getBaseLabel('c:'), 'C:'); + assert.strictEqual(labels.getBaseLabel('c:\\'), 'C:'); + assert.strictEqual(labels.getBaseLabel('c:\\some\\folder\\file.txt'), 'file.txt'); + assert.strictEqual(labels.getBaseLabel('c:\\some\\folder'), 'folder'); + assert.strictEqual(labels.getBaseLabel('c:\\some\\f:older'), 'f:older'); // https://github.com/microsoft/vscode-remote-release/issues/4227 + }); + test('mnemonicButtonLabel', () => { assert.strictEqual(labels.mnemonicButtonLabel('Hello World'), 'Hello World'); assert.strictEqual(labels.mnemonicButtonLabel(''), ''); diff --git a/src/vs/base/test/common/lifecycle.test.ts b/src/vs/base/test/common/lifecycle.test.ts index 8f31c050df..91f636f9bd 100644 --- a/src/vs/base/test/common/lifecycle.test.ts +++ b/src/vs/base/test/common/lifecycle.test.ts @@ -95,16 +95,16 @@ suite('Lifecycle', () => { }); test('Action bar has broken accessibility #100273', function () { - const array = [{ dispose() { } }, { dispose() { } }]; - const array2 = dispose(array); + let array = [{ dispose() { } }, { dispose() { } }]; + let array2 = dispose(array); assert.strictEqual(array.length, 2); assert.strictEqual(array2.length, 0); assert.ok(array !== array2); - const set = new Set([{ dispose() { } }, { dispose() { } }]); - const setValues = set.values(); - const setValues2 = dispose(setValues); + let set = new Set([{ dispose() { } }, { dispose() { } }]); + let setValues = set.values(); + let setValues2 = dispose(setValues); assert.ok(setValues === setValues2); }); diff --git a/src/vs/base/test/common/linkedList.test.ts b/src/vs/base/test/common/linkedList.test.ts index 876b6649fd..3b9c2d62f5 100644 --- a/src/vs/base/test/common/linkedList.test.ts +++ b/src/vs/base/test/common/linkedList.test.ts @@ -66,7 +66,7 @@ suite('LinkedList', function () { }); test('Push/toArray', () => { - const list = new LinkedList(); + let list = new LinkedList(); list.push('foo'); list.push('bar'); list.push('far'); @@ -107,7 +107,7 @@ suite('LinkedList', function () { }); test('unshift/toArray', () => { - const list = new LinkedList(); + let list = new LinkedList(); list.unshift('foo'); list.unshift('bar'); list.unshift('far'); @@ -116,20 +116,20 @@ suite('LinkedList', function () { }); test('pop/unshift', function () { - const list = new LinkedList(); + let list = new LinkedList(); list.push('a'); list.push('b'); assertElements(list, 'a', 'b'); - const a = list.shift(); + let a = list.shift(); assert.strictEqual(a, 'a'); assertElements(list, 'b'); list.unshift('a'); assertElements(list, 'a', 'b'); - const b = list.pop(); + let b = list.pop(); assert.strictEqual(b, 'b'); assertElements(list, 'a'); }); diff --git a/src/vs/base/test/common/map.test.ts b/src/vs/base/test/common/map.test.ts index 3f4a18d423..4b9dbf548a 100644 --- a/src/vs/base/test/common/map.test.ts +++ b/src/vs/base/test/common/map.test.ts @@ -14,7 +14,7 @@ import { URI } from 'vs/base/common/uri'; suite('Map', () => { test('LinkedMap - Simple', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('bk', 'bv'); assert.deepStrictEqual([...map.keys()], ['ak', 'bk']); @@ -24,7 +24,7 @@ suite('Map', () => { }); test('LinkedMap - Touch Old one', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('ak', 'av', Touch.AsOld); assert.deepStrictEqual([...map.keys()], ['ak']); @@ -32,7 +32,7 @@ suite('Map', () => { }); test('LinkedMap - Touch New one', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('ak', 'av', Touch.AsNew); assert.deepStrictEqual([...map.keys()], ['ak']); @@ -40,7 +40,7 @@ suite('Map', () => { }); test('LinkedMap - Touch Old two', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('bk', 'bv'); map.set('bk', 'bv', Touch.AsOld); @@ -49,7 +49,7 @@ suite('Map', () => { }); test('LinkedMap - Touch New two', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('bk', 'bv'); map.set('ak', 'av', Touch.AsNew); @@ -58,7 +58,7 @@ suite('Map', () => { }); test('LinkedMap - Touch Old from middle', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('bk', 'bv'); map.set('ck', 'cv'); @@ -68,7 +68,7 @@ suite('Map', () => { }); test('LinkedMap - Touch New from middle', () => { - const map = new LinkedMap(); + let map = new LinkedMap(); map.set('ak', 'av'); map.set('bk', 'bv'); map.set('ck', 'cv'); @@ -199,7 +199,7 @@ suite('Map', () => { cache.set(7, 7); assert.strictEqual(cache.size, 5); assert.deepStrictEqual([...cache.keys()], [3, 4, 5, 6, 7]); - const values: number[] = []; + let values: number[] = []; [3, 4, 5, 6, 7].forEach(key => values.push(cache.get(key)!)); assert.deepStrictEqual(values, [3, 4, 5, 6, 7]); }); @@ -214,7 +214,7 @@ suite('Map', () => { assert.deepStrictEqual([...cache.keys()], [1, 2, 4, 5, 3]); cache.peek(4); assert.deepStrictEqual([...cache.keys()], [1, 2, 4, 5, 3]); - const values: number[] = []; + let values: number[] = []; [1, 2, 3, 4, 5].forEach(key => values.push(cache.get(key)!)); assert.deepStrictEqual(values, [1, 2, 3, 4, 5]); }); @@ -235,7 +235,7 @@ suite('Map', () => { cache.set(i, i); } assert.deepStrictEqual(cache.size, 15); - const values: number[] = []; + let values: number[] = []; for (let i = 6; i <= 20; i++) { values.push(cache.get(i)!); assert.strictEqual(cache.get(i), i); @@ -253,7 +253,7 @@ suite('Map', () => { cache.set(11, 11); assert.strictEqual(cache.size, 5); assert.deepStrictEqual([...cache.keys()], [7, 8, 9, 10, 11]); - const values: number[] = []; + let values: number[] = []; [...cache.keys()].forEach(key => values.push(cache.get(key)!)); assert.deepStrictEqual(values, [7, 8, 9, 10, 11]); assert.deepStrictEqual([...cache.values()], values); @@ -486,7 +486,7 @@ suite('Map', () => { assert.ok(trie._isBalanced(), 'TST is not balanced'); let i = 0; - for (const [key, value] of trie) { + for (let [key, value] of trie) { const expected = elements[i++]; assert.ok(expected); assert.strictEqual(key, expected[0]); @@ -513,7 +513,7 @@ suite('Map', () => { // iterator let iterCount = 0; - for (const [key, value] of trie) { + for (let [key, value] of trie) { assert.strictEqual(value, map.get(key)); iterCount++; } @@ -557,7 +557,7 @@ suite('Map', () => { test('TernarySearchTree - findLongestMatch', function () { - const trie = TernarySearchTree.forStrings(); + let trie = TernarySearchTree.forStrings(); trie.set('foo', 1); trie.set('foobar', 2); trie.set('foobaz', 3); @@ -573,7 +573,7 @@ suite('Map', () => { }); test('TernarySearchTree - basics', function () { - const trie = new TernarySearchTree(new StringIterator()); + let trie = new TernarySearchTree(new StringIterator()); trie.set('foo', 1); trie.set('bar', 2); @@ -641,7 +641,7 @@ suite('Map', () => { }); test('TernarySearchTree (PathSegments) - basics', function () { - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/user/foo/bar', 1); trie.set('/user/foo', 2); @@ -666,7 +666,7 @@ suite('Map', () => { test('TernarySearchTree - (AVL) set', function () { { // rotate left - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/fileA', 1); trie.set('/fileB', 2); trie.set('/fileC', 3); @@ -675,7 +675,7 @@ suite('Map', () => { { // rotate left (inside middle) - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/foo/fileA', 1); trie.set('/foo/fileB', 2); trie.set('/foo/fileC', 3); @@ -684,7 +684,7 @@ suite('Map', () => { { // rotate right - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/fileC', 3); trie.set('/fileB', 2); trie.set('/fileA', 1); @@ -693,7 +693,7 @@ suite('Map', () => { { // rotate right (inside middle) - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/mid/fileC', 3); trie.set('/mid/fileB', 2); trie.set('/mid/fileA', 1); @@ -702,7 +702,7 @@ suite('Map', () => { { // rotate right, left - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/fileD', 7); trie.set('/fileB', 2); trie.set('/fileG', 42); @@ -714,7 +714,7 @@ suite('Map', () => { { // rotate left, right - const trie = new TernarySearchTree(new PathIterator()); + let trie = new TernarySearchTree(new PathIterator()); trie.set('/fileJ', 42); trie.set('/fileZ', 73); trie.set('/fileE', 15); @@ -727,7 +727,7 @@ suite('Map', () => { test('TernarySearchTree - (BST) delete', function () { - const trie = new TernarySearchTree(new StringIterator()); + let trie = new TernarySearchTree(new StringIterator()); // delete root trie.set('d', 1); @@ -757,7 +757,7 @@ suite('Map', () => { test('TernarySearchTree - (AVL) delete', function () { - const trie = new TernarySearchTree(new StringIterator()); + let trie = new TernarySearchTree(new StringIterator()); trie.clear(); trie.set('d', 1); @@ -811,7 +811,7 @@ suite('Map', () => { const tst = TernarySearchTree.forUris(); - for (const item of keys) { + for (let item of keys) { tst.set(item, true); } @@ -824,7 +824,7 @@ suite('Map', () => { const keys = ['C', 'A', 'D', 'B',]; const tst = TernarySearchTree.forStrings(); - for (const item of keys) { + for (let item of keys) { tst.set(item, true); } assertTstDfs(tst, ['A', true], ['B', true], ['C', true], ['D', true]); @@ -850,14 +850,14 @@ suite('Map', () => { } const tst = TernarySearchTree.forUris(); - for (const item of keys) { + for (let item of keys) { tst.set(item, true); - assert.ok(tst._isBalanced(), `SET${item}|${keys.map(String).join()}`); + assert.ok(tst._isBalanced()); } - for (const item of keys) { + for (let item of keys) { tst.delete(item); - assert.ok(tst._isBalanced(), `DEL${item}|${keys.map(String).join()}`); + assert.ok(tst._isBalanced()); } } }); @@ -953,7 +953,7 @@ suite('Map', () => { }); test('TernarySearchTree (URI) - basics', function () { - const trie = new TernarySearchTree(new UriIterator(() => false, () => false)); + let trie = new TernarySearchTree(new UriIterator(() => false, () => false)); trie.set(URI.file('/user/foo/bar'), 1); trie.set(URI.file('/user/foo'), 2); @@ -972,7 +972,7 @@ suite('Map', () => { }); test('TernarySearchTree (URI) - query parameters', function () { - const trie = new TernarySearchTree(new UriIterator(() => false, () => true)); + let trie = new TernarySearchTree(new UriIterator(() => false, () => true)); const root = URI.parse('memfs:/?param=1'); trie.set(root, 1); @@ -1066,7 +1066,7 @@ suite('Map', () => { }); test('TernarySearchTree (ConfigKeySegments) - basics', function () { - const trie = new TernarySearchTree(new ConfigKeysIterator()); + let trie = new TernarySearchTree(new ConfigKeysIterator()); trie.set('config.foo.bar', 1); trie.set('config.foo', 2); @@ -1107,7 +1107,7 @@ suite('Map', () => { map.set('boo', 4); let item: IteratorResult<[string, number]>; - const iter = map.findSuperstr('config'); + let iter = map.findSuperstr('config'); item = iter!.next(); assert.strictEqual(item.value[1], 2); @@ -1171,7 +1171,7 @@ suite('Map', () => { Object.freeze(keys); tst.fill(true, keys); - for (const key of keys) { + for (let key of keys) { assert.ok(tst.get(key), key); } }); @@ -1188,7 +1188,7 @@ suite('Map', () => { assert.strictEqual(map.size, 0); - const res = map.set(resource1, 1); + let res = map.set(resource1, 1); assert.ok(res === map); map.set(resource2, '2'); map.set(resource3, true); @@ -1343,7 +1343,7 @@ suite.skip('TST, perf', function () { const uris: URI[] = []; function randomWord(): string { let result = ''; - const length = 4 + Math.floor(Math.random() * 4); + let length = 4 + Math.floor(Math.random() * 4); for (let i = 0; i < length; i++) { result += (Math.random() * 26 + 65).toString(36); } @@ -1360,7 +1360,7 @@ suite.skip('TST, perf', function () { let len = 4 + Math.floor(Math.random() * 4); - const segments: string[] = []; + let segments: string[] = []; for (; len >= 0; len--) { segments.push(words[Math.floor(Math.random() * words.length)]); } @@ -1384,7 +1384,7 @@ suite.skip('TST, perf', function () { setup(() => { tree = TernarySearchTree.forUris(); - for (const uri of sampleUris) { + for (let uri of sampleUris) { tree.set(uri, true); } }); @@ -1406,15 +1406,15 @@ suite.skip('TST, perf', function () { }); perfTest('TST, insert', function () { - const insertTree = TernarySearchTree.forUris(); - for (const uri of sampleUris) { + let insertTree = TernarySearchTree.forUris(); + for (let uri of sampleUris) { insertTree.set(uri, true); } }); perfTest('TST, lookup', function () { let match = 0; - for (const candidate of candidates) { + for (let candidate of candidates) { if (tree.has(candidate)) { match += 1; } @@ -1424,7 +1424,7 @@ suite.skip('TST, perf', function () { perfTest('TST, substr', function () { let match = 0; - for (const candidate of candidates) { + for (let candidate of candidates) { if (tree.findSubstr(candidate)) { match += 1; } @@ -1433,7 +1433,7 @@ suite.skip('TST, perf', function () { }); perfTest('TST, superstr', function () { - for (const candidate of candidates) { + for (let candidate of candidates) { tree.findSuperstr(candidate); } }); diff --git a/src/vs/base/test/common/marshalling.test.ts b/src/vs/base/test/common/marshalling.test.ts index c0851b7c9d..890a44f520 100644 --- a/src/vs/base/test/common/marshalling.test.ts +++ b/src/vs/base/test/common/marshalling.test.ts @@ -9,9 +9,9 @@ import { URI } from 'vs/base/common/uri'; suite('Marshalling', () => { test('RegExp', () => { - const value = /foo/img; - const raw = stringify(value); - const clone = parse(raw); + let value = /foo/img; + let raw = stringify(value); + let clone = parse(raw); assert.strictEqual(value.source, clone.source); assert.strictEqual(value.global, clone.global); diff --git a/src/vs/base/test/common/network.test.ts b/src/vs/base/test/common/network.test.ts index f395bb6765..fe16ecabfe 100644 --- a/src/vs/base/test/common/network.test.ts +++ b/src/vs/base/test/common/network.test.ts @@ -38,19 +38,19 @@ suite('network', () => { }); (isWeb ? test.skip : test)('FileAccess: query and fragment is dropped (native)', () => { - const originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' }); - const browserUri = FileAccess.asBrowserUri(originalFileUri); + let originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' }); + let browserUri = FileAccess.asBrowserUri(originalFileUri); assert.strictEqual(browserUri.query, ''); assert.strictEqual(browserUri.fragment, ''); }); (isWeb ? test.skip : test)('FileAccess: query and fragment is kept if URI is already of same scheme (native)', () => { - const originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' }); - const browserUri = FileAccess.asBrowserUri(originalFileUri.with({ scheme: Schemas.vscodeFileResource })); + let originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' }); + let browserUri = FileAccess.asBrowserUri(originalFileUri.with({ scheme: Schemas.vscodeFileResource })); assert.strictEqual(browserUri.query, 'foo=bar'); assert.strictEqual(browserUri.fragment, 'something'); - const fileUri = FileAccess.asFileUri(originalFileUri); + let fileUri = FileAccess.asFileUri(originalFileUri); assert.strictEqual(fileUri.query, 'foo=bar'); assert.strictEqual(fileUri.fragment, 'something'); }); diff --git a/src/vs/base/test/common/objects.test.ts b/src/vs/base/test/common/objects.test.ts index eb0bb86ad3..689427c27c 100644 --- a/src/vs/base/test/common/objects.test.ts +++ b/src/vs/base/test/common/objects.test.ts @@ -5,12 +5,12 @@ import * as assert from 'assert'; import * as objects from 'vs/base/common/objects'; -const check = (one: any, other: any, msg: string) => { +let check = (one: any, other: any, msg: string) => { assert(objects.equals(one, other), msg); assert(objects.equals(other, one), '[reverse] ' + msg); }; -const checkNot = (one: any, other: any, msg: string) => { +let checkNot = (one: any, other: any, msg: string) => { assert(!objects.equals(one, other), msg); assert(!objects.equals(other, one), '[reverse] ' + msg); }; @@ -55,7 +55,7 @@ suite('Objects', () => { test('mixin - array', function () { - const foo: any = {}; + let foo: any = {}; objects.mixin(foo, { bar: [1, 2, 3] }); assert(foo.bar); @@ -67,11 +67,11 @@ suite('Objects', () => { }); test('mixin - no overwrite', function () { - const foo: any = { + let foo: any = { bar: '123' }; - const bar: any = { + let bar: any = { bar: '456' }; @@ -81,8 +81,8 @@ suite('Objects', () => { }); test('cloneAndChange', () => { - const o1 = { something: 'hello' }; - const o = { + let o1 = { something: 'hello' }; + let o = { o1: o1, o2: o1 }; @@ -90,21 +90,21 @@ suite('Objects', () => { }); test('safeStringify', () => { - const obj1: any = { + let obj1: any = { friend: null }; - const obj2: any = { + let obj2: any = { friend: null }; obj1.friend = obj2; obj2.friend = obj1; - const arr: any = [1]; + let arr: any = [1]; arr.push(arr); - const circular: any = { + let circular: any = { a: 42, b: null, c: [ @@ -119,7 +119,7 @@ suite('Objects', () => { circular.b = circular; circular.d = arr; - const result = objects.safeStringify(circular); + let result = objects.safeStringify(circular); assert.deepStrictEqual(JSON.parse(result), { a: 42, @@ -137,7 +137,7 @@ suite('Objects', () => { }); test('distinct', () => { - const base = { + let base = { one: 'one', two: 2, three: { diff --git a/src/vs/base/test/common/observable.test.ts b/src/vs/base/test/common/observable.test.ts deleted file mode 100644 index 7f3120fc58..0000000000 --- a/src/vs/base/test/common/observable.test.ts +++ /dev/null @@ -1,507 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { Emitter } from 'vs/base/common/event'; -import { ISettableObservable, autorun, derived, ITransaction, observableFromEvent, observableValue, transaction } from 'vs/base/common/observable'; -import { BaseObservable, IObservable, IObserver } from 'vs/base/common/observableImpl/base'; - -suite('observable integration', () => { - test('basic observable + autorun', () => { - const log = new Log(); - const observable = observableValue('MyObservableValue', 0); - - autorun('MyAutorun', (reader) => { - log.log(`value: ${observable.read(reader)}`); - }); - assert.deepStrictEqual(log.getAndClearEntries(), ['value: 0']); - - observable.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), ['value: 1']); - - observable.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - transaction((tx) => { - observable.set(2, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable.set(3, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), ['value: 3']); - }); - - test('basic computed + autorun', () => { - const log = new Log(); - const observable1 = observableValue('MyObservableValue1', 0); - const observable2 = observableValue('MyObservableValue2', 0); - - const computed = derived('computed', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - autorun('MyAutorun', (reader) => { - log.log(`value: ${computed.read(reader)}`); - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 0 + 0 = 0', - 'value: 0', - ]); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 1 + 0 = 1', - 'value: 1', - ]); - - observable2.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 1 + 1 = 2', - 'value: 2', - ]); - - transaction((tx) => { - observable1.set(5, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable2.set(5, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 5 + 5 = 10', - 'value: 10', - ]); - - transaction((tx) => { - observable1.set(6, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable2.set(4, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), ['recompute: 6 + 4 = 10']); - }); - - test('read during transaction', () => { - const log = new Log(); - const observable1 = observableValue('MyObservableValue1', 0); - const observable2 = observableValue('MyObservableValue2', 0); - - const computed = derived('computed', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - autorun('MyAutorun', (reader) => { - log.log(`value: ${computed.read(reader)}`); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: 0 + 0 = 0', - 'value: 0', - ]); - - log.log(`computed is ${computed.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), ['computed is 0']); - - transaction((tx) => { - observable1.set(-1, tx); - log.log(`computed is ${computed.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: -1 + 0 = -1', - 'computed is -1', - ]); - - log.log(`computed is ${computed.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), ['computed is -1']); - - observable2.set(1, tx); - assert.deepStrictEqual(log.getAndClearEntries(), []); - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute: -1 + 1 = 0', - 'value: 0', - ]); - }); - - test('topological order', () => { - const log = new Log(); - const observable1 = observableValue('MyObservableValue1', 0); - const observable2 = observableValue('MyObservableValue2', 0); - - const computed1 = derived('computed1', (reader) => { - const value1 = observable1.read(reader); - const value2 = observable2.read(reader); - const sum = value1 + value2; - log.log(`recompute1: ${value1} + ${value2} = ${sum}`); - return sum; - }); - - const computed2 = derived('computed2', (reader) => { - const value1 = computed1.read(reader); - const value2 = observable1.read(reader); - const value3 = observable2.read(reader); - const sum = value1 + value2 + value3; - log.log(`recompute2: ${value1} + ${value2} + ${value3} = ${sum}`); - return sum; - }); - - const computed3 = derived('computed3', (reader) => { - const value1 = computed2.read(reader); - const value2 = observable1.read(reader); - const value3 = observable2.read(reader); - const sum = value1 + value2 + value3; - log.log(`recompute3: ${value1} + ${value2} + ${value3} = ${sum}`); - return sum; - }); - - autorun('MyAutorun', (reader) => { - log.log(`value: ${computed3.read(reader)}`); - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 0 + 0 = 0', - 'recompute2: 0 + 0 + 0 = 0', - 'recompute3: 0 + 0 + 0 = 0', - 'value: 0', - ]); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 1 + 0 = 1', - 'recompute2: 1 + 1 + 0 = 2', - 'recompute3: 2 + 1 + 0 = 3', - 'value: 3', - ]); - - transaction((tx) => { - observable1.set(2, tx); - log.log(`computed2: ${computed2.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 2 + 0 = 2', - 'recompute2: 2 + 2 + 0 = 4', - 'computed2: 4', - ]); - - observable1.set(3, tx); - log.log(`computed2: ${computed2.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 3 + 0 = 3', - 'recompute2: 3 + 3 + 0 = 6', - 'computed2: 6', - ]); - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute3: 6 + 3 + 0 = 9', - 'value: 9', - ]); - }); - - test('self-disposing autorun', () => { - const log = new Log(); - - const observable1 = new LoggingObservableValue('MyObservableValue1', 0, log); - const observable2 = new LoggingObservableValue('MyObservableValue2', 0, log); - const observable3 = new LoggingObservableValue('MyObservableValue3', 0, log); - - const d = autorun('autorun', (reader) => { - if (observable1.read(reader) >= 2) { - observable2.read(reader); - d.dispose(); - observable3.read(reader); - } - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'MyObservableValue1.firstObserverAdded', - 'MyObservableValue1.get', - ]); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'MyObservableValue1.set (value 1)', - 'MyObservableValue1.get', - ]); - - observable1.set(2, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'MyObservableValue1.set (value 2)', - 'MyObservableValue1.get', - 'MyObservableValue2.firstObserverAdded', - 'MyObservableValue2.get', - 'MyObservableValue1.lastObserverRemoved', - 'MyObservableValue2.lastObserverRemoved', - 'MyObservableValue3.get', - ]); - }); - - test('from event', () => { - const log = new Log(); - - let value = 0; - const eventEmitter = new Emitter(); - - let id = 0; - const observable = observableFromEvent( - (handler) => { - const curId = id++; - log.log(`subscribed handler ${curId}`); - const disposable = eventEmitter.event(handler); - - return { - dispose: () => { - log.log(`unsubscribed handler ${curId}`); - disposable.dispose(); - }, - }; - }, - () => { - log.log(`compute value ${value}`); - return value; - } - ); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - log.log(`get value: ${observable.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'compute value 0', - 'get value: 0', - ]); - - log.log(`get value: ${observable.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'compute value 0', - 'get value: 0', - ]); - - const shouldReadObservable = observableValue('shouldReadObservable', true); - - const autorunDisposable = autorun('MyAutorun', (reader) => { - if (shouldReadObservable.read(reader)) { - observable.read(reader); - log.log( - `autorun, should read: true, value: ${observable.read(reader)}` - ); - } else { - log.log(`autorun, should read: false`); - } - }); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'subscribed handler 0', - 'compute value 0', - 'autorun, should read: true, value: 0', - ]); - - log.log(`get value: ${observable.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), ['get value: 0']); - - value = 1; - eventEmitter.fire(); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'compute value 1', - 'autorun, should read: true, value: 1', - ]); - - shouldReadObservable.set(false, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'autorun, should read: false', - 'unsubscribed handler 0', - ]); - - shouldReadObservable.set(true, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'subscribed handler 1', - 'compute value 1', - 'autorun, should read: true, value: 1', - ]); - - autorunDisposable.dispose(); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'unsubscribed handler 1', - ]); - }); - - test('get without observers', () => { - // Maybe this scenario should not be supported. - - const log = new Log(); - const observable1 = observableValue('MyObservableValue1', 0); - const computed1 = derived('computed', (reader) => { - const value1 = observable1.read(reader); - const result = value1 % 3; - log.log(`recompute1: ${value1} % 3 = ${result}`); - return result; - }); - const computed2 = derived('computed', (reader) => { - const value1 = computed1.read(reader); - - const result = value1 * 2; - log.log(`recompute2: ${value1} * 2 = ${result}`); - return result; - }); - const computed3 = derived('computed', (reader) => { - const value1 = computed1.read(reader); - - const result = value1 * 3; - log.log(`recompute3: ${value1} * 3 = ${result}`); - return result; - }); - const computedSum = derived('computed', (reader) => { - const value1 = computed2.read(reader); - const value2 = computed3.read(reader); - - const result = value1 + value2; - log.log(`recompute4: ${value1} + ${value2} = ${result}`); - return result; - }); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - observable1.set(1, undefined); - assert.deepStrictEqual(log.getAndClearEntries(), []); - - log.log(`value: ${computedSum.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 1 % 3 = 1', - 'recompute2: 1 * 2 = 2', - 'recompute3: 1 * 3 = 3', - 'recompute4: 2 + 3 = 5', - 'value: 5', - ]); - - log.log(`value: ${computedSum.get()}`); - assert.deepStrictEqual(log.getAndClearEntries(), [ - 'recompute1: 1 % 3 = 1', - 'recompute2: 1 * 2 = 2', - 'recompute3: 1 * 3 = 3', - 'recompute4: 2 + 3 = 5', - 'value: 5', - ]); - }); -}); - -suite('observable details', () => { - test('1', () => { - const log = new Log(); - - const shouldReadObservable = observableValue('shouldReadObservable', true); - const observable = new LoggingObservableValue('observable', 0, log); - const computed = derived('test', reader => { - if (shouldReadObservable.read(reader)) { - return observable.read(reader) * 2; - } - return 1; - }); - autorun('test', reader => { - const value = computed.read(reader); - log.log(`autorun: ${value}`); - }); - - assert.deepStrictEqual(log.getAndClearEntries(), (["observable.firstObserverAdded", "observable.get", "autorun: 0"])); - - transaction(tx => { - observable.set(1, tx); - assert.deepStrictEqual(log.getAndClearEntries(), (["observable.set (value 1)"])); - - shouldReadObservable.set(false, tx); - assert.deepStrictEqual(log.getAndClearEntries(), ([])); - - computed.get(); - assert.deepStrictEqual(log.getAndClearEntries(), (["observable.lastObserverRemoved"])); - }); - assert.deepStrictEqual(log.getAndClearEntries(), (["autorun: 1"])); - }); -}); - -export class LoggingObserver implements IObserver { - private count = 0; - - constructor(public readonly debugName: string, private readonly log: Log) { - } - - beginUpdate(observable: IObservable): void { - this.count++; - this.log.log(`${this.debugName}.beginUpdate (count ${this.count})`); - } - handleChange(observable: IObservable, change: TChange): void { - this.log.log(`${this.debugName}.handleChange (count ${this.count})`); - } - endUpdate(observable: IObservable): void { - this.log.log(`${this.debugName}.endUpdate (count ${this.count})`); - this.count--; - } -} - -export class LoggingObservableValue - extends BaseObservable - implements ISettableObservable -{ - private value: T; - - constructor(public readonly debugName: string, initialValue: T, private readonly log: Log) { - super(); - this.value = initialValue; - } - - protected override onFirstObserverAdded(): void { - this.log.log(`${this.debugName}.firstObserverAdded`); - } - - protected override onLastObserverRemoved(): void { - this.log.log(`${this.debugName}.lastObserverRemoved`); - } - - public get(): T { - this.log.log(`${this.debugName}.get`); - return this.value; - } - - public set(value: T, tx: ITransaction | undefined, change: TChange): void { - if (this.value === value) { - return; - } - - if (!tx) { - transaction((tx) => { - this.set(value, tx, change); - }, () => `Setting ${this.debugName}`); - return; - } - - this.log.log(`${this.debugName}.set (value ${value})`); - - this.value = value; - - for (const observer of this.observers) { - tx.updateObserver(observer, this); - observer.handleChange(this, change); - } - } - - override toString(): string { - return `${this.debugName}: ${this.value}`; - } -} - -class Log { - private readonly entries: string[] = []; - public log(message: string): void { - this.entries.push(message); - } - - public getAndClearEntries(): string[] { - const entries = [...this.entries]; - this.entries.length = 0; - return entries; - } -} diff --git a/src/vs/base/test/common/processes.test.ts b/src/vs/base/test/common/processes.test.ts index 8d9badfa6c..c2dc9f61c1 100644 --- a/src/vs/base/test/common/processes.test.ts +++ b/src/vs/base/test/common/processes.test.ts @@ -8,7 +8,7 @@ import * as processes from 'vs/base/common/processes'; suite('Processes', () => { test('sanitizeProcessEnvironment', () => { - const env = { + let env = { FOO: 'bar', ELECTRON_ENABLE_STACK_DUMPING: 'x', ELECTRON_ENABLE_LOGGING: 'x', diff --git a/src/vs/base/test/common/resourceTree.test.ts b/src/vs/base/test/common/resourceTree.test.ts index 92ac13f1bb..e6da572269 100644 --- a/src/vs/base/test/common/resourceTree.test.ts +++ b/src/vs/base/test/common/resourceTree.test.ts @@ -19,11 +19,11 @@ suite('ResourceTree', function () { tree.add(URI.file('/foo/bar.txt'), 'bar contents'); assert.strictEqual(tree.root.childrenCount, 1); - const foo = tree.root.get('foo')!; + let foo = tree.root.get('foo')!; assert(foo); assert.strictEqual(foo.childrenCount, 1); - const bar = foo.get('bar.txt')!; + let bar = foo.get('bar.txt')!; assert(bar); assert.strictEqual(bar.element, 'bar contents'); diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index 998060cc41..ec48ad8e83 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -235,14 +235,14 @@ suite('Resources', () => { }); function assertEqualURI(actual: URI, expected: URI, message?: string, ignoreCase?: boolean) { - const util = ignoreCase ? extUriIgnorePathCase : extUri; + let util = ignoreCase ? extUriIgnorePathCase : extUri; if (!util.isEqual(expected, actual)) { assert.strictEqual(actual.toString(), expected.toString(), message); } } function assertRelativePath(u1: URI, u2: URI, expectedPath: string | undefined, ignoreJoin?: boolean, ignoreCase?: boolean) { - const util = ignoreCase ? extUriIgnorePathCase : extUri; + let util = ignoreCase ? extUriIgnorePathCase : extUri; assert.strictEqual(util.relativePath(u1, u2), expectedPath, `from ${u1.toString()} to ${u2.toString()}`); if (expectedPath !== undefined && !ignoreJoin) { @@ -350,7 +350,7 @@ suite('Resources', () => { function assertIsEqual(u1: URI, u2: URI, ignoreCase: boolean | undefined, expected: boolean) { - const util = ignoreCase ? extUriIgnorePathCase : extUri; + let util = ignoreCase ? extUriIgnorePathCase : extUri; assert.strictEqual(util.isEqual(u1, u2), expected, `${u1.toString()}${expected ? '===' : '!=='}${u2.toString()}`); assert.strictEqual(util.compare(u1, u2) === 0, expected); @@ -363,16 +363,16 @@ suite('Resources', () => { test('isEqual', () => { - const fileURI = isWindows ? URI.file('c:\\foo\\bar') : URI.file('/foo/bar'); - const fileURI2 = isWindows ? URI.file('C:\\foo\\Bar') : URI.file('/foo/Bar'); + let fileURI = isWindows ? URI.file('c:\\foo\\bar') : URI.file('/foo/bar'); + let fileURI2 = isWindows ? URI.file('C:\\foo\\Bar') : URI.file('/foo/Bar'); assertIsEqual(fileURI, fileURI, true, true); assertIsEqual(fileURI, fileURI, false, true); assertIsEqual(fileURI, fileURI, undefined, true); assertIsEqual(fileURI, fileURI2, true, true); assertIsEqual(fileURI, fileURI2, false, false); - const fileURI3 = URI.parse('foo://server:453/foo/bar'); - const fileURI4 = URI.parse('foo://server:453/foo/Bar'); + let fileURI3 = URI.parse('foo://server:453/foo/bar'); + let fileURI4 = URI.parse('foo://server:453/foo/Bar'); assertIsEqual(fileURI3, fileURI3, true, true); assertIsEqual(fileURI3, fileURI3, false, true); assertIsEqual(fileURI3, fileURI3, undefined, true); @@ -387,8 +387,8 @@ suite('Resources', () => { assertIsEqual(URI.parse('foo://server/foo'), URI.parse('foo://server/foo/'), true, false); assertIsEqual(URI.parse('foo://server/foo'), URI.parse('foo://server/foo?'), true, true); - const fileURI5 = URI.parse('foo://server:453/foo/bar?q=1'); - const fileURI6 = URI.parse('foo://server:453/foo/bar#xy'); + let fileURI5 = URI.parse('foo://server:453/foo/bar?q=1'); + let fileURI6 = URI.parse('foo://server:453/foo/bar#xy'); assertIsEqual(fileURI5, fileURI5, true, true); assertIsEqual(fileURI5, fileURI3, true, false); @@ -399,9 +399,9 @@ suite('Resources', () => { test('isEqualOrParent', () => { - const fileURI = isWindows ? URI.file('c:\\foo\\bar') : URI.file('/foo/bar'); - const fileURI2 = isWindows ? URI.file('c:\\foo') : URI.file('/foo'); - const fileURI2b = isWindows ? URI.file('C:\\Foo\\') : URI.file('/Foo/'); + let fileURI = isWindows ? URI.file('c:\\foo\\bar') : URI.file('/foo/bar'); + let fileURI2 = isWindows ? URI.file('c:\\foo') : URI.file('/foo'); + let fileURI2b = isWindows ? URI.file('C:\\Foo\\') : URI.file('/Foo/'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI, fileURI), true, '1'); assert.strictEqual(extUri.isEqualOrParent(fileURI, fileURI), true, '2'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI, fileURI2), true, '3'); @@ -412,9 +412,9 @@ suite('Resources', () => { assert.strictEqual(extUri.isEqualOrParent(fileURI2, fileURI), false, '7'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI2b, fileURI2), true, '8'); - const fileURI3 = URI.parse('foo://server:453/foo/bar/goo'); - const fileURI4 = URI.parse('foo://server:453/foo/'); - const fileURI5 = URI.parse('foo://server:453/foo'); + let fileURI3 = URI.parse('foo://server:453/foo/bar/goo'); + let fileURI4 = URI.parse('foo://server:453/foo/'); + let fileURI5 = URI.parse('foo://server:453/foo'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI3, fileURI3, true), true, '11'); assert.strictEqual(extUri.isEqualOrParent(fileURI3, fileURI3), true, '12'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI3, fileURI4, true), true, '13'); @@ -422,8 +422,8 @@ suite('Resources', () => { assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI3, fileURI, true), false, '15'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI5, fileURI5, true), true, '16'); - const fileURI6 = URI.parse('foo://server:453/foo?q=1'); - const fileURI7 = URI.parse('foo://server:453/foo/bar?q=1'); + let fileURI6 = URI.parse('foo://server:453/foo?q=1'); + let fileURI7 = URI.parse('foo://server:453/foo/bar?q=1'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI6, fileURI5), false, '17'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI6, fileURI6), true, '18'); assert.strictEqual(extUriIgnorePathCase.isEqualOrParent(fileURI7, fileURI6), true, '19'); diff --git a/src/vs/base/test/common/scrollable.test.ts b/src/vs/base/test/common/scrollable.test.ts index 2314330145..4607555375 100644 --- a/src/vs/base/test/common/scrollable.test.ts +++ b/src/vs/base/test/common/scrollable.test.ts @@ -33,8 +33,8 @@ suite('SmoothScrollingOperation', () => { const LINE_HEIGHT = 20; function extractLines(scrollable: TestSmoothScrollingOperation, now: number): [number, number] { - const scrollTop = scrollable.testTick(now).scrollTop; - const scrollBottom = scrollTop + VIEWPORT_HEIGHT; + let scrollTop = scrollable.testTick(now).scrollTop; + let scrollBottom = scrollTop + VIEWPORT_HEIGHT; const startLineNumber = Math.floor(scrollTop / LINE_HEIGHT); const endLineNumber = Math.ceil(scrollBottom / LINE_HEIGHT); @@ -45,8 +45,7 @@ suite('SmoothScrollingOperation', () => { function simulateSmoothScroll(from: number, to: number): [number, number][] { const scrollable = new TestSmoothScrollingOperation(from, to, VIEWPORT_HEIGHT, 0, ANIMATION_DURATION); - const result: [number, number][] = []; - let resultLen = 0; + let result: [number, number][] = [], resultLen = 0; result[resultLen++] = extractLines(scrollable, 0); result[resultLen++] = extractLines(scrollable, 25); result[resultLen++] = extractLines(scrollable, 50); diff --git a/src/vs/base/test/common/skipList.test.ts b/src/vs/base/test/common/skipList.test.ts index 528d2eeb24..f0ce03ffd9 100644 --- a/src/vs/base/test/common/skipList.test.ts +++ b/src/vs/base/test/common/skipList.test.ts @@ -15,10 +15,10 @@ suite('SkipList', function () { assert.strictEqual(list.size, expected.length); assert.deepStrictEqual([...list.values()], expected); - const valuesFromEntries = [...list.entries()].map(entry => entry[1]); + let valuesFromEntries = [...list.entries()].map(entry => entry[1]); assert.deepStrictEqual(valuesFromEntries, expected); - const valuesFromIter = [...list].map(entry => entry[1]); + let valuesFromIter = [...list].map(entry => entry[1]); assert.deepStrictEqual(valuesFromIter, expected); let i = 0; @@ -32,10 +32,10 @@ suite('SkipList', function () { assert.strictEqual(list.size, expected.length); assert.deepStrictEqual([...list.keys()], expected); - const keysFromEntries = [...list.entries()].map(entry => entry[0]); + let keysFromEntries = [...list.entries()].map(entry => entry[0]); assert.deepStrictEqual(keysFromEntries, expected); - const keysFromIter = [...list].map(entry => entry[0]); + let keysFromIter = [...list].map(entry => entry[0]); assert.deepStrictEqual(keysFromIter, expected); let i = 0; @@ -46,7 +46,7 @@ suite('SkipList', function () { } test('set/get/delete', function () { - const list = new SkipList((a, b) => a - b); + let list = new SkipList((a, b) => a - b); assert.strictEqual(list.get(3), undefined); list.set(3, 1); @@ -74,7 +74,7 @@ suite('SkipList', function () { }); test('Figure 3', function () { - const list = new SkipList((a, b) => a - b); + let list = new SkipList((a, b) => a - b); list.set(3, true); list.set(6, true); list.set(7, true); @@ -92,7 +92,7 @@ suite('SkipList', function () { }); test('capacity max', function () { - const list = new SkipList((a, b) => a - b, 10); + let list = new SkipList((a, b) => a - b, 10); list.set(1, true); list.set(2, true); list.set(3, true); @@ -132,7 +132,7 @@ suite('SkipList', function () { } function delArraySorted(array: number[], element: number) { - const idx = binarySearch(array, element, cmp); + let idx = binarySearch(array, element, cmp); if (idx >= 0) { // array = array.slice(0, idx).concat(array.slice(idx)); array.splice(idx, 1); @@ -147,13 +147,13 @@ suite('SkipList', function () { const max = 2 ** 16; const values = new Set(); for (let i = 0; i < max; i++) { - const value = Math.floor(Math.random() * max); + let value = Math.floor(Math.random() * max); values.add(value); } console.log(values.size); // init - const list = new SkipList(cmp, max); + let list = new SkipList(cmp, max); let sw = new StopWatch(true); values.forEach(value => list.set(value, true)); sw.stop(); @@ -166,9 +166,9 @@ suite('SkipList', function () { // get sw = new StopWatch(true); - const someValues = [...values].slice(0, values.size / 4); + let someValues = [...values].slice(0, values.size / 4); someValues.forEach(key => { - const value = list.get(key); // find + let value = list.get(key); // find console.assert(value, '[LIST] must have ' + key); list.get(-key); // miss }); @@ -176,7 +176,7 @@ suite('SkipList', function () { console.log(`[LIST] retrieve ${sw.elapsed()}ms (${(sw.elapsed() / (someValues.length * 2)).toPrecision(4)}ms/op)`); sw = new StopWatch(true); someValues.forEach(key => { - const idx = binarySearch(array, key, cmp); // find + let idx = binarySearch(array, key, cmp); // find console.assert(idx >= 0, '[ARRAY] must have ' + key); binarySearch(array, -key, cmp); // miss }); diff --git a/src/vs/base/test/common/stream.test.ts b/src/vs/base/test/common/stream.test.ts index 82d923caa3..fe4ff668b8 100644 --- a/src/vs/base/test/common/stream.test.ts +++ b/src/vs/base/test/common/stream.test.ts @@ -155,10 +155,10 @@ suite('Stream', () => { res = stream.write('3'); assert.ok(!res); - const promise1 = stream.write('4'); + let promise1 = stream.write('4'); assert.ok(promise1 instanceof Promise); - const promise2 = stream.write('5'); + let promise2 = stream.write('5'); assert.ok(promise2 instanceof Promise); let drained1 = false; diff --git a/src/vs/base/test/common/stripComments.test.ts b/src/vs/base/test/common/stripComments.test.ts index 38f160e371..f557f7e3a3 100644 --- a/src/vs/base/test/common/stripComments.test.ts +++ b/src/vs/base/test/common/stripComments.test.ts @@ -122,26 +122,4 @@ suite('Strip Comments', () => { ].join('\n'); assert.strictEqual(stripComments(content), expected); }); - test('Trailing comma in object', () => { - const content: string = [ - "{", - ` "a": 10,`, - "}" - ].join('\n'); - const expected: string = [ - "{", - ` "a": 10`, - "}" - ].join('\n'); - assert.strictEqual(stripComments(content), expected); - }); - test('Trailing comma in array', () => { - const content: string = [ - `[ "a", "b", "c", ]` - ].join('\n'); - const expected: string = [ - `[ "a", "b", "c" ]` - ].join('\n'); - assert.strictEqual(stripComments(content), expected); - }); }); diff --git a/src/vs/base/test/common/timeTravelScheduler.ts b/src/vs/base/test/common/timeTravelScheduler.ts index ea6dd99a97..298bd13fe3 100644 --- a/src/vs/base/test/common/timeTravelScheduler.ts +++ b/src/vs/base/test/common/timeTravelScheduler.ts @@ -5,7 +5,6 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; -import { setTimeout0, setTimeout0IsFaster } from 'vs/base/common/platform'; interface PriorityQueue { length: number; @@ -178,8 +177,6 @@ export class AsyncSchedulerProcessor extends Disposable { Promise.resolve().then(() => { if (this.useSetImmediate) { originalGlobalValues.setImmediate(() => this.process()); - } else if (setTimeout0IsFaster) { - setTimeout0(() => this.process()); } else { originalGlobalValues.setTimeout(() => this.process()); } @@ -193,7 +190,7 @@ export class AsyncSchedulerProcessor extends Disposable { if (this.history.length >= this.maxTaskCount && this.scheduler.hasScheduledTasks) { const lastTasks = this._history.slice(Math.max(0, this.history.length - 10)).map(h => `${h.source.toString()}: ${h.source.stackTrace}`); - const e = new Error(`Queue did not get empty after processing ${this.history.length} items. These are the last ${lastTasks.length} scheduled tasks:\n${lastTasks.join('\n\n\n')}`); + let e = new Error(`Queue did not get empty after processing ${this.history.length} items. These are the last ${lastTasks.length} scheduled tasks:\n${lastTasks.join('\n\n\n')}`); this.lastError = e; throw e; } @@ -371,7 +368,7 @@ function createDateClass(scheduler: Scheduler): DateConstructor { return new (OriginalDate as any)(...args); } - for (const prop in OriginalDate) { + for (let prop in OriginalDate) { if (OriginalDate.hasOwnProperty(prop)) { (SchedulerDate as any)[prop] = (OriginalDate as any)[prop]; } diff --git a/src/vs/base/test/common/troubleshooting.ts b/src/vs/base/test/common/troubleshooting.ts index e9296e442c..1aa4798ed4 100644 --- a/src/vs/base/test/common/troubleshooting.ts +++ b/src/vs/base/test/common/troubleshooting.ts @@ -47,9 +47,13 @@ export function endTrackingDisposables(): void { } export function beginLoggingFS(withStacks: boolean = false): void { - (self).beginLoggingFS?.(withStacks); + if ((self).beginLoggingFS) { + (self).beginLoggingFS(withStacks); + } } export function endLoggingFS(): void { - (self).endLoggingFS?.(); + if ((self).endLoggingFS) { + (self).endLoggingFS(); + } } diff --git a/src/vs/base/test/common/uri.test.ts b/src/vs/base/test/common/uri.test.ts index 7c9b808f90..11e5076f7f 100644 --- a/src/vs/base/test/common/uri.test.ts +++ b/src/vs/base/test/common/uri.test.ts @@ -88,7 +88,7 @@ suite('URI', () => { }); test('with, identity', () => { - const uri = URI.parse('foo:bar/path'); + let uri = URI.parse('foo:bar/path'); let uri2 = uri.with(null!); assert.ok(uri === uri2); @@ -121,7 +121,7 @@ suite('URI', () => { }); test('with, validation', () => { - const uri = URI.parse('foo:bar/path'); + let uri = URI.parse('foo:bar/path'); assert.throws(() => uri.with({ scheme: 'fai:l' })); assert.throws(() => uri.with({ scheme: 'fäil' })); assert.throws(() => uri.with({ authority: 'fail' })); @@ -281,14 +281,14 @@ suite('URI', () => { }); test('VSCode URI module\'s driveLetterPath regex is incorrect, #32961', function () { - const uri = URI.parse('file:///_:/path'); + let uri = URI.parse('file:///_:/path'); assert.strictEqual(uri.fsPath, isWindows ? '\\_:\\path' : '/_:/path'); }); test('URI#file, no path-is-uri check', () => { // we don't complain here - const value = URI.file('file://path/to/file'); + let value = URI.file('file://path/to/file'); assert.strictEqual(value.scheme, 'file'); assert.strictEqual(value.authority, ''); assert.strictEqual(value.path, '/file://path/to/file'); @@ -475,10 +475,10 @@ suite('URI', () => { }); test.skip('Links in markdown are broken if url contains encoded parameters #79474', function () { - const strIn = 'https://myhost.com/Redirect?url=http%3A%2F%2Fwww.bing.com%3Fsearch%3Dtom'; - const uri1 = URI.parse(strIn); - const strOut = uri1.toString(); - const uri2 = URI.parse(strOut); + let strIn = 'https://myhost.com/Redirect?url=http%3A%2F%2Fwww.bing.com%3Fsearch%3Dtom'; + let uri1 = URI.parse(strIn); + let strOut = uri1.toString(); + let uri2 = URI.parse(strOut); assert.strictEqual(uri1.scheme, uri2.scheme); assert.strictEqual(uri1.authority, uri2.authority); @@ -489,10 +489,10 @@ suite('URI', () => { }); test.skip('Uri#parse can break path-component #45515', function () { - const strIn = 'https://firebasestorage.googleapis.com/v0/b/brewlangerie.appspot.com/o/products%2FzVNZkudXJyq8bPGTXUxx%2FBetterave-Sesame.jpg?alt=media&token=0b2310c4-3ea6-4207-bbde-9c3710ba0437'; - const uri1 = URI.parse(strIn); - const strOut = uri1.toString(); - const uri2 = URI.parse(strOut); + let strIn = 'https://firebasestorage.googleapis.com/v0/b/brewlangerie.appspot.com/o/products%2FzVNZkudXJyq8bPGTXUxx%2FBetterave-Sesame.jpg?alt=media&token=0b2310c4-3ea6-4207-bbde-9c3710ba0437'; + let uri1 = URI.parse(strIn); + let strOut = uri1.toString(); + let uri2 = URI.parse(strOut); assert.strictEqual(uri1.scheme, uri2.scheme); assert.strictEqual(uri1.authority, uri2.authority); @@ -516,9 +516,9 @@ suite('URI', () => { // console.profile(); // let c = 100000; // while (c-- > 0) { - for (const value of values) { - const data = value.toJSON() as UriComponents; - const clone = URI.revive(data); + for (let value of values) { + let data = value.toJSON() as UriComponents; + let clone = URI.revive(data); assert.strictEqual(clone.scheme, value.scheme); assert.strictEqual(clone.authority, value.authority); diff --git a/src/vs/base/test/node/css.build.test.ts b/src/vs/base/test/node/css.build.test.ts deleted file mode 100644 index 65231061d3..0000000000 --- a/src/vs/base/test/node/css.build.test.ts +++ /dev/null @@ -1,313 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import * as assert from 'assert'; -import { CSSPluginUtilities, rewriteUrls } from 'vs/css.build'; - -suite('CSSPlugin', () => { - - test('Utilities.pathOf', () => { - assert.strictEqual(CSSPluginUtilities.pathOf(''), ''); - assert.strictEqual(CSSPluginUtilities.pathOf('/a'), '/'); - assert.strictEqual(CSSPluginUtilities.pathOf('a/b/c.css'), 'a/b/'); - assert.strictEqual(CSSPluginUtilities.pathOf('a'), ''); - assert.strictEqual(CSSPluginUtilities.pathOf('a.com/a.css'), 'a.com/'); - assert.strictEqual(CSSPluginUtilities.pathOf('http://a.com/a.css'), 'http://a.com/'); - assert.strictEqual(CSSPluginUtilities.pathOf('https://a.com/a.css'), 'https://a.com/'); - assert.strictEqual(CSSPluginUtilities.pathOf('http://a.com/a/b/c.css'), 'http://a.com/a/b/'); - assert.strictEqual(CSSPluginUtilities.pathOf('https://a.com/a/b/c.css'), 'https://a.com/a/b/'); - assert.strictEqual(CSSPluginUtilities.pathOf('/a.css'), '/'); - assert.strictEqual(CSSPluginUtilities.pathOf('/a/b/c.css'), '/a/b/'); - }); - - test('Utilities.joinPaths', () => { - function mytest(a: string, b: string, expected: string) { - assert.strictEqual(CSSPluginUtilities.joinPaths(a, b), expected, '<' + a + '> + <' + b + '> = <' + expected + '>'); - } - mytest('', 'a.css', 'a.css'); - mytest('', './a.css', 'a.css'); - mytest('', '././././a.css', 'a.css'); - mytest('', './../a.css', '../a.css'); - mytest('', '../../a.css', '../../a.css'); - mytest('', '../../a/b/c.css', '../../a/b/c.css'); - mytest('/', 'a.css', '/a.css'); - mytest('/', './a.css', '/a.css'); - mytest('/', '././././a.css', '/a.css'); - mytest('/', './../a.css', '/a.css'); - mytest('/', '../../a.css', '/a.css'); - mytest('/', '../../a/b/c.css', '/a/b/c.css'); - mytest('x/y/z/', 'a.css', 'x/y/z/a.css'); - mytest('x/y/z/', './a.css', 'x/y/z/a.css'); - mytest('x/y/z/', '././././a.css', 'x/y/z/a.css'); - mytest('x/y/z/', './../a.css', 'x/y/a.css'); - mytest('x/y/z/', '../../a.css', 'x/a.css'); - mytest('x/y/z/', '../../a/b/c.css', 'x/a/b/c.css'); - - mytest('//a.com/', 'a.css', '//a.com/a.css'); - mytest('//a.com/', './a.css', '//a.com/a.css'); - mytest('//a.com/', '././././a.css', '//a.com/a.css'); - mytest('//a.com/', './../a.css', '//a.com/a.css'); - mytest('//a.com/', '../../a.css', '//a.com/a.css'); - mytest('//a.com/', '../../a/b/c.css', '//a.com/a/b/c.css'); - mytest('//a.com/x/y/z/', 'a.css', '//a.com/x/y/z/a.css'); - mytest('//a.com/x/y/z/', './a.css', '//a.com/x/y/z/a.css'); - mytest('//a.com/x/y/z/', '././././a.css', '//a.com/x/y/z/a.css'); - mytest('//a.com/x/y/z/', './../a.css', '//a.com/x/y/a.css'); - mytest('//a.com/x/y/z/', '../../a.css', '//a.com/x/a.css'); - mytest('//a.com/x/y/z/', '../../a/b/c.css', '//a.com/x/a/b/c.css'); - - mytest('http://a.com/', 'a.css', 'http://a.com/a.css'); - mytest('http://a.com/', './a.css', 'http://a.com/a.css'); - mytest('http://a.com/', '././././a.css', 'http://a.com/a.css'); - mytest('http://a.com/', './../a.css', 'http://a.com/a.css'); - mytest('http://a.com/', '../../a.css', 'http://a.com/a.css'); - mytest('http://a.com/', '../../a/b/c.css', 'http://a.com/a/b/c.css'); - mytest('http://a.com/x/y/z/', 'a.css', 'http://a.com/x/y/z/a.css'); - mytest('http://a.com/x/y/z/', './a.css', 'http://a.com/x/y/z/a.css'); - mytest('http://a.com/x/y/z/', '././././a.css', 'http://a.com/x/y/z/a.css'); - mytest('http://a.com/x/y/z/', './../a.css', 'http://a.com/x/y/a.css'); - mytest('http://a.com/x/y/z/', '../../a.css', 'http://a.com/x/a.css'); - mytest('http://a.com/x/y/z/', '../../a/b/c.css', 'http://a.com/x/a/b/c.css'); - - mytest('https://a.com/', 'a.css', 'https://a.com/a.css'); - mytest('https://a.com/', './a.css', 'https://a.com/a.css'); - mytest('https://a.com/', '././././a.css', 'https://a.com/a.css'); - mytest('https://a.com/', './../a.css', 'https://a.com/a.css'); - mytest('https://a.com/', '../../a.css', 'https://a.com/a.css'); - mytest('https://a.com/', '../../a/b/c.css', 'https://a.com/a/b/c.css'); - mytest('https://a.com/x/y/z/', 'a.css', 'https://a.com/x/y/z/a.css'); - mytest('https://a.com/x/y/z/', './a.css', 'https://a.com/x/y/z/a.css'); - mytest('https://a.com/x/y/z/', '././././a.css', 'https://a.com/x/y/z/a.css'); - mytest('https://a.com/x/y/z/', './../a.css', 'https://a.com/x/y/a.css'); - mytest('https://a.com/x/y/z/', '../../a.css', 'https://a.com/x/a.css'); - mytest('https://a.com/x/y/z/', '../../a/b/c.css', 'https://a.com/x/a/b/c.css'); - }); - - test('Utilities.commonPrefix', () => { - function mytest(a: string, b: string, expected: string) { - assert.strictEqual(CSSPluginUtilities.commonPrefix(a, b), expected, 'prefix(<' + a + '>, <' + b + '>) = <' + expected + '>'); - assert.strictEqual(CSSPluginUtilities.commonPrefix(b, a), expected, 'prefix(<' + b + '>, <' + a + '>) = <' + expected + '>'); - } - mytest('', '', ''); - mytest('x', '', ''); - mytest('x', 'x', 'x'); - mytest('aaaa', 'aaaa', 'aaaa'); - mytest('aaaaxyz', 'aaaa', 'aaaa'); - mytest('aaaaxyz', 'aaaatuv', 'aaaa'); - }); - - test('Utilities.commonFolderPrefix', () => { - function mytest(a: string, b: string, expected: string) { - assert.strictEqual(CSSPluginUtilities.commonFolderPrefix(a, b), expected, 'folderPrefix(<' + a + '>, <' + b + '>) = <' + expected + '>'); - assert.strictEqual(CSSPluginUtilities.commonFolderPrefix(b, a), expected, 'folderPrefix(<' + b + '>, <' + a + '>) = <' + expected + '>'); - } - mytest('', '', ''); - mytest('x', '', ''); - mytest('x', 'x', ''); - mytest('aaaa', 'aaaa', ''); - mytest('aaaaxyz', 'aaaa', ''); - mytest('aaaaxyz', 'aaaatuv', ''); - mytest('/', '/', '/'); - mytest('x/', '', ''); - mytest('x/', 'x/', 'x/'); - mytest('aaaa/', 'aaaa/', 'aaaa/'); - mytest('aaaa/axyz', 'aaaa/a', 'aaaa/'); - mytest('aaaa/axyz', 'aaaa/atuv', 'aaaa/'); - }); - - test('Utilities.relativePath', () => { - function mytest(a: string, b: string, expected: string) { - assert.strictEqual(CSSPluginUtilities.relativePath(a, b), expected, 'relativePath(<' + a + '>, <' + b + '>) = <' + expected + '>'); - } - mytest('', '', ''); - mytest('x', '', ''); - mytest('x', 'x', 'x'); - mytest('aaaa', 'aaaa', 'aaaa'); - mytest('aaaaxyz', 'aaaa', 'aaaa'); - mytest('aaaaxyz', 'aaaatuv', 'aaaatuv'); - - mytest('x/y/aaaaxyz', 'x/aaaatuv', '../aaaatuv'); - mytest('x/y/aaaaxyz', 'x/y/aaaatuv', 'aaaatuv'); - mytest('z/t/aaaaxyz', 'x/y/aaaatuv', '../../x/y/aaaatuv'); - mytest('aaaaxyz', 'x/y/aaaatuv', 'x/y/aaaatuv'); - - mytest('a', '/a', '/a'); - mytest('/', '/a', '/a'); - mytest('/a/b/c', '/a/b/c', '/a/b/c'); - mytest('/a/b', '/a/b/c/d', '/a/b/c/d'); - - mytest('a', 'http://a', 'http://a'); - mytest('/', 'http://a', 'http://a'); - mytest('/a/b/c', 'http://a/b/c', 'http://a/b/c'); - mytest('/a/b', 'http://a/b/c/d', 'http://a/b/c/d'); - - mytest('a', 'https://a', 'https://a'); - mytest('/', 'https://a', 'https://a'); - mytest('/a/b/c', 'https://a/b/c', 'https://a/b/c'); - mytest('/a/b', 'https://a/b/c/d', 'https://a/b/c/d'); - - mytest('x/', '', '../'); - mytest('x/', '', '../'); - mytest('x/', 'x/', ''); - mytest('x/a', 'x/a', 'a'); - }); - - test('Utilities.rewriteUrls', () => { - function mytest(originalFile: string, newFile: string, url: string, expected: string) { - assert.strictEqual(rewriteUrls(originalFile, newFile, 'sel { background:url(\'' + url + '\'); }'), 'sel { background:url(' + expected + '); }'); - assert.strictEqual(rewriteUrls(originalFile, newFile, 'sel { background:url(\"' + url + '\"); }'), 'sel { background:url(' + expected + '); }'); - assert.strictEqual(rewriteUrls(originalFile, newFile, 'sel { background:url(' + url + '); }'), 'sel { background:url(' + expected + '); }'); - } - - // img/img.png - mytest('a.css', 'b.css', 'img/img.png', 'img/img.png'); - mytest('a.css', 't/b.css', 'img/img.png', '../img/img.png'); - mytest('a.css', 'x/y/b.css', 'img/img.png', '../../img/img.png'); - mytest('x/a.css', 'b.css', 'img/img.png', 'x/img/img.png'); - mytest('x/y/a.css', 'b.css', 'img/img.png', 'x/y/img/img.png'); - mytest('x/y/a.css', 't/u/b.css', 'img/img.png', '../../x/y/img/img.png'); - mytest('x/y/a.css', 'x/u/b.css', 'img/img.png', '../y/img/img.png'); - mytest('x/y/a.css', 'x/y/b.css', 'img/img.png', 'img/img.png'); - mytest('/a.css', 'b.css', 'img/img.png', '/img/img.png'); - mytest('/a.css', 'x/b.css', 'img/img.png', '/img/img.png'); - mytest('/a.css', 'x/y/b.css', 'img/img.png', '/img/img.png'); - mytest('/x/a.css', 'b.css', 'img/img.png', '/x/img/img.png'); - mytest('/x/a.css', 'x/b.css', 'img/img.png', '/x/img/img.png'); - mytest('/x/a.css', 'x/y/b.css', 'img/img.png', '/x/img/img.png'); - mytest('/x/y/a.css', 'b.css', 'img/img.png', '/x/y/img/img.png'); - mytest('/x/y/a.css', 'x/b.css', 'img/img.png', '/x/y/img/img.png'); - mytest('/x/y/a.css', 'x/y/b.css', 'img/img.png', '/x/y/img/img.png'); - mytest('/a.css', '/b.css', 'img/img.png', '/img/img.png'); - mytest('/a.css', '/b.css', 'img/img.png', '/img/img.png'); - mytest('/x/a.css', '/b.css', 'img/img.png', '/x/img/img.png'); - mytest('/x/a.css', '/x/b.css', 'img/img.png', '/x/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'b.css', 'img/img.png', 'http://www.example.com/x/y/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'http://www.example2.com/b.css', 'img/img.png', 'http://www.example.com/x/y/img/img.png'); - mytest('https://www.example.com/x/y/a.css', 'b.css', 'img/img.png', 'https://www.example.com/x/y/img/img.png'); - - // ../img/img.png - mytest('a.css', 'b.css', '../img/img.png', '../img/img.png'); - mytest('a.css', 't/b.css', '../img/img.png', '../../img/img.png'); - mytest('a.css', 'x/y/b.css', '../img/img.png', '../../../img/img.png'); - mytest('x/a.css', 'b.css', '../img/img.png', 'img/img.png'); - mytest('x/y/a.css', 'b.css', '../img/img.png', 'x/img/img.png'); - mytest('x/y/a.css', 't/u/b.css', '../img/img.png', '../../x/img/img.png'); - mytest('x/y/a.css', 'x/u/b.css', '../img/img.png', '../img/img.png'); - mytest('x/y/a.css', 'x/y/b.css', '../img/img.png', '../img/img.png'); - mytest('/a.css', 'b.css', '../img/img.png', '/img/img.png'); - mytest('/a.css', 'x/b.css', '../img/img.png', '/img/img.png'); - mytest('/a.css', 'x/y/b.css', '../img/img.png', '/img/img.png'); - mytest('/x/a.css', 'b.css', '../img/img.png', '/img/img.png'); - mytest('/x/a.css', 'x/b.css', '../img/img.png', '/img/img.png'); - mytest('/x/a.css', 'x/y/b.css', '../img/img.png', '/img/img.png'); - mytest('/x/y/a.css', 'b.css', '../img/img.png', '/x/img/img.png'); - mytest('/x/y/a.css', 'x/b.css', '../img/img.png', '/x/img/img.png'); - mytest('/x/y/a.css', 'x/y/b.css', '../img/img.png', '/x/img/img.png'); - mytest('/a.css', '/b.css', '../img/img.png', '/img/img.png'); - mytest('/a.css', '/b.css', '../img/img.png', '/img/img.png'); - mytest('/x/a.css', '/b.css', '../img/img.png', '/img/img.png'); - mytest('/x/a.css', '/x/b.css', '../img/img.png', '/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'b.css', '../img/img.png', 'http://www.example.com/x/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'http://www.example2.com/b.css', '../img/img.png', 'http://www.example.com/x/img/img.png'); - mytest('https://www.example.com/x/y/a.css', 'b.css', '../img/img.png', 'https://www.example.com/x/img/img.png'); - - // /img/img.png - mytest('a.css', 'b.css', '/img/img.png', '/img/img.png'); - mytest('a.css', 't/b.css', '/img/img.png', '/img/img.png'); - mytest('a.css', 'x/y/b.css', '/img/img.png', '/img/img.png'); - mytest('x/a.css', 'b.css', '/img/img.png', '/img/img.png'); - mytest('x/y/a.css', 'b.css', '/img/img.png', '/img/img.png'); - mytest('x/y/a.css', 't/u/b.css', '/img/img.png', '/img/img.png'); - mytest('x/y/a.css', 'x/u/b.css', '/img/img.png', '/img/img.png'); - mytest('x/y/a.css', 'x/y/b.css', '/img/img.png', '/img/img.png'); - mytest('/a.css', 'b.css', '/img/img.png', '/img/img.png'); - mytest('/a.css', 'x/b.css', '/img/img.png', '/img/img.png'); - mytest('/a.css', 'x/y/b.css', '/img/img.png', '/img/img.png'); - mytest('/x/a.css', 'b.css', '/img/img.png', '/img/img.png'); - mytest('/x/a.css', 'x/b.css', '/img/img.png', '/img/img.png'); - mytest('/x/a.css', 'x/y/b.css', '/img/img.png', '/img/img.png'); - mytest('/x/y/a.css', 'b.css', '/img/img.png', '/img/img.png'); - mytest('/x/y/a.css', 'x/b.css', '/img/img.png', '/img/img.png'); - mytest('/x/y/a.css', 'x/y/b.css', '/img/img.png', '/img/img.png'); - mytest('/a.css', '/b.css', '/img/img.png', '/img/img.png'); - mytest('/a.css', '/b.css', '/img/img.png', '/img/img.png'); - mytest('/x/a.css', '/b.css', '/img/img.png', '/img/img.png'); - mytest('/x/a.css', '/x/b.css', '/img/img.png', '/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'b.css', '/img/img.png', 'http://www.example.com/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'http://www.example.com/x/y/b.css', '/img/img.png', 'http://www.example.com/img/img.png'); - mytest('https://www.example.com/x/y/a.css', 'b.css', '/img/img.png', 'https://www.example.com/img/img.png'); - - // http://example.com/img/img.png - mytest('a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('a.css', 't/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('a.css', 'x/y/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('x/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('x/y/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('x/y/a.css', 't/u/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('x/y/a.css', 'x/u/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('x/y/a.css', 'x/y/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/a.css', 'x/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/a.css', 'x/y/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/a.css', 'x/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/a.css', 'x/y/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/y/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/y/a.css', 'x/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/y/a.css', 'x/y/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/a.css', '/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/a.css', '/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/a.css', '/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('/x/a.css', '/x/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('http://www.example.com/x/y/a.css', 'http://www.example.com/x/y/b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - mytest('https://www.example.com/x/y/a.css', 'b.css', 'http://example.com/img/img.png', 'http://example.com/img/img.png'); - - - }); - - test('Utilities.rewriteUrls - quotes and spaces', () => { - assert.strictEqual(rewriteUrls('x/y/a.css', 't/u/b.css', 'sel { background:url(\'../img/img.png\'); }'), 'sel { background:url(../../x/img/img.png); }'); - assert.strictEqual(rewriteUrls('x/y/a.css', 't/u/b.css', 'sel { background:url(\t\'../img/img.png\'); }'), 'sel { background:url(../../x/img/img.png); }'); - assert.strictEqual(rewriteUrls('x/y/a.css', 't/u/b.css', 'sel { background:url( \'../img/img.png\'); }'), 'sel { background:url(../../x/img/img.png); }'); - assert.strictEqual(rewriteUrls('x/y/a.css', 't/u/b.css', 'sel { background:url(\'../img/img.png\'\t); }'), 'sel { background:url(../../x/img/img.png); }'); - assert.strictEqual(rewriteUrls('x/y/a.css', 't/u/b.css', 'sel { background:url(\'../img/img.png\' ); }'), 'sel { background:url(../../x/img/img.png); }'); - assert.strictEqual(rewriteUrls('x/y/a.css', 't/u/b.css', 'sel { background:url( \t \'../img/img.png\' \t); }'), 'sel { background:url(../../x/img/img.png); }'); - }); - - test('Bug 9601 - css should ignore data urls', () => { - const dataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAACHmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iPgogICAgICAgICA8ZGM6c3ViamVjdD4KICAgICAgICAgICAgPHJkZjpCYWcvPgogICAgICAgICA8L2RjOnN1YmplY3Q+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgogICAgICAgICA8eG1wOkNyZWF0b3JUb29sPkFkb2JlIEltYWdlUmVhZHk8L3htcDpDcmVhdG9yVG9vbD4KICAgICAgPC9yZGY6RGVzY3JpcHRpb24+CiAgIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+ClC8oVQAAAGnSURBVDiNrZMxTxNxGMZ///9dZWns9a4dTHSABFiuCU5dGt2d9BsQls6GD2LCd2AiQQfixKIJE0ObdKIUSvDa5uLZihP0Sh+HOw3ipOUZ3zzvL2+e932NJBaRe7/Q8Uw5eMRrzXllDU8A5mJkLB+/TflQ+67JXb+5O0FUNS9deLckns/tn2A7hxtDawZvn37Vp78AX8rmxZLDewf89HGJ+fgKCrkrBeuXKPy44hbGN7e8eTbRZwALcFE2nuOy48j6zmaTYP8Qtxaia9A1uLWQYP8QZ7OJI+s7LjsXZeMBIIlLn61xgEbLnqadtiQp7Z0orq8rrq8r7Z1IkqadtkbLnsYBuvTZkpQBhgF7SRVFJRQ3QqW9bgY5P1V6fpoDu4oboaISSqpoGLD3GzAIOEqqaFBBURHF9TWlZxlEktKzruL6mqJi5kmqaBBwJIl7Wf+7LICBIYBSKGyE+LsHuCurzPo9Zv0e7soq/u4BhY0Qpfn68p6HCbHv4Q0qtBPfarLd1LR1nAVWzDNphJq2jjXZbirxrQYV2n0PT9Lih/Rwp/xLCz3T/+gnd2VVRJs/vngAAAAASUVORK5CYII='; - - function mytest(originalFile: string, newFile: string) { - assert.strictEqual(rewriteUrls(originalFile, newFile, 'sel { background:url(' + dataUrl + '); }'), 'sel { background:url(' + dataUrl + '); }'); - assert.strictEqual(rewriteUrls(originalFile, newFile, 'sel { background:url( \t' + dataUrl + '\t ); }'), 'sel { background:url(' + dataUrl + '); }'); - } - - mytest('a.css', 'b.css'); - mytest('a.css', 't/b.css'); - mytest('a.css', 'x/y/b.css'); - mytest('x/a.css', 'b.css'); - mytest('x/y/a.css', 'b.css'); - mytest('x/y/a.css', 't/u/b.css'); - mytest('x/y/a.css', 'x/u/b.css'); - mytest('x/y/a.css', 'x/y/b.css'); - mytest('/a.css', 'b.css'); - mytest('/a.css', 'x/b.css'); - mytest('/a.css', 'x/y/b.css'); - mytest('/x/a.css', 'b.css'); - mytest('/x/a.css', 'x/b.css'); - mytest('/x/a.css', 'x/y/b.css'); - mytest('/x/y/a.css', 'b.css'); - mytest('/x/y/a.css', 'x/b.css'); - mytest('/x/y/a.css', 'x/y/b.css'); - mytest('/a.css', '/b.css'); - mytest('/a.css', '/b.css'); - mytest('/x/a.css', '/b.css'); - mytest('/x/a.css', '/x/b.css'); - mytest('http://www.example.com/x/y/a.css', 'b.css'); - mytest('http://www.example.com/x/y/a.css', 'http://www.example.com/x/y/b.css'); - mytest('https://www.example.com/x/y/a.css', 'b.css'); - }); -}); diff --git a/src/vs/base/test/node/pfs/pfs.test.ts b/src/vs/base/test/node/pfs/pfs.test.ts index 37d6e5bf85..2eb00a5b98 100644 --- a/src/vs/base/test/node/pfs/pfs.test.ts +++ b/src/vs/base/test/node/pfs/pfs.test.ts @@ -11,11 +11,9 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { randomPath } from 'vs/base/common/extpath'; import { join, sep } from 'vs/base/common/path'; import { isWindows } from 'vs/base/common/platform'; -import { configureFlushOnWrite, Promises, RimRafMode, rimrafSync, SymlinkSupport, writeFileSync } from 'vs/base/node/pfs'; +import { Promises, RimRafMode, rimrafSync, SymlinkSupport, writeFileSync } from 'vs/base/node/pfs'; import { flakySuite, getPathFromAmdModule, getRandomTestPath } from 'vs/base/test/node/testUtils'; -configureFlushOnWrite(false); // speed up all unit tests by disabling flush on write - flakySuite('PFS', function () { let testDir: string; @@ -370,36 +368,24 @@ flakySuite('PFS', function () { const smallData = 'Hello World'; const bigData = (new Array(100 * 1024)).join('Large String\n'); - return testWriteFile(smallData, smallData, bigData, bigData); - }); - - test('writeFile (string) - flush on write', async () => { - configureFlushOnWrite(true); - try { - const smallData = 'Hello World'; - const bigData = (new Array(100 * 1024)).join('Large String\n'); - - return await testWriteFile(smallData, smallData, bigData, bigData); - } finally { - configureFlushOnWrite(false); - } + return testWriteFileAndFlush(smallData, smallData, bigData, bigData); }); test('writeFile (Buffer)', async () => { const smallData = 'Hello World'; const bigData = (new Array(100 * 1024)).join('Large String\n'); - return testWriteFile(Buffer.from(smallData), smallData, Buffer.from(bigData), bigData); + return testWriteFileAndFlush(Buffer.from(smallData), smallData, Buffer.from(bigData), bigData); }); test('writeFile (UInt8Array)', async () => { const smallData = 'Hello World'; const bigData = (new Array(100 * 1024)).join('Large String\n'); - return testWriteFile(VSBuffer.fromString(smallData).buffer, smallData, VSBuffer.fromString(bigData).buffer, bigData); + return testWriteFileAndFlush(VSBuffer.fromString(smallData).buffer, smallData, VSBuffer.fromString(bigData).buffer, bigData); }); - async function testWriteFile( + async function testWriteFileAndFlush( smallData: string | Buffer | Uint8Array, smallDataValue: string, bigData: string | Buffer | Uint8Array, diff --git a/src/vs/base/test/node/uri.test.perf.ts b/src/vs/base/test/node/uri.test.perf.ts index fa5a63fa2e..bfe0d811ba 100644 --- a/src/vs/base/test/node/uri.test.perf.ts +++ b/src/vs/base/test/node/uri.test.perf.ts @@ -13,18 +13,18 @@ suite('URI - perf', function () { let manyFileUris: URI[]; setup(function () { manyFileUris = []; - const data = readFileSync(getPathFromAmdModule(require, './uri.test.data.txt')).toString(); - const lines = data.split('\n'); - for (const line of lines) { + let data = readFileSync(getPathFromAmdModule(require, './uri.test.data.txt')).toString(); + let lines = data.split('\n'); + for (let line of lines) { manyFileUris.push(URI.file(line)); } }); function perfTest(name: string, callback: Function) { test(name, _done => { - const t1 = Date.now(); + let t1 = Date.now(); callback(); - const d = Date.now() - t1; + let d = Date.now() - t1; console.log(`${name} took ${d}ms (${(d / manyFileUris.length).toPrecision(3)} ms/uri)`); _done(); }); @@ -32,28 +32,28 @@ suite('URI - perf', function () { perfTest('toString', function () { for (const uri of manyFileUris) { - const data = uri.toString(); + let data = uri.toString(); assert.ok(data); } }); perfTest('toString(skipEncoding)', function () { for (const uri of manyFileUris) { - const data = uri.toString(true); + let data = uri.toString(true); assert.ok(data); } }); perfTest('fsPath', function () { for (const uri of manyFileUris) { - const data = uri.fsPath; + let data = uri.fsPath; assert.ok(data); } }); perfTest('toJSON', function () { for (const uri of manyFileUris) { - const data = uri.toJSON(); + let data = uri.toJSON(); assert.ok(data); } }); diff --git a/src/vs/base/worker/workerMain.ts b/src/vs/base/worker/workerMain.ts index f08e487085..7984d75123 100644 --- a/src/vs/base/worker/workerMain.ts +++ b/src/vs/base/worker/workerMain.ts @@ -76,21 +76,17 @@ }); } - function configureAMDLoader() { - require.config({ - baseUrl: monacoBaseUrl, - catchError: true, - trustedTypesPolicy, - amdModulesPattern: /^vs\// - }); - } - - function loadCode(moduleId: string) { + const loadCode = function (moduleId: string) { loadAMDLoader().then(() => { - configureAMDLoader(); + require.config({ + baseUrl: monacoBaseUrl, + catchError: true, + trustedTypesPolicy, + amdModulesPattern: /^vs\// + }); require([moduleId], function (ws) { setTimeout(function () { - const messageHandler = ws.create((msg: any, transfer?: Transferable[]) => { + let messageHandler = ws.create((msg: any, transfer?: Transferable[]) => { (self).postMessage(msg, transfer); }, null); @@ -101,17 +97,10 @@ }, 0); }); }); - } - - // If the loader is already defined, configure it immediately - // This helps in the bundled case, where we must load nls files - // and they need a correct baseUrl to be loaded. - if (typeof (self).define === 'function' && (self).define.amd) { - configureAMDLoader(); - } + }; let isFirstMessage = true; - const beforeReadyMessages: MessageEvent[] = []; + let beforeReadyMessages: MessageEvent[] = []; self.onmessage = (message: MessageEvent) => { if (!isFirstMessage) { beforeReadyMessages.push(message); diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index ca282de3be..2b3f7f4c65 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -52,19 +52,6 @@ Object.keys(self.webPackagePaths).map(function (key, index) { self.webPackagePaths[key] = `${baseUrl}/node_modules/${key}/${self.webPackagePaths[key]}`; }); - - // Set up nls if the user is not using the default language (English) - const nlsConfig = {}; - const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language; - if (!locale.startsWith('en')) { - nlsConfig['vs/nls'] = { - availableLanguages: { - '*': locale - }, - translationServiceUrl: '{{WORKBENCH_NLS_BASE_URL}}' - }; - } - require.config({ baseUrl: `${baseUrl}/out`, recordStats: true, @@ -117,7 +104,7 @@ 'plotly.js-dist-min': `${window.location.origin}/static/node_modules/plotly.js-dist-min/plotly.min.js`, 'azdataGraph': `${window.location.origin}/static/node_modules/azdataGraph/dist/build.js` } - }); + }; diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts index a2c2a76f55..9390654784 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/extensionsCleaner.ts @@ -3,186 +3,27 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { URI } from 'vs/base/common/uri'; -import { IExtensionGalleryService, IExtensionIdentifier, IGlobalExtensionEnablementService, ServerDidUninstallExtensionEvent, ServerInstallExtensionResult, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { getIdAndVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; -import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; +import { Disposable } from 'vs/base/common/lifecycle'; +import { IExtensionGalleryService, IExtensionManagementService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionStorageService, IExtensionStorageService } from 'vs/platform/extensionManagement/common/extensionStorage'; import { migrateUnsupportedExtensions } from 'vs/platform/extensionManagement/common/unsupportedExtensionsMigration'; -import { INativeServerExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; -import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ILogService } from 'vs/platform/log/common/log'; import { IStorageService } from 'vs/platform/storage/common/storage'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { DidChangeProfilesEvent, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; - -const uninstalOptions: UninstallOptions = { versionOnly: true, donotIncludePack: true, donotCheckDependents: true }; export class ExtensionsCleaner extends Disposable { constructor( - @INativeServerExtensionManagementService extensionManagementService: INativeServerExtensionManagementService, - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, + @IExtensionManagementService extensionManagementService: ExtensionManagementService, @IExtensionGalleryService extensionGalleryService: IExtensionGalleryService, @IExtensionStorageService extensionStorageService: IExtensionStorageService, @IGlobalExtensionEnablementService extensionEnablementService: IGlobalExtensionEnablementService, - @IInstantiationService instantiationService: IInstantiationService, @IStorageService storageService: IStorageService, @ILogService logService: ILogService, ) { super(); - - extensionManagementService.removeUninstalledExtensions(this.userDataProfilesService.profiles.length === 1); + extensionManagementService.removeDeprecatedExtensions(); migrateUnsupportedExtensions(extensionManagementService, extensionGalleryService, extensionStorageService, extensionEnablementService, logService); ExtensionStorageService.removeOutdatedExtensionVersions(extensionManagementService, storageService); - this._register(instantiationService.createInstance(ProfileExtensionsCleaner)); } - -} - -class ProfileExtensionsCleaner extends Disposable { - - private profileExtensionsLocations = new Map(); // {{SQL CARBON EDIT}} lewissanchez - Added parenthesis - - private readonly profileModeDisposables = this._register(new MutableDisposable()); - - constructor( - @INativeServerExtensionManagementService private readonly extensionManagementService: INativeServerExtensionManagementService, - @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, - @IExtensionsProfileScannerService private readonly extensionsProfileScannerService: IExtensionsProfileScannerService, - @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, - @ILogService private readonly logService: ILogService, - ) { - super(); - this.onDidChangeProfiles({ added: this.userDataProfilesService.profiles, removed: [], all: this.userDataProfilesService.profiles }); - } - - private async onDidChangeProfiles({ added, removed, all }: Omit): Promise { - try { - await Promise.all(removed.map(profile => profile.extensionsResource ? this.removeExtensionsFromProfile(profile.extensionsResource) : Promise.resolve())); - } catch (error) { - this.logService.error(error); - } - - if (all.length === 1) { - // Exit profile mode - this.profileModeDisposables.clear(); - // Listen for entering into profile mode - const disposable = this._register(this.userDataProfilesService.onDidChangeProfiles(() => { - disposable.dispose(); - this.onDidChangeProfiles({ added: this.userDataProfilesService.profiles, removed: [], all: this.userDataProfilesService.profiles }); - })); - return; - } - - try { - if (added.length) { - await Promise.all(added.map(profile => profile.extensionsResource ? this.populateExtensionsFromProfile(profile.extensionsResource) : Promise.resolve())); - // Enter profile mode - if (!this.profileModeDisposables.value) { - this.profileModeDisposables.value = new DisposableStore(); - this.profileModeDisposables.value.add(toDisposable(() => this.profileExtensionsLocations.clear())); - this.profileModeDisposables.value.add(this.userDataProfilesService.onDidChangeProfiles(e => this.onDidChangeProfiles(e))); - this.profileModeDisposables.value.add(this.extensionManagementService.onDidInstallExtensions(e => this.onDidInstallExtensions(e))); - this.profileModeDisposables.value.add(this.extensionManagementService.onDidUninstallExtension(e => this.onDidUninstallExtension(e))); - await this.uninstallExtensionsNotInProfiles(); - } - } - } catch (error) { - this.logService.error(error); - } - } - - private async uninstallExtensionsNotInProfiles(): Promise { - const installed = await this.extensionManagementService.getAllUserInstalled(); - const toUninstall = installed.filter(installedExtension => !this.profileExtensionsLocations.has(this.getKey(installedExtension.identifier, installedExtension.manifest.version))); - if (toUninstall.length) { - await Promise.all(toUninstall.map(extension => this.extensionManagementService.uninstall(extension, uninstalOptions))); - } - } - - private async onDidInstallExtensions(installedExtensions: readonly ServerInstallExtensionResult[]): Promise { - for (const { local, profileLocation } of installedExtensions) { - if (!local || !profileLocation) { - continue; - } - this.addExtensionWithKey(this.getKey(local.identifier, local.manifest.version), profileLocation); - } - } - - private async onDidUninstallExtension(e: ServerDidUninstallExtensionEvent): Promise { - if (!e.profileLocation || !e.version) { - return; - } - if (this.removeExtensionWithKey(this.getKey(e.identifier, e.version), e.profileLocation)) { - await this.uninstallExtensions([{ identifier: e.identifier, version: e.version }]); - } - } - - private async populateExtensionsFromProfile(extensionsProfileLocation: URI): Promise { - const extensions = await this.extensionsProfileScannerService.scanProfileExtensions(extensionsProfileLocation); - for (const extension of extensions) { - this.addExtensionWithKey(this.getKey(extension.identifier, extension.version), extensionsProfileLocation); - } - } - - private async removeExtensionsFromProfile(removedProfile: URI): Promise { - const extensionsToRemove: { identifier: IExtensionIdentifier; version: string }[] = []; - for (const key of [...this.profileExtensionsLocations.keys()]) { - if (!this.removeExtensionWithKey(key, removedProfile)) { - continue; - } - const extensionToRemove = this.fromKey(key); - if (extensionToRemove) { - extensionsToRemove.push(extensionToRemove); - } - } - if (extensionsToRemove.length) { - await this.uninstallExtensions(extensionsToRemove); - } - } - - private addExtensionWithKey(key: string, extensionsProfileLocation: URI): void { - let locations = this.profileExtensionsLocations.get(key); - if (!locations) { - locations = []; - this.profileExtensionsLocations.set(key, locations); - } - locations.push(extensionsProfileLocation); - } - - private removeExtensionWithKey(key: string, profileLocation: URI): boolean { - const profiles = this.profileExtensionsLocations.get(key); - if (profiles) { - const index = profiles.findIndex(profile => this.uriIdentityService.extUri.isEqual(profile, profileLocation)); - if (index > -1) { - profiles.splice(index, 1); - } - } - if (!profiles?.length) { - this.profileExtensionsLocations.delete(key); - return true; - } - return false; - } - - private async uninstallExtensions(extensionsToRemove: { identifier: IExtensionIdentifier; version: string }[]): Promise { - const installed = await this.extensionManagementService.getAllUserInstalled(); - const toUninstall = installed.filter(installedExtension => extensionsToRemove.some(e => this.getKey(installedExtension.identifier, installedExtension.manifest.version) === this.getKey(e.identifier, e.version))); - if (toUninstall.length) { - await Promise.all(toUninstall.map(extension => this.extensionManagementService.uninstall(extension, uninstalOptions))); - } - } - - private getKey(identifier: IExtensionIdentifier, version: string): string { - return `${ExtensionIdentifier.toKey(identifier.id)}@${version}`; - } - - private fromKey(key: string): { identifier: IExtensionIdentifier; version: string } | undefined { - const [id, version] = getIdAndVersion(key); - return version ? { identifier: { id }, version } : undefined; - } - } diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts index 3266cdda6a..f7a9bf641d 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner.ts @@ -59,7 +59,7 @@ export class LanguagePackCachedDataCleaner extends Disposable { try { const installed: IStringDictionary = Object.create(null); const metaData: ILanguagePackFile = JSON.parse(await Promises.readFile(join(this.environmentService.userDataPath, 'languagepacks.json'), 'utf8')); - for (const locale of Object.keys(metaData)) { + for (let locale of Object.keys(metaData)) { const entry = metaData[locale]; installed[`${entry.hash}.${locale}`] = true; } diff --git a/src/vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater.ts b/src/vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater.ts index d4f354c3c6..382b802081 100644 --- a/src/vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater.ts +++ b/src/vs/code/electron-browser/sharedProcess/contrib/localizationsUpdater.ts @@ -4,13 +4,13 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable } from 'vs/base/common/lifecycle'; -import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; -import { NativeLanguagePackService } from 'vs/platform/languagePacks/node/languagePacks'; +import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; +import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; export class LocalizationsUpdater extends Disposable { constructor( - @ILanguagePackService private readonly localizationsService: NativeLanguagePackService + @ILocalizationsService private readonly localizationsService: LocalizationsService ) { super(); diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index f11c1d9751..b99d17e8a8 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -31,10 +31,10 @@ import { INativeEnvironmentService } from 'vs/platform/environment/common/enviro import { SharedProcessEnvironmentService } from 'vs/platform/sharedProcess/node/sharedProcessEnvironmentService'; import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService'; import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; -import { IDefaultExtensionsProfileInitService, IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionGalleryService, IExtensionManagementService, IExtensionTipsService, IGlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementChannel, ExtensionTipsChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; import { ExtensionTipsService } from 'vs/platform/extensionManagement/electron-sandbox/extensionTipsService'; -import { ExtensionManagementService, INativeServerExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; +import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { IExtensionRecommendationNotificationService } from 'vs/platform/extensionRecommendations/common/extensionRecommendations'; import { ExtensionRecommendationNotificationServiceChannelClient } from 'vs/platform/extensionRecommendations/electron-sandbox/extensionRecommendationsIpc'; import { IFileService } from 'vs/platform/files/common/files'; @@ -46,13 +46,14 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { MessagePortMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService'; import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/services'; -import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; -import { NativeLanguagePackService } from 'vs/platform/languagePacks/node/languagePacks'; +import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; +import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { ConsoleLogger, ILoggerService, ILogService, MultiplexLogService } from 'vs/platform/log/common/log'; import { FollowerLogService, LoggerChannelClient, LogLevelChannelClient } from 'vs/platform/log/common/logIpc'; import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; +import { RequestService } from 'vs/platform/request/browser/requestService'; import { IRequestService } from 'vs/platform/request/common/request'; import { ISharedProcessConfiguration } from 'vs/platform/sharedProcess/node/sharedProcess'; import { IStorageService } from 'vs/platform/storage/common/storage'; @@ -62,7 +63,7 @@ import { ICustomEndpointTelemetryService, ITelemetryService } from 'vs/platform/ import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService, getPiiPathsFromEnvironment, isInternalTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; +import { supportsTelemetry, ITelemetryAppender, NullAppender, NullTelemetryService, isInternalTelemetry, getPiiPathsFromEnvironment } from 'vs/platform/telemetry/common/telemetryUtils'; import { CustomEndpointTelemetryService } from 'vs/platform/telemetry/node/customEndpointTelemetryService'; import { LocalReconnectConstants, TerminalIpcChannels, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal'; @@ -89,7 +90,7 @@ import { ipcSharedProcessTunnelChannelName, ISharedProcessTunnelService } from ' import { SharedProcessTunnelService } from 'vs/platform/tunnel/node/sharedProcessTunnelService'; import { ipcSharedProcessWorkerChannelName, ISharedProcessWorkerConfiguration, ISharedProcessWorkerService } from 'vs/platform/sharedProcess/common/sharedProcessWorkerService'; import { SharedProcessWorkerService } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorkerService'; -// import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; // {{SQL CARBON EDIT}} - Unused import +import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; import { isLinux } from 'vs/base/common/platform'; @@ -99,14 +100,6 @@ import { InspectProfilingService as V8InspectProfilingService } from 'vs/platfor import { IV8InspectProfilingService } from 'vs/platform/profiling/common/profiling'; import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService'; import { ExtensionsScannerService } from 'vs/platform/extensionManagement/node/extensionsScannerService'; -import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; -import { PolicyChannelClient } from 'vs/platform/policy/common/policyIpc'; -import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; -import { UserDataProfilesNativeService } from 'vs/platform/userDataProfile/electron-sandbox/userDataProfile'; -import { OneDataSystemWebAppender } from 'vs/platform/telemetry/browser/1dsAppender'; -import { DefaultExtensionsProfileInitService } from 'vs/platform/extensionManagement/electron-sandbox/defaultExtensionsProfileInit'; -import { SharedProcessRequestService } from 'vs/platform/request/electron-browser/sharedProcessRequestService'; class SharedProcessMain extends Disposable { @@ -187,10 +180,6 @@ class SharedProcessMain extends Disposable { const mainProcessService = new MessagePortMainProcessService(this.server, mainRouter); services.set(IMainProcessService, mainProcessService); - // Policies - const policyService = this.configuration.policiesData ? new PolicyChannelClient(this.configuration.policiesData, mainProcessService.getChannel('policy')) : new NullPolicyService(); - services.set(IPolicyService, policyService); - // Environment const environmentService = new SharedProcessEnvironmentService(this.configuration.args, productService); services.set(INativeEnvironmentService, environmentService); @@ -232,16 +221,12 @@ class SharedProcessMain extends Disposable { )); fileService.registerProvider(Schemas.vscodeUserData, userDataFileSystemProvider); - // User Data Profiles - const userDataProfilesService = this._register(new UserDataProfilesNativeService(this.configuration.profiles, mainProcessService, environmentService)); - services.set(IUserDataProfilesService, userDataProfilesService); - // Configuration - const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, policyService, logService)); + const configurationService = this._register(new ConfigurationService(environmentService.settingsResource, fileService)); services.set(IConfigurationService, configurationService); // Storage (global access only) - const storageService = new NativeStorageService(undefined, { defaultProfile: userDataProfilesService.defaultProfile, currentProfile: userDataProfilesService.defaultProfile }, mainProcessService, environmentService); + const storageService = new NativeStorageService(undefined, mainProcessService, environmentService); services.set(IStorageService, storageService); this._register(toDisposable(() => storageService.flush())); @@ -255,7 +240,7 @@ class SharedProcessMain extends Disposable { services.set(IUriIdentityService, new UriIdentityService(fileService)); // Request - services.set(IRequestService, new SharedProcessRequestService(mainProcessService, configurationService, logService)); + services.set(IRequestService, new SyncDescriptor(RequestService)); // Checksum services.set(IChecksumService, new SyncDescriptor(ChecksumService)); @@ -284,14 +269,14 @@ class SharedProcessMain extends Disposable { appenders.push(logAppender); const { installSourcePath } = environmentService; if (productService.aiConfig?.ariaKey) { - const collectorAppender = new OneDataSystemWebAppender(internalTelemetry, 'adsworkbench', null, productService.aiConfig.ariaKey); // {{SQL CARBON EDIT}} Use our own event prefix + const collectorAppender = new OneDataSystemAppender(internalTelemetry, 'adsworkbench', null, productService.aiConfig.ariaKey); // {{SQL CARBON EDIT}} Use our own event prefix this._register(toDisposable(() => collectorAppender.flush())); // Ensure the 1DS appender is disposed so that it flushes remaining data appenders.push(collectorAppender); } telemetryService = new TelemetryService({ appenders, - commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, internalTelemetry, installSourcePath), + commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, this.configuration.machineId, productService.msftInternalDomains, installSourcePath), sendErrorTelemetry: true, piiPaths: getPiiPathsFromEnvironment(environmentService), }, configurationService, productService); @@ -309,10 +294,8 @@ class SharedProcessMain extends Disposable { services.set(ICustomEndpointTelemetryService, customEndpointTelemetryService); // Extension Management - services.set(IExtensionsProfileScannerService, new SyncDescriptor(ExtensionsProfileScannerService)); services.set(IExtensionsScannerService, new SyncDescriptor(ExtensionsScannerService)); - services.set(INativeServerExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); - services.set(IDefaultExtensionsProfileInitService, new SyncDescriptor(DefaultExtensionsProfileInitService)); + services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); // Extension Gallery services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService)); @@ -321,7 +304,7 @@ class SharedProcessMain extends Disposable { services.set(IExtensionTipsService, new SyncDescriptor(ExtensionTipsService)); // Localizations - services.set(ILanguagePackService, new SyncDescriptor(NativeLanguagePackService)); + services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService)); // Diagnostics services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService)); @@ -370,9 +353,9 @@ class SharedProcessMain extends Disposable { const channel = new ExtensionManagementChannel(accessor.get(IExtensionManagementService), () => null); this.server.registerChannel('extensions', channel); - // Language Packs - const languagePacksChannel = ProxyChannel.fromService(accessor.get(ILanguagePackService)); - this.server.registerChannel('languagePacks', languagePacksChannel); + // Localizations + const localizationsChannel = ProxyChannel.fromService(accessor.get(ILocalizationsService)); + this.server.registerChannel('localizations', localizationsChannel); // Diagnostics const diagnosticsChannel = ProxyChannel.fromService(accessor.get(IDiagnosticsService)); @@ -423,9 +406,6 @@ class SharedProcessMain extends Disposable { // Worker const sharedProcessWorkerChannel = ProxyChannel.fromService(accessor.get(ISharedProcessWorkerService)); this.server.registerChannel(ipcSharedProcessWorkerChannelName, sharedProcessWorkerChannel); - - // Default Extensions Profile Init - this.server.registerChannel('IDefaultExtensionsProfileInitService', ProxyChannel.fromService(accessor.get(IDefaultExtensionsProfileInitService))); } private registerErrorHandler(logService: ILogService): void { diff --git a/src/vs/code/electron-browser/workbench/workbench.html b/src/vs/code/electron-browser/workbench/workbench.html new file mode 100644 index 0000000000..2be94cec24 --- /dev/null +++ b/src/vs/code/electron-browser/workbench/workbench.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js new file mode 100644 index 0000000000..077777556b --- /dev/null +++ b/src/vs/code/electron-browser/workbench/workbench.js @@ -0,0 +1,214 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/// + +//@ts-check +(function () { + 'use strict'; + + const bootstrapWindow = bootstrapWindowLib(); + + // Add a perf entry right from the top + performance.mark('code/didStartRenderer'); + + // Load workbench main JS, CSS and NLS all in parallel. This is an + // optimization to prevent a waterfall of loading to happen, because + // we know for a fact that workbench.desktop.main will depend on + // the related CSS and NLS counterparts. + bootstrapWindow.load([ + 'sql/setup', // {{SQL CARBON EDIT}} + 'vs/workbench/workbench.desktop.main', + 'vs/nls!vs/workbench/workbench.desktop.main', + 'vs/css!vs/workbench/workbench.desktop.main' + ], + function (_, configuration) { + + // Mark start of workbench + performance.mark('code/didLoadWorkbenchMain'); + + // @ts-ignore + return require('vs/workbench/electron-sandbox/desktop.main').main(configuration); + }, + { + configureDeveloperSettings: function (windowConfig) { + return { + // disable automated devtools opening on error when running extension tests + // as this can lead to nondeterministic test execution (devtools steals focus) + forceDisableShowDevtoolsOnError: typeof windowConfig.extensionTestsPath === 'string', + // enable devtools keybindings in extension development window + forceEnableDeveloperKeybindings: Array.isArray(windowConfig.extensionDevelopmentPath) && windowConfig.extensionDevelopmentPath.length > 0, + removeDeveloperKeybindingsAfterLoad: true + }; + }, + canModifyDOM: function (windowConfig) { + showSplash(windowConfig); + }, + beforeLoaderConfig: function (loaderConfig) { + loaderConfig.recordStats = true; + }, + beforeRequire: function () { + performance.mark('code/willLoadWorkbenchMain'); + + // It looks like browsers only lazily enable + // the element when needed. Since we + // leverage canvas elements in our code in many + // locations, we try to help the browser to + // initialize canvas when it is idle, right + // before we wait for the scripts to be loaded. + // @ts-ignore + window.requestIdleCallback(() => { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + context.clearRect(0, 0, canvas.width, canvas.height); + canvas.remove(); + }, { timeout: 50 }); + } + } + ); + + //#region Helpers + + /** + * @typedef {import('../../../platform/window/common/window').INativeWindowConfiguration} INativeWindowConfiguration + * @typedef {import('../../../platform/environment/common/argv').NativeParsedArgs} NativeParsedArgs + * + * @returns {{ + * load: ( + * modules: string[], + * resultCallback: (result, configuration: INativeWindowConfiguration & NativeParsedArgs) => unknown, + * options?: { + * configureDeveloperSettings?: (config: INativeWindowConfiguration & NativeParsedArgs) => { + * forceDisableShowDevtoolsOnError?: boolean, + * forceEnableDeveloperKeybindings?: boolean, + * disallowReloadKeybinding?: boolean, + * removeDeveloperKeybindingsAfterLoad?: boolean + * }, + * canModifyDOM?: (config: INativeWindowConfiguration & NativeParsedArgs) => void, + * beforeLoaderConfig?: (loaderConfig: object) => void, + * beforeRequire?: () => void + * } + * ) => Promise + * }} + */ + function bootstrapWindowLib() { + // @ts-ignore (defined in bootstrap-window.js) + return window.MonacoBootstrapWindow; + } + + /** + * @param {INativeWindowConfiguration & NativeParsedArgs} configuration + */ + function showSplash(configuration) { + performance.mark('code/willShowPartsSplash'); + + let data = configuration.partsSplash; + + if (data) { + // high contrast mode has been turned by the OS -> ignore stored colors and layouts + if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { + if ((configuration.colorScheme.dark && data.baseTheme !== 'hc-black') || (!configuration.colorScheme.dark && data.baseTheme !== 'hc-light')) { + data = undefined; + } + } else if (configuration.autoDetectColorScheme) { + // OS color scheme is tracked and has changed + if ((configuration.colorScheme.dark && data.baseTheme !== 'vs-dark') || (!configuration.colorScheme.dark && data.baseTheme !== 'vs')) { + data = undefined; + } + } + } + + // developing an extension -> ignore stored layouts + if (data && configuration.extensionDevelopmentPath) { + data.layoutInfo = undefined; + } + + // minimal color configuration (works with or without persisted data) + let baseTheme, shellBackground, shellForeground; + if (data) { + baseTheme = data.baseTheme; + shellBackground = data.colorInfo.editorBackground; + shellForeground = data.colorInfo.foreground; + } else if (configuration.autoDetectHighContrast && configuration.colorScheme.highContrast) { + if (configuration.colorScheme.dark) { + baseTheme = 'hc-black'; + shellBackground = '#000000'; + shellForeground = '#FFFFFF'; + } else { + baseTheme = 'hc-light'; + shellBackground = '#FFFFFF'; + shellForeground = '#000000'; + } + } else if (configuration.autoDetectColorScheme) { + if (configuration.colorScheme.dark) { + baseTheme = 'vs-dark'; + shellBackground = '#1E1E1E'; + shellForeground = '#CCCCCC'; + } else { + baseTheme = 'vs'; + shellBackground = '#FFFFFF'; + shellForeground = '#000000'; + } + } + + const style = document.createElement('style'); + style.className = 'initialShellColors'; + document.head.appendChild(style); + style.textContent = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`; + + // restore parts if possible (we might not always store layout info) + if (data?.layoutInfo) { + const { layoutInfo, colorInfo } = data; + + const splash = document.createElement('div'); + splash.id = 'monaco-parts-splash'; + splash.className = baseTheme; + + if (layoutInfo.windowBorder) { + splash.style.position = 'relative'; + splash.style.height = 'calc(100vh - 2px)'; + splash.style.width = 'calc(100vw - 2px)'; + splash.style.border = '1px solid var(--window-border-color)'; + splash.style.setProperty('--window-border-color', colorInfo.windowBorder); + + if (layoutInfo.windowBorderRadius) { + splash.style.borderRadius = layoutInfo.windowBorderRadius; + } + } + + // ensure there is enough space + layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth)); + + // part: title + const titleDiv = document.createElement('div'); + titleDiv.setAttribute('style', `position: absolute; width: 100%; left: 0; top: 0; height: ${layoutInfo.titleBarHeight}px; background-color: ${colorInfo.titleBarBackground}; -webkit-app-region: drag;`); + splash.appendChild(titleDiv); + + // part: activity bar + const activityDiv = document.createElement('div'); + activityDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: 0; width: ${layoutInfo.activityBarWidth}px; background-color: ${colorInfo.activityBarBackground};`); + splash.appendChild(activityDiv); + + // part: side bar (only when opening workspace/folder) + // folder or workspace -> status bar color, sidebar + if (configuration.workspace) { + const sideDiv = document.createElement('div'); + sideDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: ${layoutInfo.activityBarWidth}px; width: ${layoutInfo.sideBarWidth}px; background-color: ${colorInfo.sideBarBackground};`); + splash.appendChild(sideDiv); + } + + // part: statusbar + const statusDiv = document.createElement('div'); + statusDiv.setAttribute('style', `position: absolute; width: 100%; bottom: 0; left: 0; height: ${layoutInfo.statusBarHeight}px; background-color: ${configuration.workspace ? colorInfo.statusBarBackground : colorInfo.statusBarNoFolderBackground};`); + splash.appendChild(statusDiv); + + document.body.appendChild(splash); + } + + performance.mark('code/didShowPartsSplash'); + } + + //#endregion +}()); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index cae819f54d..95990da305 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -46,7 +46,7 @@ import { getResolvedShellEnv } from 'vs/platform/shell/node/shellEnv'; import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust'; import { ExtensionUrlTrustService } from 'vs/platform/extensionManagement/node/extensionUrlTrustService'; import { IExtensionHostStarter, ipcExtensionHostStarterChannelName } from 'vs/platform/extensions/common/extensionHostStarter'; -import { ExtensionHostStarter } from 'vs/platform/extensions/electron-main/extensionHostStarter'; +import { WorkerMainProcessExtensionHostStarter } from 'vs/platform/extensions/electron-main/workerMainProcessExtensionHostStarter'; import { IExternalTerminalMainService } from 'vs/platform/externalTerminal/common/externalTerminal'; import { LinuxExternalTerminalService, MacExternalTerminalService, WindowsExternalTerminalService } from 'vs/platform/externalTerminal/node/externalTerminalService'; import { LOCAL_FILE_SYSTEM_CHANNEL_NAME } from 'vs/platform/files/common/diskFileSystemProviderClient'; @@ -70,12 +70,12 @@ import { SharedProcess } from 'vs/platform/sharedProcess/electron-main/sharedPro import { ISignService } from 'vs/platform/sign/common/sign'; import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { StorageDatabaseChannel } from 'vs/platform/storage/electron-main/storageIpc'; -import { ApplicationStorageMainService, IApplicationStorageMainService, IStorageMainService, StorageMainService } from 'vs/platform/storage/electron-main/storageMainService'; +import { GlobalStorageMainService, IGlobalStorageMainService, IStorageMainService, StorageMainService } from 'vs/platform/storage/electron-main/storageMainService'; import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties'; import { ITelemetryService, machineIdKey, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { getPiiPathsFromEnvironment, getTelemetryLevel, isInternalTelemetry, NullTelemetryService, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; +import { getPiiPathsFromEnvironment, getTelemetryLevel, NullTelemetryService, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; import { IUpdateService } from 'vs/platform/update/common/update'; import { UpdateChannel } from 'vs/platform/update/common/updateIpc'; import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateService.darwin'; @@ -99,13 +99,6 @@ import { IWorkspacesHistoryMainService, WorkspacesHistoryMainService } from 'vs/ import { WorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService'; import { IWorkspacesManagementMainService, WorkspacesManagementMainService } from 'vs/platform/workspaces/electron-main/workspacesManagementMainService'; import { CredentialsNativeMainService } from 'vs/platform/credentials/electron-main/credentialsMainService'; -import { IPolicyService } from 'vs/platform/policy/common/policy'; -import { PolicyChannel } from 'vs/platform/policy/common/policyIpc'; -import { IUserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile'; -import { IDefaultExtensionsProfileInitService } from 'vs/platform/extensionManagement/common/extensionManagement'; -import { DefaultExtensionsProfileInitHandler } from 'vs/platform/extensionManagement/electron-main/defaultExtensionsProfileInit'; -import { RequestChannel } from 'vs/platform/request/common/requestIpc'; -import { IRequestService } from 'vs/platform/request/common/request'; /** * The main VS Code application. There will only ever be one instance, @@ -270,7 +263,7 @@ export class CodeApplication extends Disposable { // remote extension schemes have the following format // http://127.0.0.1:/vscode-remote-resource?path= - if (!uri.path.endsWith(Schemas.vscodeRemoteResource) && contentTypes.some(contentType => contentType.toLowerCase().includes('image/svg'))) { + if (!uri.path.includes(Schemas.vscodeRemoteResource) && contentTypes.some(contentType => contentType.toLowerCase().includes('image/svg'))) { return callback({ cancel: !isSvgRequestFromSafeContext(details) }); } } @@ -529,9 +522,6 @@ export class CodeApplication extends Disposable { // Services const appInstantiationService = await this.initServices(machineId, sharedProcess, sharedProcessReady); - // Setup Handlers - this.setUpHandlers(appInstantiationService); - // Setup Auth Handler this._register(appInstantiationService.createInstance(ProxyAuthHandler)); // {{SQL CARBON EDIT}} Cast here to avoid compilation error (not finding constructor?) @@ -550,14 +540,6 @@ export class CodeApplication extends Disposable { } } - private setUpHandlers(instantiationService: IInstantiationService): void { - // Auth Handler - this._register(instantiationService.createInstance(ProxyAuthHandler)); - - // Default Extensions Profile Init Handler - this._register(instantiationService.createInstance(DefaultExtensionsProfileInitHandler)); - } - private async resolveMachineId(): Promise { // We cache the machineId for faster lookups on startup @@ -659,11 +641,11 @@ export class CodeApplication extends Disposable { services.set(IExtensionUrlTrustService, new SyncDescriptor(ExtensionUrlTrustService)); // Extension Host Starter - services.set(IExtensionHostStarter, new SyncDescriptor(ExtensionHostStarter)); + services.set(IExtensionHostStarter, new SyncDescriptor(WorkerMainProcessExtensionHostStarter)); // Storage services.set(IStorageMainService, new SyncDescriptor(StorageMainService)); - services.set(IApplicationStorageMainService, new SyncDescriptor(ApplicationStorageMainService)); + services.set(IGlobalStorageMainService, new SyncDescriptor(GlobalStorageMainService)); // External terminal if (isWindows) { @@ -683,10 +665,9 @@ export class CodeApplication extends Disposable { // Telemetry if (supportsTelemetry(this.productService, this.environmentMainService)) { - const isInternal = isInternalTelemetry(this.productService, this.configurationService); const channel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('telemetryAppender'))); const appender = new TelemetryAppenderClient(channel); - const commonProperties = resolveCommonProperties(this.fileService, release(), hostname(), process.arch, this.productService.commit, this.productService.version, machineId, isInternal, this.environmentMainService.installSourcePath); + const commonProperties = resolveCommonProperties(this.fileService, release(), hostname(), process.arch, this.productService.commit, this.productService.version, machineId, this.productService.msftInternalDomains, this.environmentMainService.installSourcePath); const piiPaths = getPiiPathsFromEnvironment(this.environmentMainService); const config: ITelemetryServiceConfig = { appenders: [appender], commonProperties, piiPaths, sendErrorTelemetry: true }; @@ -695,9 +676,6 @@ export class CodeApplication extends Disposable { services.set(ITelemetryService, NullTelemetryService); } - // Default Extensions Profile Init - services.set(IDefaultExtensionsProfileInitService, ProxyChannel.toService(getDelayedChannel(sharedProcessReady.then(client => client.getChannel('IDefaultExtensionsProfileInitService'))))); - // Init services that require it await backupMainService.initialize(); @@ -717,11 +695,6 @@ export class CodeApplication extends Disposable { const diagnosticsChannel = ProxyChannel.fromService(accessor.get(IDiagnosticsMainService), { disableMarshalling: true }); this.mainProcessNodeIpcServer.registerChannel('diagnostics', diagnosticsChannel); - // Policies (main & shared process) - const policyChannel = new PolicyChannel(accessor.get(IPolicyService)); - mainProcessElectronServer.registerChannel('policy', policyChannel); - sharedProcessClient.then(client => client.registerChannel('policy', policyChannel)); - // Local Files const diskFileSystemProvider = this.fileService.getProvider(Schemas.file); assertType(diskFileSystemProvider instanceof DiskFileSystemProvider); @@ -729,15 +702,6 @@ export class CodeApplication extends Disposable { mainProcessElectronServer.registerChannel(LOCAL_FILE_SYSTEM_CHANNEL_NAME, fileSystemProviderChannel); sharedProcessClient.then(client => client.registerChannel(LOCAL_FILE_SYSTEM_CHANNEL_NAME, fileSystemProviderChannel)); - // User Data Profiles - const userDataProfilesService = ProxyChannel.fromService(accessor.get(IUserDataProfilesMainService)); - mainProcessElectronServer.registerChannel('userDataProfiles', userDataProfilesService); - sharedProcessClient.then(client => client.registerChannel('userDataProfiles', userDataProfilesService)); - - // Request - const requestService = new RequestChannel(accessor.get(IRequestService)); - sharedProcessClient.then(client => client.registerChannel('request', requestService)); - // Update const updateChannel = new UpdateChannel(accessor.get(IUpdateService)); mainProcessElectronServer.registerChannel('update', updateChannel); @@ -900,13 +864,6 @@ export class CodeApplication extends Disposable { // or if no window is open (macOS only) shouldOpenInNewWindow ||= isMacintosh && windowsMainService.getWindowCount() === 0; - // Pass along edit session id - if (params.get('editSessionId') !== null) { - environmentService.editSessionId = params.get('editSessionId') ?? undefined; - params.delete('editSessionId'); - uri = uri.with({ query: params.toString() }); - } - // Check for URIs to open in window const windowOpenableFromProtocolLink = app.getWindowOpenableFromProtocolLink(uri); logService.trace('app#handleURL: windowOpenableFromProtocolLink = ', windowOpenableFromProtocolLink); @@ -1016,7 +973,6 @@ export class CodeApplication extends Disposable { cli: args, forceNewWindow: args['new-window'] || (!hasCliArgs && args['unity-launch']), diffMode: args.diff, - mergeMode: args.merge, noRecentEntry, waitMarkerFileURI, gotoLineMode: args.goto, @@ -1142,7 +1098,7 @@ export class CodeApplication extends Disposable { code: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'The type of shared process crash to understand the nature of the crash better.' }; visible: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether shared process window was visible or not.' }; shuttingdown: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Whether the application is shutting down when the crash happens.' }; - owner: 'bpasero'; + owner: 'bpaser'; comment: 'Event which fires whenever an error occurs in the shared process'; }; diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 54af9e0983..a2835de9b4 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -62,14 +62,6 @@ import { IStateMainService } from 'vs/platform/state/electron-main/state'; import { StateMainService } from 'vs/platform/state/electron-main/stateMainService'; import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils'; import { IThemeMainService, ThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; -import { IUserDataProfilesMainService, UserDataProfilesMainService } from 'vs/platform/userDataProfile/electron-main/userDataProfile'; -import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; -import { NativePolicyService } from 'vs/platform/policy/node/nativePolicyService'; -import { FilePolicyService } from 'vs/platform/policy/common/filePolicyService'; -import { DisposableStore } from 'vs/base/common/lifecycle'; -import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { PROFILES_ENABLEMENT_CONFIG } from 'vs/platform/userDataProfile/common/userDataProfile'; /** * The main VS Code entry point. @@ -97,13 +89,13 @@ class CodeMain { setUnexpectedErrorHandler(err => console.error(err)); // Create services - const [instantiationService, instanceEnvironment, environmentMainService, configurationService, stateMainService, bufferLogService, productService, userDataProfilesMainService] = this.createServices(); + const [instantiationService, instanceEnvironment, environmentMainService, configurationService, stateMainService, bufferLogService, productService] = this.createServices(); try { // Init services try { - await this.initServices(environmentMainService, userDataProfilesMainService, configurationService, stateMainService); + await this.initServices(environmentMainService, configurationService, stateMainService); } catch (error) { // Show a dialog for errors that can be resolved by the user @@ -145,10 +137,8 @@ class CodeMain { } } - private createServices(): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateMainService, BufferLogService, IProductService, UserDataProfilesMainService] { + private createServices(): [IInstantiationService, IProcessEnvironment, IEnvironmentMainService, ConfigurationService, StateMainService, BufferLogService, IProductService] { const services = new ServiceCollection(); - const disposables = new DisposableStore(); - process.once('exit', () => disposables.dispose()); // Product const productService = { _serviceBrand: undefined, ...product }; @@ -163,7 +153,8 @@ class CodeMain { // we are the only instance running, otherwise we'll have concurrent // log file access on Windows (https://github.com/microsoft/vscode/issues/41218) const bufferLogService = new BufferLogService(); - const logService = disposables.add(new MultiplexLogService([new ConsoleMainLogger(getLogLevel(environmentMainService)), bufferLogService])); + const logService = new MultiplexLogService([new ConsoleMainLogger(getLogLevel(environmentMainService)), bufferLogService]); + process.once('exit', () => logService.dispose()); services.set(ILogService, logService); // Files @@ -172,34 +163,20 @@ class CodeMain { const diskFileSystemProvider = new DiskFileSystemProvider(logService); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - // URI Identity - const uriIdentityService = new UriIdentityService(fileService); - services.set(IUriIdentityService, uriIdentityService); - // Logger services.set(ILoggerService, new LoggerService(logService, fileService)); - // State - const stateMainService = new StateMainService(environmentMainService, logService, fileService); - services.set(IStateMainService, stateMainService); - - // User Data Profiles - const userDataProfilesMainService = new UserDataProfilesMainService(stateMainService, uriIdentityService, environmentMainService, fileService, logService); - services.set(IUserDataProfilesMainService, userDataProfilesMainService); - - // Policy - const policyService = isWindows && productService.win32RegValueName ? disposables.add(new NativePolicyService(productService.win32RegValueName)) - : environmentMainService.policyFile ? disposables.add(new FilePolicyService(environmentMainService.policyFile, fileService, logService)) - : new NullPolicyService(); - services.set(IPolicyService, policyService); - // Configuration - const configurationService = new ConfigurationService(userDataProfilesMainService.defaultProfile.settingsResource, fileService, policyService, logService); + const configurationService = new ConfigurationService(environmentMainService.settingsResource, fileService); services.set(IConfigurationService, configurationService); // Lifecycle services.set(ILifecycleMainService, new SyncDescriptor(LifecycleMainService)); + // State + const stateMainService = new StateMainService(environmentMainService, logService, fileService); + services.set(IStateMainService, stateMainService); + // Request services.set(IRequestService, new SyncDescriptor(RequestMainService)); @@ -215,7 +192,7 @@ class CodeMain { // Protocol services.set(IProtocolMainService, new SyncDescriptor(ProtocolMainService)); - return [new InstantiationService(services, true), instanceEnvironment, environmentMainService, configurationService, stateMainService, bufferLogService, productService, userDataProfilesMainService]; + return [new InstantiationService(services, true), instanceEnvironment, environmentMainService, configurationService, stateMainService, bufferLogService, productService]; } private patchEnvironment(environmentMainService: IEnvironmentMainService): IProcessEnvironment { @@ -235,28 +212,26 @@ class CodeMain { return instanceEnvironment; } - private async initServices(environmentMainService: IEnvironmentMainService, userDataProfilesMainService: UserDataProfilesMainService, configurationService: ConfigurationService, stateMainService: StateMainService): Promise { - await Promises.settled([ + private initServices(environmentMainService: IEnvironmentMainService, configurationService: ConfigurationService, stateMainService: StateMainService): Promise { + return Promises.settled([ // Environment service (paths) Promise.all([ environmentMainService.extensionsPath, environmentMainService.codeCachePath, environmentMainService.logsPath, - userDataProfilesMainService.defaultProfile.globalStorageHome.fsPath, + environmentMainService.globalStorageHome.fsPath, environmentMainService.workspaceStorageHome.fsPath, environmentMainService.localHistoryHome.fsPath, environmentMainService.backupHome ].map(path => path ? FSPromises.mkdir(path, { recursive: true }) : undefined)), - // State service - stateMainService.init(), - // Configuration service - configurationService.initialize() - ]); + configurationService.initialize(), - userDataProfilesMainService.setEnablement(!!configurationService.getValue(PROFILES_ENABLEMENT_CONFIG)); + // State service + stateMainService.init() + ]); } private async claimInstance(logService: ILogService, environmentMainService: IEnvironmentMainService, lifecycleMainService: ILifecycleMainService, instantiationService: IInstantiationService, productService: IProductService, retry: boolean): Promise { diff --git a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts index 6bd8da6322..98e9947198 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterMain.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterMain.ts @@ -142,7 +142,6 @@ export class IssueReporter extends Disposable { this.updateExperimentsInfo(configuration.data.experiments); this.updateRestrictedMode(configuration.data.restrictedMode); this.updatePreviewFeaturesEnabled(configuration.data.previewFeaturesEnabled); // {{SQL CARBON EDIT}} Add preview features flag - this.updateUnsupportedMode(configuration.data.isUnsupported); } render(): void { @@ -1162,10 +1161,6 @@ export class IssueReporter extends Disposable { this.issueReporterModel.update({ previewFeaturesEnabled }); } - private updateUnsupportedMode(isUnsupported: boolean) { - this.issueReporterModel.update({ isUnsupported }); - } - private updateExperimentsInfo(experimentInfo: string | undefined) { this.issueReporterModel.update({ experimentInfo }); const target = document.querySelector('.block-experiments .block-info'); @@ -1209,15 +1204,21 @@ export class IssueReporter extends Disposable { private addEventListener(elementId: string, eventType: string, handler: (event: Event) => void): void { const element = this.getElementById(elementId); - element?.addEventListener(eventType, handler); + if (element) { + element.addEventListener(eventType, handler); + } } } // helper functions function hide(el: Element | undefined | null) { - el?.classList.add('hidden'); + if (el) { + el.classList.add('hidden'); + } } function show(el: Element | undefined | null) { - el?.classList.remove('hidden'); + if (el) { + el.classList.remove('hidden'); + } } diff --git a/src/vs/code/electron-sandbox/issue/issueReporterModel.ts b/src/vs/code/electron-sandbox/issue/issueReporterModel.ts index 1c7a2434cc..02922c15d7 100644 --- a/src/vs/code/electron-sandbox/issue/issueReporterModel.ts +++ b/src/vs/code/electron-sandbox/issue/issueReporterModel.ts @@ -34,7 +34,6 @@ export interface IssueReporterData { experimentInfo?: string; restrictedMode?: boolean; previewFeaturesEnabled?: boolean; // {{SQL CARBON EDIT}} Add preview features flag - isUnsupported?: boolean; } export class IssueReporterModel { @@ -64,15 +63,8 @@ export class IssueReporterModel { // {{SQL CARBON EDIT}} serialize(): string { - const modes = []; - if (this._data.restrictedMode) { - modes.push('Restricted'); - } - if (this._data.isUnsupported) { - modes.push('Unsupported'); - } return ` -Type: ${this.getIssueTypeTitle()} +Issue Type: ${this.getIssueTypeTitle()} ${this._data.issueDescription} ${this.getExtensionVersion()} @@ -80,7 +72,6 @@ Azure Data Studio version: ${this._data.versionInfo && this._data.versionInfo.vs OS version: ${this._data.versionInfo && this._data.versionInfo.os} Restricted Mode: ${this._data.restrictedMode ? 'Yes' : 'No'} Preview Features: ${this._data.previewFeaturesEnabled ? 'Enabled' : 'Disabled'} -Modes:${modes.length ? ' ' + modes.join(', ') : ''} ${this.getRemoteOSes()} ${this.getInfos()} `; diff --git a/src/vs/code/electron-sandbox/workbench/workbench.html b/src/vs/code/electron-sandbox/workbench/workbench.html index f34f6f6cd2..2a18556fce 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench.html +++ b/src/vs/code/electron-sandbox/workbench/workbench.html @@ -4,7 +4,7 @@ - + diff --git a/src/vs/code/electron-sandbox/workbench/workbench.js b/src/vs/code/electron-sandbox/workbench/workbench.js index ca0af36024..b77bc66b0b 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench.js +++ b/src/vs/code/electron-sandbox/workbench/workbench.js @@ -16,11 +16,10 @@ // Load workbench main JS, CSS and NLS all in parallel. This is an // optimization to prevent a waterfall of loading to happen, because - // we know for a fact that workbench.desktop.main will depend on + // we know for a fact that workbench.desktop.sandbox.main will depend on // the related CSS and NLS counterparts. bootstrapWindow.load([ - 'sql/setup', // {{SQL CARBON EDIT}} - 'vs/workbench/workbench.desktop.main', + 'vs/workbench/workbench.desktop.sandbox.main', 'vs/nls!vs/workbench/workbench.desktop.main', 'vs/css!vs/workbench/workbench.desktop.main' ], @@ -62,7 +61,7 @@ window.requestIdleCallback(() => { const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); - context?.clearRect(0, 0, canvas.width, canvas.height); + context.clearRect(0, 0, canvas.width, canvas.height); canvas.remove(); }, { timeout: 50 }); } diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 2cb321ab30..94ba236f85 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -8,7 +8,7 @@ import { chmodSync, existsSync, readFileSync, statSync, truncateSync, unlinkSync import { homedir, release, tmpdir } from 'os'; import type { ProfilingSession, Target } from 'v8-inspect-profiler'; import { Event } from 'vs/base/common/event'; -import { isAbsolute, resolve, join } from 'vs/base/common/path'; +import { isAbsolute, resolve } from 'vs/base/common/path'; import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform'; import { randomPort } from 'vs/base/common/ports'; import { isString } from 'vs/base/common/types'; @@ -24,8 +24,6 @@ import product from 'vs/platform/product/common/product'; import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { randomPath } from 'vs/base/common/extpath'; import { Utils } from 'vs/platform/profiling/common/profiling'; -import { dirname } from 'vs/base/common/resources'; -import { FileAccess } from 'vs/base/common/network'; function shouldSpawnCliProcess(argv: NativeParsedArgs): boolean { return !!argv['install-source'] @@ -61,21 +59,6 @@ export async function main(argv: string[]): Promise { console.log(buildVersionMessage(product.version, product.commit)); } - // Shell integration - else if (args['locate-shell-integration-path']) { - let file: string; - switch (args['locate-shell-integration-path']) { - // Usage: `[[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path bash)"` - case 'bash': file = 'shellIntegration-bash.sh'; break; - // Usage: `if ($env:TERM_PROGRAM -eq "vscode") { . "$(code --locate-shell-integration-path pwsh)" }` - case 'pwsh': file = 'shellIntegration.ps1'; break; - // Usage: `[[ "$TERM_PROGRAM" == "vscode" ]] && . "$(code --locate-shell-integration-path zsh)"` - case 'zsh': file = 'shellIntegration-rc.zsh'; break; - default: throw new Error('Error using --locate-shell-integration-path: Invalid shell type'); - } - console.log(join(dirname(FileAccess.asFileUri('', require)).fsPath, 'out', 'vs', 'workbench', 'contrib', 'terminal', 'browser', 'media', file)); - } - // Extensions Management else if (shouldSpawnCliProcess(args)) { const cli = await new Promise((resolve, reject) => require(['vs/code/node/cliProcessMain'], resolve, reject)); @@ -303,7 +286,7 @@ export async function main(argv: string[]): Promise { return; } let suffix = ''; - const result = await session.stop(); + let result = await session.stop(); if (!process.env['VSCODE_DEV']) { // when running from a not-development-build we remove // absolute filenames because we don't want to reveal anything diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index f1f28d0042..57634bf038 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -11,8 +11,8 @@ import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/err import { Disposable } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { isAbsolute, join } from 'vs/base/common/path'; -import { isWindows } from 'vs/base/common/platform'; import { cwd } from 'vs/base/common/process'; +import { joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; import { Promises } from 'vs/base/node/pfs'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; @@ -23,11 +23,10 @@ import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; import { NativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; import { ExtensionGalleryServiceWithNoStorageService } from 'vs/platform/extensionManagement/common/extensionGalleryService'; -import { IExtensionGalleryService, IExtensionManagementCLIService, InstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; +import { IExtensionGalleryService, IExtensionManagementCLIService, IExtensionManagementService, InstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ExtensionManagementCLIService } from 'vs/platform/extensionManagement/common/extensionManagementCLIService'; -import { ExtensionsProfileScannerService, IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService'; import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService'; -import { ExtensionManagementService, INativeServerExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; +import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService'; import { ExtensionsScannerService } from 'vs/platform/extensionManagement/node/extensionsScannerService'; import { IFileService } from 'vs/platform/files/common/files'; import { FileService } from 'vs/platform/files/common/fileService'; @@ -36,29 +35,22 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; -import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; -import { NativeLanguagePackService } from 'vs/platform/languagePacks/node/languagePacks'; +import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; +import { LocalizationsService } from 'vs/platform/localizations/node/localizations'; import { ConsoleLogger, getLogLevel, ILogger, ILogService, LogLevel, MultiplexLogService } from 'vs/platform/log/common/log'; import { SpdLogLogger } from 'vs/platform/log/node/spdlogLog'; -import { FilePolicyService } from 'vs/platform/policy/common/filePolicyService'; -import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/policy'; -import { NativePolicyService } from 'vs/platform/policy/node/nativePolicyService'; import product from 'vs/platform/product/common/product'; import { IProductService } from 'vs/platform/product/common/productService'; import { IRequestService } from 'vs/platform/request/common/request'; import { RequestService } from 'vs/platform/request/node/requestService'; -import { IStateService } from 'vs/platform/state/node/state'; -import { StateService } from 'vs/platform/state/node/stateService'; import { resolveCommonProperties } from 'vs/platform/telemetry/common/commonProperties'; import { ITelemetryService, machineIdKey } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; -import { supportsTelemetry, NullTelemetryService, getPiiPathsFromEnvironment, isInternalTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; +import { supportsTelemetry, NullTelemetryService, isInternalTelemetry, getPiiPathsFromEnvironment } from 'vs/platform/telemetry/common/telemetryUtils'; import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender'; import { buildTelemetryMessage } from 'vs/platform/telemetry/node/telemetry'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; -import { IUserDataProfilesService, PROFILES_ENABLEMENT_CONFIG } from 'vs/platform/userDataProfile/common/userDataProfile'; -import { UserDataProfilesService } from 'vs/platform/userDataProfile/node/userDataProfile'; class CliMain extends Disposable { @@ -136,35 +128,12 @@ class CliMain extends Disposable { const diskFileSystemProvider = this._register(new DiskFileSystemProvider(logService)); fileService.registerProvider(Schemas.file, diskFileSystemProvider); - // State - const stateService = new StateService(environmentService, logService, fileService); - services.set(IStateService, stateService); - - // Uri Identity - const uriIdentityService = new UriIdentityService(fileService); - services.set(IUriIdentityService, uriIdentityService); - - // User Data Profiles - const userDataProfilesService = new UserDataProfilesService(stateService, uriIdentityService, environmentService, fileService, logService); - services.set(IUserDataProfilesService, userDataProfilesService); - - // Policy - const policyService = isWindows && productService.win32RegValueName ? this._register(new NativePolicyService(productService.win32RegValueName)) - : environmentService.policyFile ? this._register(new FilePolicyService(environmentService.policyFile, fileService, logService)) - : new NullPolicyService(); - services.set(IPolicyService, policyService); - // Configuration - const configurationService = this._register(new ConfigurationService(userDataProfilesService.defaultProfile.settingsResource, fileService, policyService, logService)); + const configurationService = this._register(new ConfigurationService(environmentService.settingsResource, fileService)); services.set(IConfigurationService, configurationService); - // Initialize - await Promise.all([ - stateService.init(), - configurationService.initialize() - ]); - - userDataProfilesService.setEnablement(!!configurationService.getValue(PROFILES_ENABLEMENT_CONFIG)); + // Init config + await configurationService.initialize(); // URI Identity services.set(IUriIdentityService, new UriIdentityService(fileService)); @@ -176,14 +145,13 @@ class CliMain extends Disposable { services.set(IDownloadService, new SyncDescriptor(DownloadService)); // Extensions - services.set(IExtensionsProfileScannerService, new SyncDescriptor(ExtensionsProfileScannerService)); services.set(IExtensionsScannerService, new SyncDescriptor(ExtensionsScannerService)); - services.set(INativeServerExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); + services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryServiceWithNoStorageService)); services.set(IExtensionManagementCLIService, new SyncDescriptor(ExtensionManagementCLIService)); // Localizations - services.set(ILanguagePackService, new SyncDescriptor(NativeLanguagePackService)); + services.set(ILocalizationsService, new SyncDescriptor(LocalizationsService)); // Telemetry const appenders: OneDataSystemAppender[] = []; @@ -201,7 +169,7 @@ class CliMain extends Disposable { commonProperties: (async () => { let machineId: string | undefined = undefined; try { - const storageContents = await Promises.readFile(environmentService.stateResource.fsPath); + const storageContents = await Promises.readFile(joinPath(environmentService.globalStorageHome, 'storage.json').fsPath); machineId = JSON.parse(storageContents.toString())[machineIdKey]; } catch (error) { if (error.code !== 'ENOENT') { @@ -209,7 +177,7 @@ class CliMain extends Disposable { } } - return resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, machineId, isInternal, installSourcePath); + return resolveCommonProperties(fileService, release(), hostname(), process.arch, productService.commit, productService.version, machineId, productService.msftInternalDomains, installSourcePath); })(), piiPaths: getPiiPathsFromEnvironment(environmentService) }; diff --git a/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts b/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts index ce0eb14849..4c83f7de53 100644 --- a/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts +++ b/src/vs/code/test/electron-sandbox/issue/testReporterModel.test.ts @@ -27,7 +27,7 @@ suite('IssueReporter', () => { const issueReporterModel = new IssueReporterModel({}); assert.strictEqual(issueReporterModel.serialize(), ` -Type: Bug +Issue Type: Bug undefined @@ -35,7 +35,6 @@ Azure Data Studio version: undefined OS version: undefined Restricted Mode: No Preview Features: Disabled -Modes: Extensions: none `); @@ -60,7 +59,7 @@ Extensions: none }); assert.strictEqual(issueReporterModel.serialize(), ` -Type: Bug +Issue Type: Bug undefined @@ -68,7 +67,6 @@ Azure Data Studio version: undefined OS version: undefined Restricted Mode: No Preview Features: Disabled -Modes:
    System Info @@ -106,13 +104,13 @@ Modes: }); assert.strictEqual(issueReporterModel.serialize(), ` -Type: Bug +Issue Type: Bug undefined VS Code version: undefined OS version: undefined -Modes: +Restricted Mode: No
    System Info @@ -161,13 +159,13 @@ vsins829:30139715 }); assert.strictEqual(issueReporterModel.serialize(), ` -Type: Bug +Issue Type: Bug undefined VS Code version: undefined OS version: undefined -Modes: +Restricted Mode: No
    System Info @@ -218,13 +216,13 @@ Modes: }); assert.strictEqual(issueReporterModel.serialize(), ` -Type: Bug +Issue Type: Bug undefined VS Code version: undefined OS version: undefined -Modes: +Restricted Mode: No Remote OS version: Linux x64 4.18.0
    @@ -267,13 +265,13 @@ Remote OS version: Linux x64 4.18.0 }); assert.strictEqual(issueReporterModel.serialize(), ` -Type: Bug +Issue Type: Bug undefined VS Code version: undefined OS version: undefined -Modes: +Restricted Mode: No
    System Info @@ -291,26 +289,6 @@ Modes: `); }); - test('should supply mode if applicable', () => { // {{SQL CARBON EDIT}} Modifies test for ADS - const issueReporterModel = new IssueReporterModel({ - isUnsupported: true, - restrictedMode: true - }); - assert.strictEqual(issueReporterModel.serialize(), - ` -Type: Bug - -undefined - -Azure Data Studio version: undefined -OS version: undefined -Restricted Mode: Yes -Preview Features: Disabled -Modes: Restricted, Unsupported - -Extensions: none -`); - }); test('should normalize GitHub urls', () => { [ 'https://github.com/repo', diff --git a/src/vs/css.build.ts b/src/vs/css.build.ts deleted file mode 100644 index 45a11cc042..0000000000 --- a/src/vs/css.build.ts +++ /dev/null @@ -1,304 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -interface ICSSPluginConfig { - inlineResources?: boolean | 'base64'; - inlineResourcesLimit?: number; -} - -interface ICSSEntryPointData { - moduleName: string; - contents: string; - fsPath: string; -} - -// This file gets compiled also with the standalone editor, -// so we cannot depend on types from node.d.ts -interface INodeFS { - readFileSync(path: string, encoding: 'utf8'): string; - readFileSync(path: string): INodeBuffer; -} -interface INodeBuffer { - length: number; - toString(encoding?: 'base64'): string; -} -interface INodePath { - dirname(p: string): string; - join(...paths: string[]): string; -} - -const nodeReq = (module: string): T | undefined => { - if (typeof (require).__$__nodeRequire === 'function') { - return (require).__$__nodeRequire(module); - } - return undefined; -}; - -const fs = nodeReq('fs'); -const path = nodeReq('path'); - -let inlineResources: boolean | 'base64' = false; -let inlineResourcesLimit: number = 5000; - -const contentsMap: { [moduleName: string]: string } = {}; -const pathMap: { [moduleName: string]: string } = {}; -const entryPoints: { [entryPoint: string]: ICSSEntryPointData[] } = {}; -const inlinedResources: string[] = []; - -/** - * Invoked by the loader at build-time - */ -export function load(name: string, req: AMDLoader.IRelativeRequire, load: AMDLoader.IPluginLoadCallback, config: AMDLoader.IConfigurationOptions | { isBuild?: boolean }): void { // {{SQL CARBON EDIT}} Added type to config - if (!fs) { - throw new Error(`Cannot load files without 'fs'!`); - } - config = config || {}; - const myConfig = (config['vs/css'] || {}); - inlineResources = (typeof myConfig.inlineResources === 'undefined' ? false : myConfig.inlineResources); - inlineResourcesLimit = (myConfig.inlineResourcesLimit || 5000); - const cssUrl = req.toUrl(name + '.css'); - let contents = fs.readFileSync(cssUrl, 'utf8'); - if (contents.charCodeAt(0) === 65279 /* BOM */) { - // Remove BOM - contents = contents.substring(1); - } - if (config.isBuild) { - contentsMap[name] = contents; - pathMap[name] = cssUrl; - } - load({}); -} - -/** - * Invoked by the loader at build-time - */ -export function write(pluginName: string, moduleName: string, write: AMDLoader.IPluginWriteCallback): void { - const entryPoint = write.getEntryPoint(); - - entryPoints[entryPoint] = entryPoints[entryPoint] || []; - entryPoints[entryPoint].push({ - moduleName: moduleName, - contents: contentsMap[moduleName], - fsPath: pathMap[moduleName], - }); - - write.asModule(pluginName + '!' + moduleName, - 'define([\'vs/css!' + entryPoint + '\'], {});' - ); -} - -/** - * Invoked by the loader at build-time - */ -export function writeFile(pluginName: string, moduleName: string, req: AMDLoader.IRelativeRequire, write: AMDLoader.IPluginWriteFileCallback, config: AMDLoader.IConfigurationOptions): void { - if (entryPoints && entryPoints.hasOwnProperty(moduleName)) { - const fileName = req.toUrl(moduleName + '.css'); - const contents = [ - '/*---------------------------------------------------------', - ' * Copyright (c) Microsoft Corporation. All rights reserved.', - ' *--------------------------------------------------------*/' - ], - entries = entryPoints[moduleName]; - for (let i = 0; i < entries.length; i++) { - if (inlineResources) { - contents.push(rewriteOrInlineUrls(entries[i].fsPath, entries[i].moduleName, moduleName, entries[i].contents, inlineResources === 'base64', inlineResourcesLimit)); - } else { - contents.push(rewriteUrls(entries[i].moduleName, moduleName, entries[i].contents)); - } - } - write(fileName, contents.join('\r\n')); - } -} - -export function getInlinedResources(): string[] { - return inlinedResources || []; -} - -function rewriteOrInlineUrls(originalFileFSPath: string, originalFile: string, newFile: string, contents: string, forceBase64: boolean, inlineByteLimit: number): string { - if (!fs || !path) { - throw new Error(`Cannot rewrite or inline urls without 'fs' or 'path'!`); - } - return CSSPluginUtilities.replaceURL(contents, (url) => { - if (/\.(svg|png)$/.test(url)) { - const fsPath = path.join(path.dirname(originalFileFSPath), url); - const fileContents = fs.readFileSync(fsPath); - - if (fileContents.length < inlineByteLimit) { - const normalizedFSPath = fsPath.replace(/\\/g, '/'); - inlinedResources.push(normalizedFSPath); - - const MIME = /\.svg$/.test(url) ? 'image/svg+xml' : 'image/png'; - let DATA = ';base64,' + fileContents.toString('base64'); - - if (!forceBase64 && /\.svg$/.test(url)) { - // .svg => url encode as explained at https://codepen.io/tigt/post/optimizing-svgs-in-data-uris - const newText = fileContents.toString() - .replace(/"/g, '\'') - .replace(/%/g, '%25') - .replace(//g, '%3E') - .replace(/&/g, '%26') - .replace(/#/g, '%23') - .replace(/\s+/g, ' '); - const encodedData = ',' + newText; - if (encodedData.length < DATA.length) { - DATA = encodedData; - } - } - return '"data:' + MIME + DATA + '"'; - } - } - - const absoluteUrl = CSSPluginUtilities.joinPaths(CSSPluginUtilities.pathOf(originalFile), url); - return CSSPluginUtilities.relativePath(newFile, absoluteUrl); - }); -} - -export function rewriteUrls(originalFile: string, newFile: string, contents: string): string { - return CSSPluginUtilities.replaceURL(contents, (url) => { - const absoluteUrl = CSSPluginUtilities.joinPaths(CSSPluginUtilities.pathOf(originalFile), url); - return CSSPluginUtilities.relativePath(newFile, absoluteUrl); - }); -} - -export class CSSPluginUtilities { - - public static startsWith(haystack: string, needle: string): boolean { - return haystack.length >= needle.length && haystack.substr(0, needle.length) === needle; - } - - /** - * Find the path of a file. - */ - public static pathOf(filename: string): string { - const lastSlash = filename.lastIndexOf('/'); - if (lastSlash !== -1) { - return filename.substr(0, lastSlash + 1); - } else { - return ''; - } - } - - /** - * A conceptual a + b for paths. - * Takes into account if `a` contains a protocol. - * Also normalizes the result: e.g.: a/b/ + ../c => a/c - */ - public static joinPaths(a: string, b: string): string { - - function findSlashIndexAfterPrefix(haystack: string, prefix: string): number { - if (CSSPluginUtilities.startsWith(haystack, prefix)) { - return Math.max(prefix.length, haystack.indexOf('/', prefix.length)); - } - return 0; - } - - let aPathStartIndex = 0; - aPathStartIndex = aPathStartIndex || findSlashIndexAfterPrefix(a, '//'); - aPathStartIndex = aPathStartIndex || findSlashIndexAfterPrefix(a, 'http://'); - aPathStartIndex = aPathStartIndex || findSlashIndexAfterPrefix(a, 'https://'); - - function pushPiece(pieces: string[], piece: string): void { - if (piece === './') { - // Ignore - return; - } - if (piece === '../') { - const prevPiece = (pieces.length > 0 ? pieces[pieces.length - 1] : null); - if (prevPiece && prevPiece === '/') { - // Ignore - return; - } - if (prevPiece && prevPiece !== '../') { - // Pop - pieces.pop(); - return; - } - } - // Push - pieces.push(piece); - } - - function push(pieces: string[], path: string): void { - while (path.length > 0) { - const slashIndex = path.indexOf('/'); - const piece = (slashIndex >= 0 ? path.substring(0, slashIndex + 1) : path); - path = (slashIndex >= 0 ? path.substring(slashIndex + 1) : ''); - pushPiece(pieces, piece); - } - } - - let pieces: string[] = []; - push(pieces, a.substr(aPathStartIndex)); - if (b.length > 0 && b.charAt(0) === '/') { - pieces = []; - } - push(pieces, b); - - return a.substring(0, aPathStartIndex) + pieces.join(''); - } - - public static commonPrefix(str1: string, str2: string): string { - const len = Math.min(str1.length, str2.length); - for (let i = 0; i < len; i++) { - if (str1.charCodeAt(i) !== str2.charCodeAt(i)) { - return str1.substring(0, i); - } - } - return str1.substring(0, len); - } - - public static commonFolderPrefix(fromPath: string, toPath: string): string { - const prefix = CSSPluginUtilities.commonPrefix(fromPath, toPath); - const slashIndex = prefix.lastIndexOf('/'); - if (slashIndex === -1) { - return ''; - } - return prefix.substring(0, slashIndex + 1); - } - - public static relativePath(fromPath: string, toPath: string): string { - if (CSSPluginUtilities.startsWith(toPath, '/') || CSSPluginUtilities.startsWith(toPath, 'http://') || CSSPluginUtilities.startsWith(toPath, 'https://')) { - return toPath; - } - - // Ignore common folder prefix - const prefix = CSSPluginUtilities.commonFolderPrefix(fromPath, toPath); - fromPath = fromPath.substr(prefix.length); - toPath = toPath.substr(prefix.length); - - const upCount = fromPath.split('/').length; - let result = ''; - for (let i = 1; i < upCount; i++) { - result += '../'; - } - return result + toPath; - } - - public static replaceURL(contents: string, replacer: (url: string) => string): string { - // Use ")" as the terminator as quotes are oftentimes not used at all - return contents.replace(/url\(\s*([^\)]+)\s*\)?/g, (_: string, ...matches: string[]) => { - let url = matches[0]; - // Eliminate starting quotes (the initial whitespace is not captured) - if (url.charAt(0) === '"' || url.charAt(0) === '\'') { - url = url.substring(1); - } - // The ending whitespace is captured - while (url.length > 0 && (url.charAt(url.length - 1) === ' ' || url.charAt(url.length - 1) === '\t')) { - url = url.substring(0, url.length - 1); - } - // Eliminate ending quotes - if (url.charAt(url.length - 1) === '"' || url.charAt(url.length - 1) === '\'') { - url = url.substring(0, url.length - 1); - } - - if (!CSSPluginUtilities.startsWith(url, 'data:') && !CSSPluginUtilities.startsWith(url, 'http://') && !CSSPluginUtilities.startsWith(url, 'https://')) { - url = replacer(url); - } - - return 'url(' + url + ')'; - }); - } -} diff --git a/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts b/src/vs/css.d.ts similarity index 92% rename from src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts rename to src/vs/css.d.ts index f711cb84dc..e99b7c43cc 100644 --- a/src/vscode-dts/vscode.proposed.notebookKernelSource.d.ts +++ b/src/vs/css.d.ts @@ -3,5 +3,3 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -declare module 'vscode' { -} diff --git a/src/vs/css.js b/src/vs/css.js index ad8d37febd..6c64a99dba 100644 --- a/src/vs/css.js +++ b/src/vs/css.js @@ -16,6 +16,10 @@ 'use strict'; var CSSLoaderPlugin; (function (CSSLoaderPlugin) { + /** + * Known issue: + * - In IE there is no way to know if the CSS file loaded successfully or not. + */ var BrowserCSSLoader = /** @class */ (function () { function BrowserCSSLoader() { this._pendingLoads = 0; diff --git a/src/vs/css.ts b/src/vs/css.ts deleted file mode 100644 index 0cf0e755ea..0000000000 --- a/src/vs/css.ts +++ /dev/null @@ -1,81 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -interface ICSSPluginConfig { - disabled?: boolean; -} - -/** - * Invoked by the loader at run-time - */ -export function load(name: string, req: AMDLoader.IRelativeRequire, load: AMDLoader.IPluginLoadCallback, config: AMDLoader.IConfigurationOptions | { isBuild?: boolean }): void { // {{SQL CARBON EDIT}} Added type to config - config = config || {}; - const cssConfig = (config['vs/css'] || {}); - - if (cssConfig.disabled) { - // the plugin is asked to not create any style sheets - load({}); - return; - } - - const cssUrl = req.toUrl(name + '.css'); - loadCSS(name, cssUrl, () => { - load({}); - }, (err: any) => { - if (typeof load.error === 'function') { - load.error('Could not find ' + cssUrl + '.'); - } - }); -} - -function loadCSS(name: string, cssUrl: string, callback: () => void, errorback: (err: any) => void): void { - if (linkTagExists(name, cssUrl)) { - callback(); - return; - } - createLinkTag(name, cssUrl, callback, errorback); -} - -function linkTagExists(name: string, cssUrl: string): boolean { - const links = document.getElementsByTagName('link'); - for (let i = 0, len = links.length; i < len; i++) { - const nameAttr = links[i].getAttribute('data-name'); - const hrefAttr = links[i].getAttribute('href'); - if (nameAttr === name || hrefAttr === cssUrl) { - return true; - } - } - return false; -} - -function createLinkTag(name: string, cssUrl: string, callback: () => void, errorback: (err: any) => void): void { - const linkNode = document.createElement('link'); - linkNode.setAttribute('rel', 'stylesheet'); - linkNode.setAttribute('type', 'text/css'); - linkNode.setAttribute('data-name', name); - - attachListeners(name, linkNode, callback, errorback); - linkNode.setAttribute('href', cssUrl); - - const head = document.head || document.getElementsByTagName('head')[0]; - head.appendChild(linkNode); -} - -function attachListeners(name: string, linkNode: HTMLLinkElement, callback: () => void, errorback: (err: any) => void): void { - const unbind = () => { - linkNode.removeEventListener('load', loadEventListener); - linkNode.removeEventListener('error', errorEventListener); - }; - const loadEventListener = (e: any) => { - unbind(); - callback(); - }; - const errorEventListener = (e: any) => { - unbind(); - errorback(e); - }; - linkNode.addEventListener('load', loadEventListener); - linkNode.addEventListener('error', errorEventListener); -} diff --git a/src/vs/editor/browser/config/domFontInfo.ts b/src/vs/editor/browser/config/domFontInfo.ts index 8b63846129..85c93bfce8 100644 --- a/src/vs/editor/browser/config/domFontInfo.ts +++ b/src/vs/editor/browser/config/domFontInfo.ts @@ -3,19 +3,21 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as browser from 'vs/base/browser/browser'; import { FastDomNode } from 'vs/base/browser/fastDomNode'; +import { EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; export function applyFontInfo(domNode: FastDomNode | HTMLElement, fontInfo: BareFontInfo): void { if (domNode instanceof FastDomNode) { - domNode.setFontFamily(fontInfo.getMassagedFontFamily()); + domNode.setFontFamily(fontInfo.getMassagedFontFamily(browser.isSafari ? EDITOR_FONT_DEFAULTS.fontFamily : null)); domNode.setFontWeight(fontInfo.fontWeight); domNode.setFontSize(fontInfo.fontSize); domNode.setFontFeatureSettings(fontInfo.fontFeatureSettings); domNode.setLineHeight(fontInfo.lineHeight); domNode.setLetterSpacing(fontInfo.letterSpacing); } else { - domNode.style.fontFamily = fontInfo.getMassagedFontFamily(); + domNode.style.fontFamily = fontInfo.getMassagedFontFamily(browser.isSafari ? EDITOR_FONT_DEFAULTS.fontFamily : null); domNode.style.fontWeight = fontInfo.fontWeight; domNode.style.fontSize = fontInfo.fontSize + 'px'; domNode.style.fontFeatureSettings = fontInfo.fontFeatureSettings; diff --git a/src/vs/editor/browser/config/editorConfiguration.ts b/src/vs/editor/browser/config/editorConfiguration.ts index 89ee977c55..353d5aac1e 100644 --- a/src/vs/editor/browser/config/editorConfiguration.ts +++ b/src/vs/editor/browser/config/editorConfiguration.ts @@ -30,6 +30,12 @@ export interface IEditorConstructionOptions extends IEditorOptions { * Defaults to an internal DOM node. */ overflowWidgetsDomNode?: HTMLElement; + /** + * Enables dropping into the editor. + * + * This shows a preview of the drop location and triggers an `onDropIntoEditor` event. + */ + enableDropIntoEditor?: boolean; } export class EditorConfiguration extends Disposable implements IEditorConfiguration { diff --git a/src/vs/editor/browser/config/fontMeasurements.ts b/src/vs/editor/browser/config/fontMeasurements.ts index f2d25f4f42..424668ebb8 100644 --- a/src/vs/editor/browser/config/fontMeasurements.ts +++ b/src/vs/editor/browser/config/fontMeasurements.ts @@ -149,7 +149,9 @@ class FontMeasurementsImpl extends Disposable { private _createRequest(chr: string, type: CharWidthRequestType, all: CharWidthRequest[], monospace: CharWidthRequest[] | null): CharWidthRequest { const result = new CharWidthRequest(chr, type); all.push(result); - monospace?.push(result); + if (monospace) { + monospace.push(result); + } return result; } diff --git a/src/vs/editor/browser/config/migrateOptions.ts b/src/vs/editor/browser/config/migrateOptions.ts index 723a082497..1b519aa3c3 100644 --- a/src/vs/editor/browser/config/migrateOptions.ts +++ b/src/vs/editor/browser/config/migrateOptions.ts @@ -3,6 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { forEach } from 'vs/base/common/collections'; import { IEditorOptions } from 'vs/editor/common/config/editorOptions'; export interface ISettingsReader { @@ -151,22 +152,14 @@ const suggestFilteredTypesMapping: Record = { registerEditorSettingMigration('suggest.filteredTypes', (value, read, write) => { if (value && typeof value === 'object') { - for (const entry of Object.entries(suggestFilteredTypesMapping)) { - const v = value[entry[0]]; + forEach(suggestFilteredTypesMapping, entry => { + const v = value[entry.key]; if (v === false) { - if (typeof read(`suggest.${entry[1]}`) === 'undefined') { - write(`suggest.${entry[1]}`, false); + if (typeof read(`suggest.${entry.value}`) === 'undefined') { + write(`suggest.${entry.value}`, false); } } - } + }); write('suggest.filteredTypes', undefined); } }); - -registerEditorSettingMigration('quickSuggestions', (input, read, write) => { - if (typeof input === 'boolean') { - const value = input ? 'on' : 'off'; - const newValue = { comments: value, strings: value, other: value }; - write('quickSuggestions', newValue); - } -}); diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index ac5875a20c..8c5e924b78 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -6,7 +6,7 @@ import * as dom from 'vs/base/browser/dom'; import { StandardWheelEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent'; import { TimeoutTimer } from 'vs/base/common/async'; -import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { HitTestContext, MouseTarget, MouseTargetFactory, PointerHandlerLastRenderData } from 'vs/editor/browser/controller/mouseTarget'; import { IMouseTarget, IMouseTargetViewZoneData, MouseTargetType } from 'vs/editor/browser/editorBrowser'; @@ -21,6 +21,22 @@ import * as viewEvents from 'vs/editor/common/viewEvents'; import { ViewEventHandler } from 'vs/editor/common/viewEventHandler'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; +/** + * Merges mouse events when mouse move events are throttled + */ +export function createMouseMoveEventMerger(mouseTargetFactory: MouseTargetFactory | null) { + return function (lastEvent: EditorMouseEvent | null, currentEvent: EditorMouseEvent): EditorMouseEvent { + let targetIsWidget = false; + if (mouseTargetFactory) { + targetIsWidget = mouseTargetFactory.mouseTargetIsWidget(currentEvent); + } + if (!targetIsWidget) { + currentEvent.preventDefault(); + } + return currentEvent; + }; +} + export interface IPointerHandlerHelper { viewDomNode: HTMLElement; linesContentDomNode: HTMLElement; @@ -48,6 +64,8 @@ export interface IPointerHandlerHelper { export class MouseHandler extends ViewEventHandler { + static readonly MOUSE_MOVE_MINIMUM_TIME = 100; // ms + protected _context: ViewContext; protected viewController: ViewController; protected viewHelper: IPointerHandlerHelper; @@ -55,7 +73,6 @@ export class MouseHandler extends ViewEventHandler { protected readonly _mouseDownOperation: MouseDownOperation; private lastMouseLeaveTime: number; private _height: number; - private _mouseLeaveMonitor: IDisposable | null = null; constructor(context: ViewContext, viewController: ViewController, viewHelper: IPointerHandlerHelper) { super(); @@ -80,25 +97,9 @@ export class MouseHandler extends ViewEventHandler { this._register(mouseEvents.onContextMenu(this.viewHelper.viewDomNode, (e) => this._onContextMenu(e, true))); - this._register(mouseEvents.onMouseMove(this.viewHelper.viewDomNode, (e) => { - this._onMouseMove(e); - - // See https://github.com/microsoft/vscode/issues/138789 - // When moving the mouse really quickly, the browser sometimes forgets to - // send us a `mouseleave` or `mouseout` event. We therefore install here - // a global `mousemove` listener to manually recover if the mouse goes outside - // the editor. As soon as the mouse leaves outside of the editor, we - // remove this listener - - if (!this._mouseLeaveMonitor) { - this._mouseLeaveMonitor = dom.addDisposableListener(document, 'mousemove', (e) => { - if (!this.viewHelper.viewDomNode.contains(e.target as Node | null)) { - // went outside the editor! - this._onMouseLeave(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode)); - } - }); - } - })); + this._register(mouseEvents.onMouseMoveThrottled(this.viewHelper.viewDomNode, + (e) => this._onMouseMove(e), + createMouseMoveEventMerger(this.mouseTargetFactory), MouseHandler.MOUSE_MOVE_MINIMUM_TIME)); this._register(mouseEvents.onMouseUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e))); @@ -108,9 +109,11 @@ export class MouseHandler extends ViewEventHandler { // because their `e.detail` is always 0. // We will therefore save the pointer id for the mouse and then reuse it in the `mousedown` event // for `element.setPointerCapture`. - let capturePointerId: number = 0; - this._register(mouseEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => { - capturePointerId = pointerId; + let mousePointerId: number = 0; + this._register(mouseEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerType, pointerId) => { + if (pointerType === 'mouse') { + mousePointerId = pointerId; + } })); // The `pointerup` listener registered by `GlobalEditorPointerMoveMonitor` does not get invoked 100% of the times. // I speculate that this is because the `pointerup` listener is only registered during the `mousedown` event, and perhaps @@ -120,7 +123,7 @@ export class MouseHandler extends ViewEventHandler { this._register(dom.addDisposableListener(this.viewHelper.viewDomNode, dom.EventType.POINTER_UP, (e: PointerEvent) => { this._mouseDownOperation.onPointerUp(); })); - this._register(mouseEvents.onMouseDown(this.viewHelper.viewDomNode, (e) => this._onMouseDown(e, capturePointerId))); + this._register(mouseEvents.onMouseDown(this.viewHelper.viewDomNode, (e) => this._onMouseDown(e, mousePointerId))); const onMouseWheel = (browserEvent: IMouseWheelEvent) => { this.viewController.emitMouseWheel(browserEvent); @@ -151,10 +154,6 @@ export class MouseHandler extends ViewEventHandler { public override dispose(): void { this._context.removeEventHandler(this); - if (this._mouseLeaveMonitor) { - this._mouseLeaveMonitor.dispose(); - this._mouseLeaveMonitor = null; - } super.dispose(); } @@ -221,11 +220,6 @@ export class MouseHandler extends ViewEventHandler { } public _onMouseMove(e: EditorMouseEvent): void { - const targetIsWidget = this.mouseTargetFactory.mouseTargetIsWidget(e); - if (!targetIsWidget) { - e.preventDefault(); - } - if (this._mouseDownOperation.isActive()) { // In selection/drag operation return; @@ -243,10 +237,6 @@ export class MouseHandler extends ViewEventHandler { } public _onMouseLeave(e: EditorMouseEvent): void { - if (this._mouseLeaveMonitor) { - this._mouseLeaveMonitor.dispose(); - this._mouseLeaveMonitor = null; - } this.lastMouseLeaveTime = (new Date()).getTime(); this.viewController.emitMouseLeave({ event: e, @@ -414,6 +404,7 @@ class MouseDownOperation extends Disposable { this._viewHelper.viewLinesDomNode, pointerId, e.buttons, + createMouseMoveEventMerger(null), (e) => this._onMouseDownThenMove(e), (browserEvent?: MouseEvent | KeyboardEvent) => { const position = this._findMousePosition(this._lastMouseEvent!, false); @@ -444,6 +435,7 @@ class MouseDownOperation extends Disposable { this._viewHelper.viewLinesDomNode, pointerId, e.buttons, + createMouseMoveEventMerger(null), (e) => this._onMouseDownThenMove(e), () => this._stop() ); diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index 1c265289f9..46fcbb24f5 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -823,21 +823,7 @@ export class MouseTargetFactory { const curr = points[i]; if (prev.offset <= request.mouseContentHorizontalOffset && request.mouseContentHorizontalOffset <= curr.offset) { const rng = new EditorRange(lineNumber, prev.column, lineNumber, curr.column); - - // See https://github.com/microsoft/vscode/issues/152819 - // Due to the use of zwj, the browser's hit test result is skewed towards the left - // Here we try to correct that if the mouse horizontal offset is closer to the right than the left - - const prevDelta = Math.abs(prev.offset - request.mouseContentHorizontalOffset); - const nextDelta = Math.abs(curr.offset - request.mouseContentHorizontalOffset); - - const resultPos = ( - prevDelta < nextDelta - ? new Position(lineNumber, prev.column) - : new Position(lineNumber, curr.column) - ); - - return request.fulfillContentText(resultPos, rng, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText }); + return request.fulfillContentText(pos, rng, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText }); } } return request.fulfillContentText(pos, null, { mightBeForeignElement: !mouseIsOverSpanNode || !!injectedText, injectedText }); diff --git a/src/vs/editor/browser/controller/pointerHandler.ts b/src/vs/editor/browser/controller/pointerHandler.ts index e52b61d5fa..81be5b6433 100644 --- a/src/vs/editor/browser/controller/pointerHandler.ts +++ b/src/vs/editor/browser/controller/pointerHandler.ts @@ -7,7 +7,7 @@ import * as dom from 'vs/base/browser/dom'; import * as platform from 'vs/base/common/platform'; import { EventType, Gesture, GestureEvent } from 'vs/base/browser/touch'; import { Disposable } from 'vs/base/common/lifecycle'; -import { IPointerHandlerHelper, MouseHandler } from 'vs/editor/browser/controller/mouseHandler'; +import { IPointerHandlerHelper, MouseHandler, createMouseMoveEventMerger } from 'vs/editor/browser/controller/mouseHandler'; import { IMouseTarget, MouseTargetType } from 'vs/editor/browser/editorBrowser'; import { EditorMouseEvent, EditorPointerEventFactory } from 'vs/editor/browser/editorDom'; import { ViewController } from 'vs/editor/browser/view/viewController'; @@ -45,7 +45,9 @@ export class PointerEventHandler extends MouseHandler { // PonterEvents const pointerEvents = new EditorPointerEventFactory(this.viewHelper.viewDomNode); - this._register(pointerEvents.onPointerMove(this.viewHelper.viewDomNode, (e) => this._onMouseMove(e))); + this._register(pointerEvents.onPointerMoveThrottled(this.viewHelper.viewDomNode, + (e) => this._onMouseMove(e), + createMouseMoveEventMerger(this.mouseTargetFactory), MouseHandler.MOUSE_MOVE_MINIMUM_TIME)); this._register(pointerEvents.onPointerUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e))); this._register(pointerEvents.onPointerLeave(this.viewHelper.viewDomNode, (e) => this._onMouseLeave(e))); this._register(pointerEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => this._onMouseDown(e, pointerId))); diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index c352bf4985..2bb33282d9 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -31,8 +31,7 @@ import * as viewEvents from 'vs/editor/common/viewEvents'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { IEditorAriaOptions } from 'vs/editor/browser/editorBrowser'; import { MOUSE_CURSOR_TEXT_CSS_CLASS_NAME } from 'vs/base/browser/ui/mouseCursor/mouseCursor'; -import { TokenizationRegistry } from 'vs/editor/common/languages'; -import { ColorId, ITokenPresentation } from 'vs/editor/common/encodedTokenAttributes'; +import { ColorId, ITokenPresentation, TokenizationRegistry } from 'vs/editor/common/languages'; import { Color } from 'vs/base/common/color'; export interface IVisibleRangeProvider { @@ -522,7 +521,7 @@ export class TextAreaHandler extends ViewPart { this._accessibilitySupport = options.get(EditorOption.accessibilitySupport); const accessibilityPageSize = options.get(EditorOption.accessibilityPageSize); if (this._accessibilitySupport === AccessibilitySupport.Enabled && accessibilityPageSize === EditorOptions.accessibilityPageSize.defaultValue) { - // If a screen reader is attached and the default value is not set we should automatically increase the page size to 500 for a better experience + // If a screen reader is attached and the default value is not set we shuold automatically increase the page size to 500 for a better experience this._accessibilityPageSize = 500; } else { this._accessibilityPageSize = accessibilityPageSize; @@ -634,7 +633,9 @@ export class TextAreaHandler extends ViewPart { public prepareRender(ctx: RenderingContext): void { this._primaryCursorPosition = new Position(this._selections[0].positionLineNumber, this._selections[0].positionColumn); this._primaryCursorVisibleRange = ctx.visibleRangeForPosition(this._primaryCursorPosition); - this._visibleTextArea?.prepareRender(ctx); + if (this._visibleTextArea) { + this._visibleTextArea.prepareRender(ctx); + } } public render(ctx: RestrictedRenderingContext): void { diff --git a/src/vs/editor/browser/coreCommands.ts b/src/vs/editor/browser/coreCommands.ts index 37a6088f9c..228b1c6e5f 100644 --- a/src/vs/editor/browser/coreCommands.ts +++ b/src/vs/editor/browser/coreCommands.ts @@ -84,7 +84,7 @@ export namespace EditorScroll_ { \`\`\` * 'by': Unit to move. Default is computed based on 'to' value. \`\`\` - 'line', 'wrappedLine', 'page', 'halfPage', 'editor' + 'line', 'wrappedLine', 'page', 'halfPage' \`\`\` * 'value': Number of units to move. Default is '1'. * 'revealCursor': If 'true' reveals the cursor if it is outside view port. @@ -100,7 +100,7 @@ export namespace EditorScroll_ { }, 'by': { 'type': 'string', - 'enum': ['line', 'wrappedLine', 'page', 'halfPage', 'editor'] + 'enum': ['line', 'wrappedLine', 'page', 'halfPage'] }, 'value': { 'type': 'number', @@ -130,8 +130,7 @@ export namespace EditorScroll_ { Line: 'line', WrappedLine: 'wrappedLine', Page: 'page', - HalfPage: 'halfPage', - Editor: 'editor' + HalfPage: 'halfPage' }; /** @@ -173,9 +172,6 @@ export namespace EditorScroll_ { case RawUnit.HalfPage: unit = Unit.HalfPage; break; - case RawUnit.Editor: - unit = Unit.Editor; - break; default: unit = Unit.WrappedLine; } @@ -209,8 +205,7 @@ export namespace EditorScroll_ { Line = 1, WrappedLine = 2, Page = 3, - HalfPage = 4, - Editor = 5 + HalfPage = 4 } } @@ -1284,14 +1279,6 @@ export namespace CoreNavigationCommands { return viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber); } - if (args.unit === EditorScroll_.Unit.Editor) { - let desiredTopModelLineNumber = 0; - if (args.direction === EditorScroll_.Direction.Down) { - desiredTopModelLineNumber = viewModel.model.getLineCount() - viewModel.cursorConfig.pageSize; - } - return viewModel.viewLayout.getVerticalOffsetForLineNumber(desiredTopModelLineNumber); - } - let noOfLines: number; if (args.unit === EditorScroll_.Unit.Page) { noOfLines = viewModel.cursorConfig.pageSize * args.value; @@ -1358,29 +1345,6 @@ export namespace CoreNavigationCommands { } }); - export const ScrollEditorTop: CoreEditorCommand = registerEditorCommand(new class extends CoreEditorCommand { - constructor() { - super({ - id: 'scrollEditorTop', - precondition: undefined, - kbOpts: { - weight: CORE_WEIGHT, - kbExpr: EditorContextKeys.textInputFocus, - } - }); - } - - runCoreEditorCommand(viewModel: IViewModel, args: any): void { - EditorScroll._runEditorScroll(viewModel, args.source, { - direction: EditorScroll_.Direction.Up, - unit: EditorScroll_.Unit.Editor, - value: 1, - revealCursor: false, - select: false - }); - } - }); - export const ScrollLineDown: CoreEditorCommand = registerEditorCommand(new class extends CoreEditorCommand { constructor() { super({ @@ -1432,29 +1396,6 @@ export namespace CoreNavigationCommands { } }); - export const ScrollEditorBottom: CoreEditorCommand = registerEditorCommand(new class extends CoreEditorCommand { - constructor() { - super({ - id: 'scrollEditorBottom', - precondition: undefined, - kbOpts: { - weight: CORE_WEIGHT, - kbExpr: EditorContextKeys.textInputFocus, - } - }); - } - - runCoreEditorCommand(viewModel: IViewModel, args: any): void { - EditorScroll._runEditorScroll(viewModel, args.source, { - direction: EditorScroll_.Direction.Down, - unit: EditorScroll_.Unit.Editor, - value: 1, - revealCursor: false, - select: false - }); - } - }); - class WordCommand extends CoreEditorCommand { private readonly _inSelectionMode: boolean; diff --git a/src/vs/editor/browser/dnd.ts b/src/vs/editor/browser/dnd.ts deleted file mode 100644 index 542a05e64f..0000000000 --- a/src/vs/editor/browser/dnd.ts +++ /dev/null @@ -1,76 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { DataTransfers } from 'vs/base/browser/dnd'; -import { distinct } from 'vs/base/common/arrays'; -import { createFileDataTransferItem, createStringDataTransferItem, IDataTransferItem, VSDataTransfer } from 'vs/base/common/dataTransfer'; -import { Mimes } from 'vs/base/common/mime'; -import { URI } from 'vs/base/common/uri'; -import { CodeDataTransfers, extractEditorsDropData, FileAdditionalNativeProperties } from 'vs/platform/dnd/browser/dnd'; - - -export function toVSDataTransfer(dataTransfer: DataTransfer) { - const vsDataTransfer = new VSDataTransfer(); - for (const item of dataTransfer.items) { - const type = item.type; - if (item.kind === 'string') { - const asStringValue = new Promise(resolve => item.getAsString(resolve)); - vsDataTransfer.append(type, createStringDataTransferItem(asStringValue)); - } else if (item.kind === 'file') { - const file = item.getAsFile(); - if (file) { - vsDataTransfer.append(type, createFileDataTransferItemFromFile(file)); - } - } - } - return vsDataTransfer; -} - -export function createFileDataTransferItemFromFile(file: File): IDataTransferItem { - const uri = (file as FileAdditionalNativeProperties).path ? URI.parse((file as FileAdditionalNativeProperties).path!) : undefined; - return createFileDataTransferItem(file.name, uri, async () => { - return new Uint8Array(await file.arrayBuffer()); - }); -} - -const INTERNAL_DND_MIME_TYPES = Object.freeze([ - CodeDataTransfers.EDITORS, - CodeDataTransfers.FILES, - DataTransfers.RESOURCES, -]); - -export function addExternalEditorsDropData(dataTransfer: VSDataTransfer, dragEvent: DragEvent, overwriteUriList = false) { - if (dragEvent.dataTransfer && (overwriteUriList || !dataTransfer.has(Mimes.uriList))) { - const editorData = extractEditorsDropData(dragEvent) - .filter(input => input.resource) - .map(input => input.resource!.toString()); - - // Also add in the files - for (const item of dragEvent.dataTransfer?.items) { - const file = item.getAsFile(); - if (file) { - editorData.push((file as FileAdditionalNativeProperties).path ? URI.file((file as FileAdditionalNativeProperties).path!).toString() : file.name); - } - } - - if (editorData.length) { - dataTransfer.replace(Mimes.uriList, createStringDataTransferItem(UriList.create(editorData))); - } - } - - for (const internal of INTERNAL_DND_MIME_TYPES) { - dataTransfer.delete(internal); - } -} - -export const UriList = Object.freeze({ - // http://amundsen.com/hypermedia/urilist/ - create: (entries: ReadonlyArray): string => { - return distinct(entries.map(x => x.toString())).join('\r\n'); - }, - parse: (str: string): string[] => { - return str.split('\r\n').filter(value => !value.startsWith('#')); - } -}); diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index cb63b590ae..570ecbdec7 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -681,7 +681,7 @@ export interface ICodeEditor extends editorCommon.IEditor { /** * Restores the view state of the editor from a serializable object generated by `saveViewState`. */ - restoreViewState(state: editorCommon.ICodeEditorViewState | null): void; + restoreViewState(state: editorCommon.ICodeEditorViewState): void; /** * Returns true if the text inside this editor or an editor widget has focus. @@ -852,29 +852,24 @@ export interface ICodeEditor extends editorCommon.IEditor { /** * All decorations added through this call will get the ownerId of this editor. - * @deprecated + * @see {@link ITextModel.deltaDecorations} */ deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[]; /** - * Remove previously added decorations. + * @internal */ - removeDecorations(decorationIds: string[]): void; + setDecorations(description: string, decorationTypeKey: string, ranges: editorCommon.IDecorationOptions[]): void; /** * @internal */ - setDecorationsByType(description: string, decorationTypeKey: string, ranges: editorCommon.IDecorationOptions[]): void; + setDecorationsFast(decorationTypeKey: string, ranges: IRange[]): void; /** * @internal */ - setDecorationsByTypeFast(decorationTypeKey: string, ranges: IRange[]): void; - - /** - * @internal - */ - removeDecorationsByType(decorationTypeKey: string): void; + removeDecorations(decorationTypeKey: string): void; /** * Get the layout info for the editor. @@ -899,15 +894,10 @@ export interface ICodeEditor extends editorCommon.IEditor { getWhitespaces(): IEditorWhitespace[]; /** - * Get the vertical position (top offset) for the line's top w.r.t. to the first line. + * Get the vertical position (top offset) for the line w.r.t. to the first line. */ getTopForLineNumber(lineNumber: number): number; - /** - * Get the vertical position (top offset) for the line's bottom w.r.t. to the first line. - */ - getBottomForLineNumber(lineNumber: number): number; - /** * Get the vertical position (top offset) for the position w.r.t. to the first line. */ @@ -1126,7 +1116,7 @@ export interface IDiffEditor extends editorCommon.IEditor { /** * Restores the view state of the editor from a serializable object generated by `saveViewState`. */ - restoreViewState(state: editorCommon.IDiffEditorViewState | null): void; + restoreViewState(state: editorCommon.IDiffEditorViewState): void; /** * Type the getModel() of IEditor. diff --git a/src/vs/editor/browser/editorDom.ts b/src/vs/editor/browser/editorDom.ts index 916a7ea9fa..fa1e28f19f 100644 --- a/src/vs/editor/browser/editorDom.ts +++ b/src/vs/editor/browser/editorDom.ts @@ -136,6 +136,10 @@ export class EditorMouseEvent extends StandardMouseEvent { } } +export interface EditorMouseEventMerger { + (lastEvent: EditorMouseEvent | null, currentEvent: EditorMouseEvent): EditorMouseEvent; +} + export class EditorMouseEventFactory { private readonly _editorViewDomNode: HTMLElement; @@ -166,20 +170,23 @@ export class EditorMouseEventFactory { }); } - public onPointerDown(target: HTMLElement, callback: (e: EditorMouseEvent, pointerId: number) => void): IDisposable { + public onPointerDown(target: HTMLElement, callback: (e: EditorMouseEvent, pointerType: string, pointerId: number) => void): IDisposable { return dom.addDisposableListener(target, dom.EventType.POINTER_DOWN, (e: PointerEvent) => { - callback(this._create(e), e.pointerId); + callback(this._create(e), e.pointerType, e.pointerId); }); } public onMouseLeave(target: HTMLElement, callback: (e: EditorMouseEvent) => void): IDisposable { - return dom.addDisposableListener(target, dom.EventType.MOUSE_LEAVE, (e: MouseEvent) => { + return dom.addDisposableNonBubblingMouseOutListener(target, (e: MouseEvent) => { callback(this._create(e)); }); } - public onMouseMove(target: HTMLElement, callback: (e: EditorMouseEvent) => void): IDisposable { - return dom.addDisposableListener(target, 'mousemove', (e) => callback(this._create(e))); + public onMouseMoveThrottled(target: HTMLElement, callback: (e: EditorMouseEvent) => void, merger: EditorMouseEventMerger, minimumTimeMs: number): IDisposable { + const myMerger: dom.IEventMerger = (lastEvent: EditorMouseEvent | null, currentEvent: MouseEvent): EditorMouseEvent => { + return merger(lastEvent, this._create(currentEvent)); + }; + return dom.addDisposableThrottledListener(target, 'mousemove', callback, myMerger, minimumTimeMs); } } @@ -208,26 +215,29 @@ export class EditorPointerEventFactory { } public onPointerLeave(target: HTMLElement, callback: (e: EditorMouseEvent) => void): IDisposable { - return dom.addDisposableListener(target, dom.EventType.POINTER_LEAVE, (e: MouseEvent) => { + return dom.addDisposableNonBubblingPointerOutListener(target, (e: MouseEvent) => { callback(this._create(e)); }); } - public onPointerMove(target: HTMLElement, callback: (e: EditorMouseEvent) => void): IDisposable { - return dom.addDisposableListener(target, 'pointermove', (e) => callback(this._create(e))); + public onPointerMoveThrottled(target: HTMLElement, callback: (e: EditorMouseEvent) => void, merger: EditorMouseEventMerger, minimumTimeMs: number): IDisposable { + const myMerger: dom.IEventMerger = (lastEvent: EditorMouseEvent | null, currentEvent: MouseEvent): EditorMouseEvent => { + return merger(lastEvent, this._create(currentEvent)); + }; + return dom.addDisposableThrottledListener(target, 'pointermove', callback, myMerger, minimumTimeMs); } } export class GlobalEditorPointerMoveMonitor extends Disposable { private readonly _editorViewDomNode: HTMLElement; - private readonly _globalPointerMoveMonitor: GlobalPointerMoveMonitor; + private readonly _globalPointerMoveMonitor: GlobalPointerMoveMonitor; private _keydownListener: IDisposable | null; constructor(editorViewDomNode: HTMLElement) { super(); this._editorViewDomNode = editorViewDomNode; - this._globalPointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); + this._globalPointerMoveMonitor = this._register(new GlobalPointerMoveMonitor()); this._keydownListener = null; } @@ -235,6 +245,7 @@ export class GlobalEditorPointerMoveMonitor extends Disposable { initialElement: Element, pointerId: number, initialButtons: number, + merger: EditorMouseEventMerger, pointerMoveCallback: (e: EditorMouseEvent) => void, onStopCallback: (browserEvent?: PointerEvent | KeyboardEvent) => void ): void { @@ -250,18 +261,14 @@ export class GlobalEditorPointerMoveMonitor extends Disposable { this._globalPointerMoveMonitor.stopMonitoring(true, e.browserEvent); }, true); - this._globalPointerMoveMonitor.startMonitoring( - initialElement, - pointerId, - initialButtons, - (e) => { - pointerMoveCallback(new EditorMouseEvent(e, true, this._editorViewDomNode)); - }, - (e) => { - this._keydownListener!.dispose(); - onStopCallback(e); - } - ); + const myMerger: dom.IEventMerger = (lastEvent: EditorMouseEvent | null, currentEvent: PointerEvent): EditorMouseEvent => { + return merger(lastEvent, new EditorMouseEvent(currentEvent, true, this._editorViewDomNode)); + }; + + this._globalPointerMoveMonitor.startMonitoring(initialElement, pointerId, initialButtons, myMerger, pointerMoveCallback, (e) => { + this._keydownListener!.dispose(); + onStopCallback(e); + }); } public stopMonitoring(): void { diff --git a/src/vs/editor/browser/editorExtensions.ts b/src/vs/editor/browser/editorExtensions.ts index 83f10f46d7..afc18bd15f 100644 --- a/src/vs/editor/browser/editorExtensions.ts +++ b/src/vs/editor/browser/editorExtensions.ts @@ -338,10 +338,8 @@ export abstract class EditorAction extends EditorCommand { protected reportTelemetry(accessor: ServicesAccessor, editor: ICodeEditor) { type EditorActionInvokedClassification = { - owner: 'alexdima'; - comment: 'An editor action has been invoked.'; - name: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The label of the action that was invoked.' }; - id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The identifier of the action that was invoked.' }; + name: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; + id: { classification: 'SystemMetaData'; purpose: 'FeatureInsight' }; }; type EditorActionInvokedEvent = { name: string; diff --git a/src/vs/editor/browser/services/abstractCodeEditorService.ts b/src/vs/editor/browser/services/abstractCodeEditorService.ts index 510f67c4f8..9b488fb02b 100644 --- a/src/vs/editor/browser/services/abstractCodeEditorService.ts +++ b/src/vs/editor/browser/services/abstractCodeEditorService.ts @@ -5,12 +5,11 @@ import * as dom from 'vs/base/browser/dom'; import { Emitter, Event } from 'vs/base/common/event'; -import { IDisposable, DisposableStore, Disposable, toDisposable } from 'vs/base/common/lifecycle'; -import { LinkedList } from 'vs/base/common/linkedList'; +import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import { URI } from 'vs/base/common/uri'; import { ICodeEditor, IDiffEditor } from 'vs/editor/browser/editorBrowser'; -import { ICodeEditorOpenHandler, ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { IContentDecorationRenderOptions, IDecorationRenderOptions, IThemeDecorationRenderOptions, isThemeColor } from 'vs/editor/common/editorCommon'; import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, InjectedTextOptions, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model'; import { IResourceEditorInput } from 'vs/platform/editor/common/editor'; @@ -43,7 +42,6 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC protected _globalStyleSheet: GlobalStyleSheet | null; private readonly _decorationOptionProviders = new Map(); private readonly _editorStyleSheets = new Map(); - private readonly _codeEditorOpenHandlers = new LinkedList(); constructor( @IThemeService private readonly _themeService: IThemeService, @@ -163,7 +161,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC if (provider.refCount <= 0) { this._decorationOptionProviders.delete(key); provider.dispose(); - this.listCodeEditors().forEach((ed) => ed.removeDecorationsByType(key)); + this.listCodeEditors().forEach((ed) => ed.removeDecorations(key)); } } } @@ -249,21 +247,7 @@ export abstract class AbstractCodeEditorService extends Disposable implements IC } abstract getActiveCodeEditor(): ICodeEditor | null; - - async openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise { - for (const handler of this._codeEditorOpenHandlers) { - const candidate = await handler(input, source, sideBySide); - if (candidate !== null) { - return candidate; - } - } - return null; - } - - registerCodeEditorOpenHandler(handler: ICodeEditorOpenHandler): IDisposable { - const rm = this._codeEditorOpenHandlers.unshift(handler); - return toDisposable(rm); - } + abstract openCodeEditor(input: IResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise; } export class ModelTransientSettingWatcher { @@ -792,7 +776,7 @@ class DecorationCSSRules { private collectCSSText(opts: any, properties: string[], cssTextArr: string[]): boolean { const lenBefore = cssTextArr.length; - for (const property of properties) { + for (let property of properties) { const value = this.resolveValue(opts[property]); if (typeof value === 'string') { cssTextArr.push(strings.format(_CSS_MAP[property], value)); diff --git a/src/vs/editor/browser/services/bulkEditService.ts b/src/vs/editor/browser/services/bulkEditService.ts index 5c8bd18041..019f4e2463 100644 --- a/src/vs/editor/browser/services/bulkEditService.ts +++ b/src/vs/editor/browser/services/bulkEditService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { TextEdit, WorkspaceEdit, WorkspaceEditMetadata, IWorkspaceFileEdit, WorkspaceFileEditOptions, IWorkspaceTextEdit } from 'vs/editor/common/languages'; +import { TextEdit, WorkspaceEdit, WorkspaceEditMetadata, WorkspaceFileEdit, WorkspaceFileEditOptions, WorkspaceTextEdit } from 'vs/editor/common/languages'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { IProgress, IProgressStep } from 'vs/platform/progress/common/progress'; import { IDisposable } from 'vs/base/common/lifecycle'; @@ -15,77 +15,49 @@ import { CancellationToken } from 'vs/base/common/cancellation'; export const IBulkEditService = createDecorator('IWorkspaceEditService'); +function isWorkspaceFileEdit(thing: any): thing is WorkspaceFileEdit { + return isObject(thing) && (Boolean((thing).newUri) || Boolean((thing).oldUri)); +} + +function isWorkspaceTextEdit(thing: any): thing is WorkspaceTextEdit { + return isObject(thing) && URI.isUri((thing).resource) && isObject((thing).edit); +} + export class ResourceEdit { protected constructor(readonly metadata?: WorkspaceEditMetadata) { } static convert(edit: WorkspaceEdit): ResourceEdit[] { - return edit.edits.map(edit => { - if (ResourceTextEdit.is(edit)) { - return ResourceTextEdit.lift(edit); - } - if (ResourceFileEdit.is(edit)) { - return ResourceFileEdit.lift(edit); + return edit.edits.map(edit => { + if (isWorkspaceTextEdit(edit)) { + return new ResourceTextEdit(edit.resource, edit.edit, edit.modelVersionId, edit.metadata); + } + if (isWorkspaceFileEdit(edit)) { + return new ResourceFileEdit(edit.oldUri, edit.newUri, edit.options, edit.metadata); } throw new Error('Unsupported edit'); }); } } -export class ResourceTextEdit extends ResourceEdit implements IWorkspaceTextEdit { - - static is(candidate: any): candidate is IWorkspaceTextEdit { - if (candidate instanceof ResourceTextEdit) { - return true; - } - return isObject(candidate) - && URI.isUri((candidate).resource) - && isObject((candidate).textEdit); - } - - static lift(edit: IWorkspaceTextEdit): ResourceTextEdit { - if (edit instanceof ResourceTextEdit) { - return edit; - } else { - return new ResourceTextEdit(edit.resource, edit.textEdit, edit.versionId, edit.metadata); - } - } - +export class ResourceTextEdit extends ResourceEdit { constructor( readonly resource: URI, - readonly textEdit: TextEdit & { insertAsSnippet?: boolean }, - readonly versionId: number | undefined = undefined, - metadata?: WorkspaceEditMetadata, + readonly textEdit: TextEdit, + readonly versionId?: number, + metadata?: WorkspaceEditMetadata ) { super(metadata); } } -export class ResourceFileEdit extends ResourceEdit implements IWorkspaceFileEdit { - - static is(candidate: any): candidate is IWorkspaceFileEdit { - if (candidate instanceof ResourceFileEdit) { - return true; - } else { - return isObject(candidate) - && (Boolean((candidate).newResource) || Boolean((candidate).oldResource)); - } - } - - static lift(edit: IWorkspaceFileEdit): ResourceFileEdit { - if (edit instanceof ResourceFileEdit) { - return edit; - } else { - return new ResourceFileEdit(edit.oldResource, edit.newResource, edit.options, edit.metadata); - } - } - +export class ResourceFileEdit extends ResourceEdit { constructor( readonly oldResource: URI | undefined, readonly newResource: URI | undefined, - readonly options: WorkspaceFileEditOptions = {}, + readonly options?: WorkspaceFileEditOptions, metadata?: WorkspaceEditMetadata ) { super(metadata); diff --git a/src/vs/editor/browser/services/codeEditorService.ts b/src/vs/editor/browser/services/codeEditorService.ts index bf194117e5..356f5b040e 100644 --- a/src/vs/editor/browser/services/codeEditorService.ts +++ b/src/vs/editor/browser/services/codeEditorService.ts @@ -10,7 +10,6 @@ import { IModelDecorationOptions, ITextModel } from 'vs/editor/common/model'; import { ITextResourceEditorInput } from 'vs/platform/editor/common/editor'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; -import { IDisposable } from 'vs/base/common/lifecycle'; export const ICodeEditorService = createDecorator('codeEditorService'); @@ -54,9 +53,4 @@ export interface ICodeEditorService { getActiveCodeEditor(): ICodeEditor | null; openCodeEditor(input: ITextResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise; - registerCodeEditorOpenHandler(handler: ICodeEditorOpenHandler): IDisposable; -} - -export interface ICodeEditorOpenHandler { - (input: ITextResourceEditorInput, source: ICodeEditor | null, sideBySide?: boolean): Promise; } diff --git a/src/vs/editor/browser/services/editorWorkerService.ts b/src/vs/editor/browser/services/editorWorkerService.ts index 697f7281b5..d05542ded2 100644 --- a/src/vs/editor/browser/services/editorWorkerService.ts +++ b/src/vs/editor/browser/services/editorWorkerService.ts @@ -303,7 +303,7 @@ class EditorModelManager extends Disposable { } public override dispose(): void { - for (const modelUrl in this._syncedModels) { + for (let modelUrl in this._syncedModels) { dispose(this._syncedModels[modelUrl]); } this._syncedModels = Object.create(null); @@ -328,7 +328,7 @@ class EditorModelManager extends Disposable { const currentTime = (new Date()).getTime(); const toRemove: string[] = []; - for (const modelUrl in this._syncedModelsLastUsedTime) { + for (let modelUrl in this._syncedModelsLastUsedTime) { const elapsedTime = currentTime - this._syncedModelsLastUsedTime[modelUrl]; if (elapsedTime > STOP_SYNC_MODEL_DELTA_TIME_MS) { toRemove.push(modelUrl); diff --git a/src/vs/editor/browser/services/openerService.ts b/src/vs/editor/browser/services/openerService.ts index 74f729565f..72b297ae79 100644 --- a/src/vs/editor/browser/services/openerService.ts +++ b/src/vs/editor/browser/services/openerService.ts @@ -163,7 +163,7 @@ export class OpenerService implements IOpenerService { // validate against the original URI that this URI resolves to, if one exists const validationTarget = this._resolvedUriTargets.get(targetURI) ?? target; for (const validator of this._validators) { - if (!(await validator.shouldOpen(validationTarget, options))) { + if (!(await validator.shouldOpen(validationTarget))) { return false; } } diff --git a/src/vs/editor/browser/view.ts b/src/vs/editor/browser/view.ts index f74e8822af..e6136ab871 100644 --- a/src/vs/editor/browser/view.ts +++ b/src/vs/editor/browser/view.ts @@ -49,7 +49,6 @@ import { IViewModel } from 'vs/editor/common/viewModel'; import { getThemeTypeSelector, IColorTheme } from 'vs/platform/theme/common/themeService'; import { EditorOption } from 'vs/editor/common/config/editorOptions'; import { PointerHandlerLastRenderData } from 'vs/editor/browser/controller/mouseTarget'; -import { BlockDecorations } from 'vs/editor/browser/viewParts/blockDecorations/blockDecorations'; export interface IContentWidgetData { @@ -181,9 +180,6 @@ export class View extends ViewEventHandler { const rulers = new Rulers(this._context); this._viewParts.push(rulers); - const blockOutline = new BlockDecorations(this._context); - this._viewParts.push(blockOutline); - const minimap = new Minimap(this._context); this._viewParts.push(minimap); @@ -196,7 +192,6 @@ export class View extends ViewEventHandler { this._linesContent.appendChild(contentViewOverlays.getDomNode()); this._linesContent.appendChild(rulers.domNode); - this._linesContent.appendChild(blockOutline.domNode); this._linesContent.appendChild(this._viewZones.domNode); this._linesContent.appendChild(this._viewLines.getDomNode()); this._linesContent.appendChild(this._contentWidgets.domNode); diff --git a/src/vs/editor/browser/view/viewUserInputEvents.ts b/src/vs/editor/browser/view/viewUserInputEvents.ts index 114e4144a4..5912efe308 100644 --- a/src/vs/editor/browser/view/viewUserInputEvents.ts +++ b/src/vs/editor/browser/view/viewUserInputEvents.ts @@ -33,47 +33,69 @@ export class ViewUserInputEvents { } public emitKeyDown(e: IKeyboardEvent): void { - this.onKeyDown?.(e); + if (this.onKeyDown) { + this.onKeyDown(e); + } } public emitKeyUp(e: IKeyboardEvent): void { - this.onKeyUp?.(e); + if (this.onKeyUp) { + this.onKeyUp(e); + } } public emitContextMenu(e: IEditorMouseEvent): void { - this.onContextMenu?.(this._convertViewToModelMouseEvent(e)); + if (this.onContextMenu) { + this.onContextMenu(this._convertViewToModelMouseEvent(e)); + } } public emitMouseMove(e: IEditorMouseEvent): void { - this.onMouseMove?.(this._convertViewToModelMouseEvent(e)); + if (this.onMouseMove) { + this.onMouseMove(this._convertViewToModelMouseEvent(e)); + } } public emitMouseLeave(e: IPartialEditorMouseEvent): void { - this.onMouseLeave?.(this._convertViewToModelMouseEvent(e)); + if (this.onMouseLeave) { + this.onMouseLeave(this._convertViewToModelMouseEvent(e)); + } } public emitMouseDown(e: IEditorMouseEvent): void { - this.onMouseDown?.(this._convertViewToModelMouseEvent(e)); + if (this.onMouseDown) { + this.onMouseDown(this._convertViewToModelMouseEvent(e)); + } } public emitMouseUp(e: IEditorMouseEvent): void { - this.onMouseUp?.(this._convertViewToModelMouseEvent(e)); + if (this.onMouseUp) { + this.onMouseUp(this._convertViewToModelMouseEvent(e)); + } } public emitMouseDrag(e: IEditorMouseEvent): void { - this.onMouseDrag?.(this._convertViewToModelMouseEvent(e)); + if (this.onMouseDrag) { + this.onMouseDrag(this._convertViewToModelMouseEvent(e)); + } } public emitMouseDrop(e: IPartialEditorMouseEvent): void { - this.onMouseDrop?.(this._convertViewToModelMouseEvent(e)); + if (this.onMouseDrop) { + this.onMouseDrop(this._convertViewToModelMouseEvent(e)); + } } public emitMouseDropCanceled(): void { - this.onMouseDropCanceled?.(); + if (this.onMouseDropCanceled) { + this.onMouseDropCanceled(); + } } public emitMouseWheel(e: IMouseWheelEvent): void { - this.onMouseWheel?.(e); + if (this.onMouseWheel) { + this.onMouseWheel(e); + } } private _convertViewToModelMouseEvent(e: IEditorMouseEvent): IEditorMouseEvent; diff --git a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css b/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css deleted file mode 100644 index f2100bd484..0000000000 --- a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.css +++ /dev/null @@ -1,14 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -.monaco-editor .blockDecorations-container { - position: absolute; - top: 0; -} - -.monaco-editor .blockDecorations-block { - position: absolute; - box-sizing: border-box; -} diff --git a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts b/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts deleted file mode 100644 index d7f72cfa80..0000000000 --- a/src/vs/editor/browser/viewParts/blockDecorations/blockDecorations.ts +++ /dev/null @@ -1,103 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the Source EULA. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createFastDomNode, FastDomNode } from 'vs/base/browser/fastDomNode'; -import 'vs/css!./blockDecorations'; -import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/browser/view/renderingContext'; -import { ViewPart } from 'vs/editor/browser/view/viewPart'; -import { EditorOption } from 'vs/editor/common/config/editorOptions'; -import * as viewEvents from 'vs/editor/common/viewEvents'; -import { ViewContext } from 'vs/editor/common/viewModel/viewContext'; - -export class BlockDecorations extends ViewPart { - - public domNode: FastDomNode; - - private readonly blocks: FastDomNode[] = []; - - private contentWidth: number = -1; - - constructor(context: ViewContext) { - super(context); - - this.domNode = createFastDomNode(document.createElement('div')); - this.domNode.setAttribute('role', 'presentation'); - this.domNode.setAttribute('aria-hidden', 'true'); - this.domNode.setClassName('blockDecorations-container'); - - this.update(); - } - - private update(): boolean { - let didChange = false; - const options = this._context.configuration.options; - const layoutInfo = options.get(EditorOption.layoutInfo); - const newContentWidth = layoutInfo.contentWidth - layoutInfo.verticalScrollbarWidth; - - if (this.contentWidth !== newContentWidth) { - this.contentWidth = newContentWidth; - didChange = true; - } - - return didChange; - } - - public override dispose(): void { - super.dispose(); - } - - // --- begin event handlers - - public override onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - return this.update(); - } - public override onScrollChanged(e: viewEvents.ViewScrollChangedEvent): boolean { - return e.scrollTopChanged || e.scrollLeftChanged; - } - public override onDecorationsChanged(e: viewEvents.ViewDecorationsChangedEvent): boolean { - return true; - } - - public override onZonesChanged(e: viewEvents.ViewZonesChangedEvent): boolean { - return true; - } - - // --- end event handlers - public prepareRender(ctx: RenderingContext): void { - // Nothing to read - } - - public render(ctx: RestrictedRenderingContext): void { - let count = 0; - const decorations = ctx.getDecorationsInViewport(); - for (const decoration of decorations) { - if (!decoration.options.blockClassName) { - continue; - } - - let block = this.blocks[count]; - if (!block) { - block = this.blocks[count] = createFastDomNode(document.createElement('div')); - this.domNode.appendChild(block); - } - const top = ctx.getVerticalOffsetForLineNumber(decoration.range.startLineNumber); - // See https://github.com/microsoft/vscode/pull/152740#discussion_r902661546 - const bottom = ctx.getVerticalOffsetForLineNumber(decoration.range.endLineNumber + 1); - - block.setClassName('blockDecorations-block ' + decoration.options.blockClassName); - block.setLeft(ctx.scrollLeft); - block.setWidth(this.contentWidth); - block.setTop(top); - block.setHeight(bottom - top); - - count++; - } - - for (let i = count; i < this.blocks.length; i++) { - this.blocks[i].domNode.remove(); - } - this.blocks.length = count; - } -} diff --git a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts index 31c6eb8eb1..dcb3381798 100644 --- a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts +++ b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts @@ -27,7 +27,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay { private _lineNumbersLeft!: number; private _lineNumbersWidth!: number; private _lastCursorModelPosition: Position; - private _lastCursorViewPosition: Position; private _renderResult: string[] | null; private _activeLineNumber: number; @@ -38,7 +37,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay { this._readConfig(); this._lastCursorModelPosition = new Position(1, 1); - this._lastCursorViewPosition = new Position(1, 1); this._renderResult = null; this._activeLineNumber = 1; this._context.addEventHandler(this); @@ -70,7 +68,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay { } public override onCursorStateChanged(e: viewEvents.ViewCursorStateChangedEvent): boolean { const primaryViewPosition = e.selections[0].getPosition(); - this._lastCursorViewPosition = primaryViewPosition; this._lastCursorModelPosition = this._context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(primaryViewPosition); let shouldRender = false; @@ -115,6 +112,14 @@ export class LineNumbersOverlay extends DynamicViewOverlay { return this._renderCustomLineNumbers(modelLineNumber); } + if (this._renderLineNumbers === RenderLineNumbersType.Relative) { + const diff = Math.abs(this._lastCursorModelPosition.lineNumber - modelLineNumber); + if (diff === 0) { + return '' + modelLineNumber + ''; + } + return String(diff); + } + if (this._renderLineNumbers === RenderLineNumbersType.Interval) { if (this._lastCursorModelPosition.lineNumber === modelLineNumber) { return String(modelLineNumber); @@ -139,45 +144,6 @@ export class LineNumbersOverlay extends DynamicViewOverlay { const visibleEndLineNumber = ctx.visibleRange.endLineNumber; const common = '
    '; - let relativeLineNumbers: number[] | null = null; - if (this._renderLineNumbers === RenderLineNumbersType.Relative) { - relativeLineNumbers = new Array(visibleEndLineNumber - visibleStartLineNumber + 1); - - if (this._lastCursorViewPosition.lineNumber >= visibleStartLineNumber && this._lastCursorViewPosition.lineNumber <= visibleEndLineNumber) { - relativeLineNumbers[this._lastCursorViewPosition.lineNumber - visibleStartLineNumber] = this._lastCursorModelPosition.lineNumber; - } - - // Iterate up to compute relative line numbers - { - let value = 0; - for (let lineNumber = this._lastCursorViewPosition.lineNumber + 1; lineNumber <= visibleEndLineNumber; lineNumber++) { - const modelPosition = this._context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(new Position(lineNumber, 1)); - const isWrappedLine = (modelPosition.column !== 1); - if (!isWrappedLine) { - value++; - } - if (lineNumber >= visibleStartLineNumber) { - relativeLineNumbers[lineNumber - visibleStartLineNumber] = isWrappedLine ? 0 : value; - } - } - } - - // Iterate down to compute relative line numbers - { - let value = 0; - for (let lineNumber = this._lastCursorViewPosition.lineNumber - 1; lineNumber >= visibleStartLineNumber; lineNumber--) { - const modelPosition = this._context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(new Position(lineNumber, 1)); - const isWrappedLine = (modelPosition.column !== 1); - if (!isWrappedLine) { - value++; - } - if (lineNumber <= visibleEndLineNumber) { - relativeLineNumbers[lineNumber - visibleStartLineNumber] = isWrappedLine ? 0 : value; - } - } - } - } - const lineCount = this._context.viewModel.getLineCount(); const output: string[] = []; for (let lineNumber = visibleStartLineNumber; lineNumber <= visibleEndLineNumber; lineNumber++) { @@ -191,20 +157,7 @@ export class LineNumbersOverlay extends DynamicViewOverlay { } } - let renderLineNumber: string; - if (relativeLineNumbers) { - const relativeLineNumber = relativeLineNumbers[lineIndex]; - if (this._lastCursorViewPosition.lineNumber === lineNumber) { - // current line! - renderLineNumber = `${relativeLineNumber}`; - } else if (relativeLineNumber) { - renderLineNumber = String(relativeLineNumber); - } else { - renderLineNumber = ''; - } - } else { - renderLineNumber = this._getLineRenderLineNumber(lineNumber); - } + const renderLineNumber = this._getLineRenderLineNumber(lineNumber); if (renderLineNumber) { if (lineNumber === this._activeLineNumber) { diff --git a/src/vs/editor/browser/viewParts/lines/viewLine.ts b/src/vs/editor/browser/viewParts/lines/viewLine.ts index 77ef37357b..5bb20137b0 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLine.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLine.ts @@ -446,8 +446,8 @@ class FastRenderedViewLine implements IRenderedViewLine { } private _getCharPosition(column: number): number { - const horizontalOffset = this._characterMapping.getHorizontalOffset(column); - return this._charWidth * horizontalOffset; + const charOffset = this._characterMapping.getAbsoluteOffset(column); + return this._charWidth * charOffset; } public getColumnOfNodeOffset(lineNumber: number, spanNode: HTMLElement, offset: number): number { @@ -625,8 +625,8 @@ class RenderedViewLine implements IRenderedViewLine { } const result = r[0].left; if (this.input.isBasicASCII) { - const horizontalOffset = this._characterMapping.getHorizontalOffset(column); - const expectedResult = Math.round(this.input.spaceWidth * horizontalOffset); + const charOffset = this._characterMapping.getAbsoluteOffset(column); + const expectedResult = Math.round(this.input.spaceWidth * charOffset); if (Math.abs(expectedResult - result) <= 1) { return expectedResult; } diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 96951fec6b..a3e7a59e9f 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -412,8 +412,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, return null; } - const visibleRanges: LineVisibleRanges[] = []; - let visibleRangesLen = 0; + let visibleRanges: LineVisibleRanges[] = [], visibleRangesLen = 0; const domReadingContext = new DomReadingContext(this.domNode.domNode, this._textRangeRestingSpot); let nextLineModelLineNumber: number = 0; diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.css b/src/vs/editor/browser/viewParts/minimap/minimap.css index 034d0dbf16..cbfa190288 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.css +++ b/src/vs/editor/browser/viewParts/minimap/minimap.css @@ -30,12 +30,3 @@ left: -1px; width: 1px; } - -/* 0.5s fade in/out for the minimap */ -.minimap.autohide { - opacity: 0.0; - transition: opacity 0.5s; -} -.minimap.autohide:hover { - opacity: 1.0; -} diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index d8502d8f7e..1e356e9956 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -6,7 +6,7 @@ import 'vs/css!./minimap'; import * as dom from 'vs/base/browser/dom'; import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; -import { GlobalPointerMoveMonitor } from 'vs/base/browser/globalPointerMoveMonitor'; +import { GlobalPointerMoveMonitor, standardPointerMoveMerger } from 'vs/base/browser/globalPointerMoveMonitor'; import { CharCode } from 'vs/base/common/charCode'; import { IDisposable, Disposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; @@ -18,7 +18,7 @@ import { Range } from 'vs/editor/common/core/range'; import { RGBA8 } from 'vs/editor/common/core/rgba'; import { ScrollType } from 'vs/editor/common/editorCommon'; import { IEditorConfiguration } from 'vs/editor/common/config/editorConfiguration'; -import { ColorId } from 'vs/editor/common/encodedTokenAttributes'; +import { ColorId } from 'vs/editor/common/languages'; import { MinimapCharRenderer } from 'vs/editor/browser/viewParts/minimap/minimapCharRenderer'; import { Constants } from 'vs/editor/browser/viewParts/minimap/minimapCharSheet'; import { MinimapTokensColorTracker } from 'vs/editor/common/viewModel/minimapTokensColorTracker'; @@ -56,8 +56,6 @@ class MinimapOptions { public readonly showSlider: 'always' | 'mouseover'; - public readonly autohide: boolean; - public readonly pixelRatio: number; public readonly typicalHalfwidthCharacterWidth: number; @@ -122,7 +120,6 @@ class MinimapOptions { this.minimapHeightIsEditorHeight = minimapLayout.minimapHeightIsEditorHeight; this.scrollBeyondLastLine = options.get(EditorOption.scrollBeyondLastLine); this.showSlider = minimapOpts.showSlider; - this.autohide = minimapOpts.autohide; this.pixelRatio = pixelRatio; this.typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this.lineHeight = options.get(EditorOption.lineHeight); @@ -169,7 +166,6 @@ class MinimapOptions { && this.minimapHeightIsEditorHeight === other.minimapHeightIsEditorHeight && this.scrollBeyondLastLine === other.scrollBeyondLastLine && this.showSlider === other.showSlider - && this.autohide === other.autohide && this.pixelRatio === other.pixelRatio && this.typicalHalfwidthCharacterWidth === other.typicalHalfwidthCharacterWidth && this.lineHeight === other.lineHeight @@ -1234,6 +1230,7 @@ class InnerMinimap extends Disposable { e.target, e.pointerId, e.buttons, + standardPointerMoveMerger, pointerMoveData => handlePointerMove(pointerMoveData.pageY, pointerMoveData.pageX), () => { this._slider.toggleClassName('active', false); @@ -1259,17 +1256,10 @@ class InnerMinimap extends Disposable { } private _getMinimapDomNodeClassName(): string { - const class_ = ['minimap']; if (this._model.options.showSlider === 'always') { - class_.push('slider-always'); - } else { - class_.push('slider-mouseover'); + return 'minimap slider-always'; } - if (this._model.options.autohide) { - class_.push('autohide'); - } - - return class_.join(' '); + return 'minimap slider-mouseover'; } public getDomNode(): FastDomNode { @@ -1336,11 +1326,15 @@ class InnerMinimap extends Disposable { return false; } public onLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number): boolean { - this._lastRenderData?.onLinesDeleted(deleteFromLineNumber, deleteToLineNumber); + if (this._lastRenderData) { + this._lastRenderData.onLinesDeleted(deleteFromLineNumber, deleteToLineNumber); + } return true; } public onLinesInserted(insertFromLineNumber: number, insertToLineNumber: number): boolean { - this._lastRenderData?.onLinesInserted(insertFromLineNumber, insertToLineNumber); + if (this._lastRenderData) { + this._lastRenderData.onLinesInserted(insertFromLineNumber, insertToLineNumber); + } return true; } public onScrollChanged(): boolean { diff --git a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts index 514b83eae0..408457f88b 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts @@ -62,15 +62,9 @@ class Settings { const minimapOpts = options.get(EditorOption.minimap); const minimapEnabled = minimapOpts.enabled; const minimapSide = minimapOpts.side; - const themeColor = theme.getColor(editorOverviewRulerBackground); - const defaultBackground = TokenizationRegistry.getDefaultBackground(); - let backgroundColor: Color | null = null; - - if (themeColor !== undefined) { - backgroundColor = themeColor; - } else if (minimapEnabled) { - backgroundColor = defaultBackground; - } + const backgroundColor = minimapEnabled + ? theme.getColor(editorOverviewRulerBackground) || TokenizationRegistry.getDefaultBackground() + : null; if (backgroundColor === null || minimapSide === 'left') { this.backgroundColor = null; diff --git a/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts b/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts index 44cfada860..0ec70bea1f 100644 --- a/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts +++ b/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts @@ -61,7 +61,7 @@ export class ScrollDecorationViewPart extends ViewPart { if (layoutInfo.minimap.renderMinimap === 0 || (layoutInfo.minimap.minimapWidth > 0 && layoutInfo.minimap.minimapLeft === 0)) { this._width = layoutInfo.width; } else { - this._width = layoutInfo.width - layoutInfo.verticalScrollbarWidth; + this._width = layoutInfo.width - layoutInfo.minimap.minimapWidth - layoutInfo.verticalScrollbarWidth; } } diff --git a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts index d08f3f7648..65b67f29ec 100644 --- a/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts +++ b/src/vs/editor/browser/viewParts/viewCursors/viewCursor.ts @@ -172,13 +172,7 @@ export class ViewCursor { } const range = firstVisibleRangeForCharacter.ranges[0]; - const width = ( - nextGrapheme === '\t' - ? this._typicalHalfwidthCharacterWidth - : (range.width < 1 - ? this._typicalHalfwidthCharacterWidth - : range.width) - ); + const width = range.width < 1 ? this._typicalHalfwidthCharacterWidth : range.width; let textContentClassName = ''; if (this._cursorStyle === TextEditorCursorStyle.Block) { diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 633920bbeb..fcdb2fd9a7 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -14,7 +14,7 @@ import { Color } from 'vs/base/common/color'; import { onUnexpectedError } from 'vs/base/common/errors'; import { Emitter, EmitterOptions, Event, EventDeliveryQueue } from 'vs/base/common/event'; import { hash } from 'vs/base/common/hash'; -import { Disposable, IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle'; import { Schemas } from 'vs/base/common/network'; import { EditorConfiguration, IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import * as editorBrowser from 'vs/editor/browser/editorBrowser'; @@ -267,7 +267,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE private _bannerDomNode: HTMLElement | null = null; - private _dropIntoEditorDecorations: EditorDecorationsCollection = this.createDecorationsCollection(); + private _dropIntoEditorDecorationIds: string[] = []; constructor( domElement: HTMLElement, @@ -368,47 +368,35 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._actions[internalAction.id] = internalAction; }); - const isDropIntoEnabled = () => { - return !this._configuration.options.get(EditorOption.readOnly) - && this._configuration.options.get(EditorOption.dropIntoEditor).enabled; - }; + if (_options.enableDropIntoEditor) { + this._register(new dom.DragAndDropObserver(this._domElement, { + onDragEnter: () => undefined, + onDragOver: e => { + const target = this.getTargetAtClientPoint(e.clientX, e.clientY); + if (target?.position) { + this.showDropIndicatorAt(target.position); + } + }, + onDrop: async e => { + this.removeDropIndicator(); - this._register(new dom.DragAndDropObserver(this._domElement, { - onDragEnter: () => undefined, - onDragOver: e => { - if (!isDropIntoEnabled()) { - return; - } - - const target = this.getTargetAtClientPoint(e.clientX, e.clientY); - if (target?.position) { - this.showDropIndicatorAt(target.position); - } - }, - onDrop: async e => { - if (!isDropIntoEnabled()) { - return; - } - - this.removeDropIndicator(); - - if (!e.dataTransfer) { - return; - } - - const target = this.getTargetAtClientPoint(e.clientX, e.clientY); - if (target?.position) { - this._onDropIntoEditor.fire({ position: target.position, event: e }); - } - }, - onDragLeave: () => { - this.removeDropIndicator(); - }, - onDragEnd: () => { - this.removeDropIndicator(); - }, - })); + if (!e.dataTransfer) { + return; + } + const target = this.getTargetAtClientPoint(e.clientX, e.clientY); + if (target?.position) { + this._onDropIntoEditor.fire({ position: target.position, event: e }); + } + }, + onDragLeave: () => { + this.removeDropIndicator(); + }, + onDragEnd: () => { + this.removeDropIndicator(); + }, + })); + } this._codeEditorService.addCodeEditor(this); } @@ -538,9 +526,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE private _removeDecorationTypes(): void { this._decorationTypeKeysToIds = {}; if (this._decorationTypeSubtypes) { - for (const decorationType in this._decorationTypeSubtypes) { + for (let decorationType in this._decorationTypeSubtypes) { const subTypes = this._decorationTypeSubtypes[decorationType]; - for (const subType in subTypes) { + for (let subType in subTypes) { this._removeDecorationType(decorationType + '-' + subType); } } @@ -569,47 +557,33 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return this._modelData.viewModel.viewLayout.getWhitespaces(); } - private static _getVerticalOffsetAfterPosition(modelData: ModelData, modelLineNumber: number, modelColumn: number, includeViewZones: boolean): number { + private static _getVerticalOffsetForPosition(modelData: ModelData, modelLineNumber: number, modelColumn: number): number { const modelPosition = modelData.model.validatePosition({ lineNumber: modelLineNumber, column: modelColumn }); const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition); - return modelData.viewModel.viewLayout.getVerticalOffsetAfterLineNumber(viewPosition.lineNumber, includeViewZones); + return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber); } - public getTopForLineNumber(lineNumber: number, includeViewZones: boolean = false): number { + public getTopForLineNumber(lineNumber: number): number { if (!this._modelData) { return -1; } - return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, 1, includeViewZones); + return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, 1); } public getTopForPosition(lineNumber: number, column: number): number { if (!this._modelData) { return -1; } - return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, column, false); - } - - private static _getVerticalOffsetForPosition(modelData: ModelData, modelLineNumber: number, modelColumn: number, includeViewZones: boolean = false): number { - const modelPosition = modelData.model.validatePosition({ - lineNumber: modelLineNumber, - column: modelColumn - }); - const viewPosition = modelData.viewModel.coordinatesConverter.convertModelPositionToViewPosition(modelPosition); - return modelData.viewModel.viewLayout.getVerticalOffsetForLineNumber(viewPosition.lineNumber, includeViewZones); - } - - public getBottomForLineNumber(lineNumber: number, includeViewZones: boolean = false): number { - if (!this._modelData) { - return -1; - } - return CodeEditorWidget._getVerticalOffsetAfterPosition(this._modelData, lineNumber, 1, includeViewZones); + return CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, lineNumber, column); } public setHiddenAreas(ranges: IRange[]): void { - this._modelData?.viewModel.setHiddenAreas(ranges.map(r => Range.lift(r))); + if (this._modelData) { + this._modelData.viewModel.setHiddenAreas(ranges.map(r => Range.lift(r))); + } } public getVisibleColumnFromPosition(rawPosition: IPosition): number { @@ -1182,10 +1156,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE if (!this._modelData || text.length === 0) { return; } - const viewModel = this._modelData.viewModel; - const startPosition = viewModel.getSelection().getStartPosition(); - viewModel.paste(text, pasteOnNewLine, multicursorText, source); - const endPosition = viewModel.getSelection().getStartPosition(); + const startPosition = this._modelData.viewModel.getSelection().getStartPosition(); + this._modelData.viewModel.paste(text, pasteOnNewLine, multicursorText, source); + const endPosition = this._modelData.viewModel.getSelection().getStartPosition(); if (source === 'keyboard') { this._onDidPaste.fire({ range: new Range(startPosition.lineNumber, startPosition.column, endPosition.lineNumber, endPosition.column), @@ -1282,10 +1255,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._modelData.viewModel.executeCommands(commands, source); } - public createDecorationsCollection(decorations?: IModelDeltaDecoration[]): EditorDecorationsCollection { - return new EditorDecorationsCollection(this, decorations); - } - public changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any { if (!this._modelData) { // callback will not be called @@ -1308,9 +1277,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return this._modelData.model.getDecorationsInRange(range, this._id, filterValidationDecorations(this._configuration.options)); } - /** - * @deprecated - */ public deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[] { if (!this._modelData) { return []; @@ -1323,17 +1289,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return this._modelData.model.deltaDecorations(oldDecorations, newDecorations, this._id); } - public removeDecorations(decorationIds: string[]): void { - if (!this._modelData || decorationIds.length === 0) { - return; - } - - this._modelData.model.changeDecorations((changeAccessor) => { - changeAccessor.deltaDecorations(decorationIds, []); - }); - } - - public setDecorationsByType(description: string, decorationTypeKey: string, decorationOptions: editorCommon.IDecorationOptions[]): void { + public setDecorations(description: string, decorationTypeKey: string, decorationOptions: editorCommon.IDecorationOptions[]): void { const newDecorationsSubTypes: { [key: string]: boolean } = {}; const oldDecorationsSubTypes = this._decorationTypeSubtypes[decorationTypeKey] || {}; @@ -1341,7 +1297,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE const newModelDecorations: IModelDeltaDecoration[] = []; - for (const decorationOption of decorationOptions) { + for (let decorationOption of decorationOptions) { let typeKey = decorationTypeKey; if (decorationOption.renderOptions) { // identify custom reder options by a hash code over all keys and values @@ -1364,7 +1320,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } // remove decoration sub types that are no longer used, deregister decoration type if necessary - for (const subType in oldDecorationsSubTypes) { + for (let subType in oldDecorationsSubTypes) { if (!newDecorationsSubTypes[subType]) { this._removeDecorationType(decorationTypeKey + '-' + subType); } @@ -1375,11 +1331,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._decorationTypeKeysToIds[decorationTypeKey] = this.deltaDecorations(oldDecorationsIds, newModelDecorations); } - public setDecorationsByTypeFast(decorationTypeKey: string, ranges: IRange[]): void { + public setDecorationsFast(decorationTypeKey: string, ranges: IRange[]): void { // remove decoration sub types that are no longer used, deregister decoration type if necessary const oldDecorationsSubTypes = this._decorationTypeSubtypes[decorationTypeKey] || {}; - for (const subType in oldDecorationsSubTypes) { + for (let subType in oldDecorationsSubTypes) { this._removeDecorationType(decorationTypeKey + '-' + subType); } this._decorationTypeSubtypes[decorationTypeKey] = {}; @@ -1395,7 +1351,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._decorationTypeKeysToIds[decorationTypeKey] = this.deltaDecorations(oldDecorationsIds, newModelDecorations); } - public removeDecorationsByType(decorationTypeKey: string): void { + public removeDecorations(decorationTypeKey: string): void { // remove decorations for type and sub type const oldDecorationsIds = this._decorationTypeKeysToIds[decorationTypeKey]; if (oldDecorationsIds) { @@ -1819,7 +1775,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } protected _postDetachModelCleanup(detachedModel: ITextModel | null): void { - detachedModel?.removeAllDecorationsWithOwnerId(this._id); + if (detachedModel) { + detachedModel.removeAllDecorationsWithOwnerId(this._id); + } } private _detachModel(): ITextModel | null { @@ -1864,17 +1822,17 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } private showDropIndicatorAt(position: Position): void { - const newDecorations: IModelDeltaDecoration[] = [{ + let newDecorations: IModelDeltaDecoration[] = [{ range: new Range(position.lineNumber, position.column, position.lineNumber, position.column), options: CodeEditorWidget.dropIntoEditorDecorationOptions }]; - this._dropIntoEditorDecorations.set(newDecorations); + this._dropIntoEditorDecorationIds = this.deltaDecorations(this._dropIntoEditorDecorationIds, newDecorations); this.revealPosition(position, editorCommon.ScrollType.Immediate); } private removeDropIndicator(): void { - this._dropIntoEditorDecorations.clear(); + this._dropIntoEditorDecorationIds = this.deltaDecorations(this._dropIntoEditorDecorationIds, []); } } @@ -2167,82 +2125,8 @@ class CodeEditorWidgetFocusTracker extends Disposable { } public refreshState(): void { - this._domFocusTracker.refreshState?.(); - } -} - -class EditorDecorationsCollection implements editorCommon.IEditorDecorationsCollection { - - private _decorationIds: string[] = []; - private _isChangingDecorations: boolean = false; - - public get length(): number { - return this._decorationIds.length; - } - - constructor( - private readonly _editor: editorBrowser.ICodeEditor, - decorations: IModelDeltaDecoration[] | undefined - ) { - if (Array.isArray(decorations) && decorations.length > 0) { - this.set(decorations); - } - } - - public onDidChange(listener: (e: IModelDecorationsChangedEvent) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable { - return this._editor.onDidChangeModelDecorations((e) => { - if (this._isChangingDecorations) { - return; - } - listener.call(thisArgs, e); - }, disposables); - } - - public getRange(index: number): Range | null { - if (!this._editor.hasModel()) { - return null; - } - if (index >= this._decorationIds.length) { - return null; - } - return this._editor.getModel().getDecorationRange(this._decorationIds[index]); - } - - public getRanges(): Range[] { - if (!this._editor.hasModel()) { - return []; - } - const model = this._editor.getModel(); - const result: Range[] = []; - for (const decorationId of this._decorationIds) { - const range = model.getDecorationRange(decorationId); - if (range) { - result.push(range); - } - } - return result; - } - - public has(decoration: IModelDecoration): boolean { - return this._decorationIds.includes(decoration.id); - } - - public clear(): void { - if (this._decorationIds.length === 0) { - // nothing to do - return; - } - this.set([]); - } - - public set(newDecorations: IModelDeltaDecoration[]): void { - try { - this._isChangingDecorations = true; - this._editor.changeDecorations((accessor) => { - this._decorationIds = accessor.deltaDecorations(this._decorationIds, newDecorations); - }); - } finally { - this._isChangingDecorations = false; + if (this._domFocusTracker.refreshState) { + this._domFocusTracker.refreshState(); } } } diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index acd38d7162..5ab48860e4 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -6,7 +6,6 @@ import 'vs/css!./media/diffEditor'; import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; -import * as assert from 'vs/base/common/assert'; import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; import { ISashEvent, IVerticalSashLayoutProvider, Sash, SashState, Orientation } from 'vs/base/browser/ui/sash/sash'; import { RunOnceScheduler } from 'vs/base/common/async'; @@ -53,7 +52,7 @@ import { IViewLineTokens } from 'vs/editor/common/tokens/lineTokens'; import { FontInfo } from 'vs/editor/common/config/fontInfo'; import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { ILineBreaksComputer } from 'vs/editor/common/modelLineProjectionData'; -import { IChange, ICharChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/diffComputer'; +import { IChange, IDiffComputationResult, ILineChange } from 'vs/editor/common/diff/diffComputer'; import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { IDimension } from 'vs/editor/common/core/dimension'; import { isHighContrast } from 'vs/platform/theme/common/theme'; @@ -115,9 +114,7 @@ class VisualEditorState { this._zonesMap = {}; // (2) Model decorations - editor.changeDecorations((changeAccessor) => { - this._decorations = changeAccessor.deltaDecorations(this._decorations, []); - }); + this._decorations = editor.deltaDecorations(this._decorations, []); } public apply(editor: CodeEditorWidget, overviewRuler: editorBrowser.IOverviewRuler | null, newDecorations: IEditorDiffDecorationsWithZones, restoreScrollState: boolean): void { @@ -152,15 +149,17 @@ class VisualEditorState { } }); - scrollState?.restore(editor); + if (scrollState) { + scrollState.restore(editor); + } // decorations - editor.changeDecorations((changeAccessor) => { - this._decorations = changeAccessor.deltaDecorations(this._decorations, newDecorations.decorations); - }); + this._decorations = editor.deltaDecorations(this._decorations, newDecorations.decorations); // overview ruler - overviewRuler?.setZones(newDecorations.overviewZones); + if (overviewRuler) { + overviewRuler.setZones(newDecorations.overviewZones); + } } } @@ -264,7 +263,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE let diffOptions: any = { enableSplitViewResizing: true, renderSideBySide: true, - renderMarginRevertIcon: true, maxComputationTime: 5000, maxFileSize: 50, ignoreTrimWhitespace: true, @@ -432,30 +430,24 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE return result; } - private _disposeOverviewRulers(): void { - if (this._originalOverviewRuler) { - this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode()); - this._originalOverviewRuler.dispose(); - this._originalOverviewRuler = null; - } - if (this._modifiedOverviewRuler) { - this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode()); - this._modifiedOverviewRuler.dispose(); - this._modifiedOverviewRuler = null; - } - } - - private _createOverviewRulers(): void { + private _recreateOverviewRulers(): void { if (!this._options.renderOverviewRuler) { return; } - assert.ok(!this._originalOverviewRuler && !this._modifiedOverviewRuler); - + if (this._originalOverviewRuler) { + this._overviewDomElement.removeChild(this._originalOverviewRuler.getDomNode()); + this._originalOverviewRuler.dispose(); + } if (this._originalEditor.hasModel()) { this._originalOverviewRuler = this._originalEditor.createOverviewRuler('original diffOverviewRuler')!; this._overviewDomElement.appendChild(this._originalOverviewRuler.getDomNode()); } + + if (this._modifiedOverviewRuler) { + this._overviewDomElement.removeChild(this._modifiedOverviewRuler.getDomNode()); + this._modifiedOverviewRuler.dispose(); + } if (this._modifiedEditor.hasModel()) { this._modifiedOverviewRuler = this._modifiedEditor.createOverviewRuler('modified diffOverviewRuler')!; this._overviewDomElement.appendChild(this._modifiedOverviewRuler.getDomNode()); @@ -601,77 +593,11 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE }); })); - // Revert change when an arrow is clicked. - this._register(editor.onMouseDown(event => { - if (!event.event.rightButton && event.target.position && event.target.element?.className.includes('arrow-revert-change')) { - const lineNumber = event.target.position.lineNumber; - const change = this._diffComputationResult?.changes.find(c => c.modifiedStartLineNumber === lineNumber - 1 || c.modifiedStartLineNumber === lineNumber); - if (change) { - this.revertChange(change); - } - event.event.stopPropagation(); - this._updateDecorations(); - return; - } - })); - return editor; } - /** - * Reverts a change in the modified editor. - */ - revertChange(change: IChange) { - const editor = this._modifiedEditor; - const original = this._originalEditor.getModel(); - const modified = this._modifiedEditor.getModel(); - if (!original || !modified || !editor) { - return; - } - - const originalRange = change.originalEndLineNumber > 0 ? new Range(change.originalStartLineNumber, 1, change.originalEndLineNumber, original.getLineMaxColumn(change.originalEndLineNumber)) : null; - const originalContent = originalRange ? original.getValueInRange(originalRange) : null; - - const newRange = change.modifiedEndLineNumber > 0 ? new Range(change.modifiedStartLineNumber, 1, change.modifiedEndLineNumber, modified.getLineMaxColumn(change.modifiedEndLineNumber)) : null; - - const eol = modified.getEOL(); - - if (change.originalEndLineNumber === 0 && newRange) { - // Insert change. - // To revert: delete the new content and a linebreak (if possible) - - let range = newRange; - if (change.modifiedStartLineNumber > 1) { - // Try to include a linebreak from before. - range = newRange.setStartPosition(change.modifiedStartLineNumber - 1, modified.getLineMaxColumn(change.modifiedStartLineNumber - 1)); - } else if (change.modifiedEndLineNumber < modified.getLineCount()) { - // Try to include the linebreak from after. - range = newRange.setEndPosition(change.modifiedEndLineNumber + 1, 1); - } - editor.executeEdits('diffEditor', [{ - range, - text: '', - }]); - } else if (change.modifiedEndLineNumber === 0 && originalContent !== null) { - // Delete change. - // To revert: insert the old content and a linebreak. - - const insertAt = change.modifiedStartLineNumber < modified.getLineCount() ? new Position(change.modifiedStartLineNumber + 1, 1) : new Position(change.modifiedStartLineNumber, modified.getLineMaxColumn(change.modifiedStartLineNumber)); - editor.executeEdits('diffEditor', [{ - range: Range.fromPositions(insertAt, insertAt), - text: change.modifiedStartLineNumber < modified.getLineCount() ? originalContent + eol : eol + originalContent, - }]); - } else if (newRange && originalContent !== null) { - // Modified change. - editor.executeEdits('diffEditor', [{ - range: newRange, - text: originalContent, - }]); - } - } - protected _createInnerEditor(instantiationService: IInstantiationService, container: HTMLElement, options: Readonly, editorWidgetOptions: ICodeEditorWidgetOptions): CodeEditorWidget { - return instantiationService.createInstance(CodeEditorWidget, container, options, editorWidgetOptions); + return instantiationService.createInstance(CodeEditorWidget, container, { enableDropIntoEditor: true, ...options }, editorWidgetOptions); } public override dispose(): void { @@ -751,7 +677,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE const changed = changedDiffEditorOptions(this._options, newOptions); this._options = newOptions; - const beginUpdateDecorations = (changed.ignoreTrimWhitespace || changed.renderIndicators || changed.renderMarginRevertIcon); + const beginUpdateDecorations = (changed.ignoreTrimWhitespace || changed.renderIndicators); const beginUpdateDecorationsSoon = (this._isVisible && (changed.maxComputationTime || changed.maxFileSize)); if (beginUpdateDecorations) { @@ -803,8 +729,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE // Remove all view zones & decorations this._cleanViewZonesAndDecorations(); - this._disposeOverviewRulers(); - // Update code editor models this._originalEditor.setModel(model ? model.original : null); this._modifiedEditor.setModel(model ? model.modified : null); @@ -823,7 +747,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._setState(editorBrowser.DiffEditorState.Idle); if (model) { - this._createOverviewRulers(); + this._recreateOverviewRulers(); // Begin comparing this._beginUpdateDecorations(); @@ -997,10 +921,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE this._modifiedEditor.trigger(source, handlerId, payload); } - public createDecorationsCollection(decorations?: IModelDeltaDecoration[]): editorCommon.IEditorDecorationsCollection { - return this._modifiedEditor.createDecorationsCollection(decorations); - } - public changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any { return this._modifiedEditor.changeDecorations(callback); } @@ -1150,8 +1070,7 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE const foreignModified = this._modifiedEditorState.getForeignViewZones(this._modifiedEditor.getWhitespaces()); // {{SQL CARBON EDIT}} - // const diffDecorations = this._strategy.getEditorsDiffDecorations(lineChanges, this._options.ignoreTrimWhitespace, this._options.renderIndicators, foreignOriginal, foreignModified, this._originalEditor, this._modifiedEditor, this._options.reverse); // {{ SQL CARBON TODO }} - The last 3 args are different in the updated version below. - const diffDecorations = this._strategy.getEditorsDiffDecorations(lineChanges, this._options.ignoreTrimWhitespace, this._options.renderIndicators, this._options.renderMarginRevertIcon, foreignOriginal, foreignModified); + const diffDecorations = this._strategy.getEditorsDiffDecorations(lineChanges, this._options.ignoreTrimWhitespace, this._options.renderIndicators, foreignOriginal, foreignModified, this._originalEditor, this._modifiedEditor, this._options.reverse); try { this._currentlyChangingViewZones = true; @@ -1192,7 +1111,6 @@ export class DiffEditorWidget extends Disposable implements editorBrowser.IDiffE result.ariaLabel = options.originalAriaLabel; } result.readOnly = !this._options.originalEditable; - result.dropIntoEditor = { enabled: !result.readOnly }; result.extraEditorClassName = 'original-in-monaco-diff-editor'; return { ...result, @@ -1468,7 +1386,7 @@ abstract class DiffEditorWidgetStyle extends Disposable { } // {{SQL CARBON EDIT}} - add reverse parameter - public getEditorsDiffDecorations(lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, renderMarginRevertIcon: boolean, originalWhitespaces: IEditorWhitespace[], modifiedWhitespaces: IEditorWhitespace[], reverse?: boolean): IEditorsDiffDecorationsWithZones { + public getEditorsDiffDecorations(lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, originalWhitespaces: IEditorWhitespace[], modifiedWhitespaces: IEditorWhitespace[], originalEditor: editorBrowser.ICodeEditor, modifiedEditor: editorBrowser.ICodeEditor, reverse?: boolean): IEditorsDiffDecorationsWithZones { // Get view zones modifiedWhitespaces = modifiedWhitespaces.sort((a, b) => { return a.afterLineNumber - b.afterLineNumber; @@ -1480,7 +1398,7 @@ abstract class DiffEditorWidgetStyle extends Disposable { // Get decorations & overview ruler zones let originalDecorations = this._getOriginalEditorDecorations(zones, lineChanges, ignoreTrimWhitespace, renderIndicators); - const modifiedDecorations = this._getModifiedEditorDecorations(zones, lineChanges, ignoreTrimWhitespace, renderIndicators, renderMarginRevertIcon); + let modifiedDecorations = this._getModifiedEditorDecorations(zones, lineChanges, ignoreTrimWhitespace, renderIndicators); // {{SQL CARBON EDIT}} - reverse decorations if (reverse) { @@ -1507,7 +1425,7 @@ abstract class DiffEditorWidgetStyle extends Disposable { protected abstract _getViewZones(lineChanges: ILineChange[], originalForeignVZ: IEditorWhitespace[], modifiedForeignVZ: IEditorWhitespace[], renderIndicators: boolean): IEditorsZones; protected abstract _getOriginalEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean): IEditorDiffDecorations; - protected abstract _getModifiedEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, renderMarginRevertIcon: boolean): IEditorDiffDecorations; + protected abstract _getModifiedEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean): IEditorDiffDecorations; public abstract setEnableSplitViewResizing(enableSplitViewResizing: boolean): void; public abstract layout(): number; @@ -1823,11 +1741,6 @@ function createDecoration(startLineNumber: number, startColumn: number, endLineN const DECORATIONS = { - arrowRevertChange: ModelDecorationOptions.register({ - description: 'diff-editor-arrow-revert-change', - glyphMarginClassName: 'arrow-revert-change ' + ThemeIcon.asClassName(Codicon.arrowRight), - }), - charDelete: ModelDecorationOptions.register({ description: 'diff-editor-char-delete', className: 'char-delete' @@ -2082,7 +1995,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IVerti if (lineChange.charChanges) { for (const charChange of lineChange.charChanges) { - if (isCharChangeOrDelete(charChange)) { + if (isChangeOrDelete(charChange)) { if (ignoreTrimWhitespace) { for (let lineNumber = charChange.originalStartLineNumber; lineNumber <= charChange.originalEndLineNumber; lineNumber++) { let startColumn: number; @@ -2111,7 +2024,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IVerti return result; } - protected _getModifiedEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, renderMarginRevertIcon: boolean): IEditorDiffDecorations { + protected _getModifiedEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean): IEditorDiffDecorations { const modifiedEditor = this._dataSource.getModifiedEditor(); const overviewZoneColor = String(this._insertColor); @@ -2125,21 +2038,6 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IVerti for (const lineChange of lineChanges) { - // Arrows for reverting changes. - if (renderMarginRevertIcon) { - if (lineChange.modifiedEndLineNumber > 0) { - result.decorations.push({ - range: new Range(lineChange.modifiedStartLineNumber, 1, lineChange.modifiedStartLineNumber, 1), - options: DECORATIONS.arrowRevertChange - }); - } else { - const viewZone = zones.modified.find(z => z.afterLineNumber === lineChange.modifiedStartLineNumber); - if (viewZone) { - viewZone.marginDomNode = createViewZoneMarginArrow(); - } - } - } - if (isChangeOrInsert(lineChange)) { result.decorations.push({ @@ -2155,7 +2053,7 @@ class DiffEditorWidgetSideBySide extends DiffEditorWidgetStyle implements IVerti if (lineChange.charChanges) { for (const charChange of lineChange.charChanges) { - if (isCharChangeOrInsert(charChange)) { + if (isChangeOrInsert(charChange)) { if (ignoreTrimWhitespace) { for (let lineNumber = charChange.modifiedStartLineNumber; lineNumber <= charChange.modifiedEndLineNumber; lineNumber++) { let startColumn: number; @@ -2304,7 +2202,7 @@ class DiffEditorWidgetInline extends DiffEditorWidgetStyle { return result; } - protected _getModifiedEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean, renderMarginRevertIcon: boolean): IEditorDiffDecorations { + protected _getModifiedEditorDecorations(zones: IEditorsZones, lineChanges: ILineChange[], ignoreTrimWhitespace: boolean, renderIndicators: boolean): IEditorDiffDecorations { const modifiedEditor = this._dataSource.getModifiedEditor(); const overviewZoneColor = String(this._insertColor); @@ -2330,7 +2228,7 @@ class DiffEditorWidgetInline extends DiffEditorWidgetStyle { if (lineChange.charChanges) { for (const charChange of lineChange.charChanges) { - if (isCharChangeOrInsert(charChange)) { + if (isChangeOrInsert(charChange)) { if (ignoreTrimWhitespace) { for (let lineNumber = charChange.modifiedStartLineNumber; lineNumber <= charChange.modifiedEndLineNumber; lineNumber++) { let startColumn: number; @@ -2492,7 +2390,7 @@ class InlineViewZonesComputer extends ViewZonesComputer { const decorations: InlineDecoration[] = []; if (lineChange.charChanges) { for (const charChange of lineChange.charChanges) { - if (isCharChangeOrDelete(charChange)) { + if (isChangeOrDelete(charChange)) { decorations.push(new InlineDecoration( new Range(charChange.originalStartLineNumber, charChange.originalStartColumn, charChange.originalEndLineNumber, charChange.originalEndColumn), 'char-delete', @@ -2667,7 +2565,7 @@ class InlineViewZonesComputer extends ViewZonesComputer { marginDomNode.appendChild(marginElement); } - return output.characterMapping.getHorizontalOffset(output.characterMapping.length); + return output.characterMapping.getAbsoluteOffset(output.characterMapping.length); } } @@ -2675,40 +2573,20 @@ function validateDiffWordWrap(value: 'off' | 'on' | 'inherit' | undefined, defau return validateStringSetOption<'off' | 'on' | 'inherit'>(value, defaultValue, ['off', 'on', 'inherit']); } -function isChangeOrInsert(lineChange: ILineChange): boolean { +function isChangeOrInsert(lineChange: IChange): boolean { return lineChange.modifiedEndLineNumber > 0; } -function isChangeOrDelete(lineChange: ILineChange): boolean { +function isChangeOrDelete(lineChange: IChange): boolean { return lineChange.originalEndLineNumber > 0; } -function isCharChangeOrInsert(charChange: ICharChange): boolean { - if (charChange.modifiedStartLineNumber === charChange.modifiedEndLineNumber) { - return charChange.modifiedEndColumn - charChange.modifiedStartColumn > 0; - } - return charChange.modifiedEndLineNumber - charChange.modifiedStartLineNumber > 0; -} - -function isCharChangeOrDelete(charChange: ICharChange): boolean { - if (charChange.originalStartLineNumber === charChange.originalEndLineNumber) { - return charChange.originalEndColumn - charChange.originalStartColumn > 0; - } - return charChange.originalEndLineNumber - charChange.originalStartLineNumber > 0; -} - function createFakeLinesDiv(): HTMLElement { const r = document.createElement('div'); r.className = 'diagonal-fill'; return r; } -function createViewZoneMarginArrow(): HTMLElement { - const arrow = document.createElement('div'); - arrow.className = 'arrow-revert-change ' + ThemeIcon.asClassName(Codicon.arrowRight); - return dom.$('div', {}, arrow); -} - function getViewRange(model: ITextModel, viewModel: IViewModel, startLineNumber: number, endLineNumber: number): Range { const lineCount = model.getLineCount(); startLineNumber = Math.min(lineCount, Math.max(1, startLineNumber)); @@ -2723,7 +2601,6 @@ function validateDiffEditorOptions(options: Readonly, defaul let outOptions: any = { enableSplitViewResizing: validateBooleanOption(options.enableSplitViewResizing, defaults.enableSplitViewResizing), renderSideBySide: validateBooleanOption(options.renderSideBySide, defaults.renderSideBySide), - renderMarginRevertIcon: validateBooleanOption(options.renderMarginRevertIcon, defaults.renderMarginRevertIcon), maxComputationTime: clampedInt(options.maxComputationTime, defaults.maxComputationTime, 0, Constants.MAX_SAFE_SMALL_INTEGER), maxFileSize: clampedInt(options.maxFileSize, defaults.maxFileSize, 0, Constants.MAX_SAFE_SMALL_INTEGER), ignoreTrimWhitespace: validateBooleanOption(options.ignoreTrimWhitespace, defaults.ignoreTrimWhitespace), @@ -2741,7 +2618,6 @@ function changedDiffEditorOptions(a: ValidDiffEditorBaseOptions, b: ValidDiffEdi return { enableSplitViewResizing: (a.enableSplitViewResizing !== b.enableSplitViewResizing), renderSideBySide: (a.renderSideBySide !== b.renderSideBySide), - renderMarginRevertIcon: (a.renderMarginRevertIcon !== b.renderMarginRevertIcon), maxComputationTime: (a.maxComputationTime !== b.maxComputationTime), maxFileSize: (a.maxFileSize !== b.maxFileSize), ignoreTrimWhitespace: (a.ignoreTrimWhitespace !== b.ignoreTrimWhitespace), diff --git a/src/vs/editor/browser/widget/media/diffEditor.css b/src/vs/editor/browser/widget/media/diffEditor.css index b681cdf62b..e1a6a8001b 100644 --- a/src/vs/editor/browser/widget/media/diffEditor.css +++ b/src/vs/editor/browser/widget/media/diffEditor.css @@ -57,15 +57,6 @@ text-align: right; } -.monaco-editor .arrow-revert-change { - z-index: 10; - position: absolute; -} - -.monaco-editor .arrow-revert-change:hover { - cursor: pointer; -} - /* ---------- Inline Diff ---------- */ .monaco-editor .view-zones .view-lines .view-line span { diff --git a/src/vs/editor/common/config/editorConfigurationSchema.ts b/src/vs/editor/common/config/editorConfigurationSchema.ts index c320bcc755..e4cbd5abb2 100644 --- a/src/vs/editor/common/config/editorConfigurationSchema.ts +++ b/src/vs/editor/common/config/editorConfigurationSchema.ts @@ -146,11 +146,6 @@ const editorConfiguration: IConfigurationNode = { default: true, description: nls.localize('sideBySide', "Controls whether the diff editor shows the diff side by side or inline.") }, - 'diffEditor.renderMarginRevertIcon': { - type: 'boolean', - default: true, - description: nls.localize('renderMarginRevertIcon', "When enabled, the diff editor shows arrows in its glyph margin to revert changes.") - }, 'diffEditor.ignoreTrimWhitespace': { type: 'boolean', default: true, diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 89b0ce356b..7d485cc521 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -169,10 +169,6 @@ export interface IEditorOptions { * Control the behavior and rendering of the scrollbars. */ scrollbar?: IEditorScrollbarOptions; - /** - * Control the behavior of experimental options - */ - experimental?: IEditorExperimentalOptions; /** * Control the behavior and rendering of the minimap. */ @@ -567,7 +563,7 @@ export interface IEditorOptions { * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter. * Defaults to 'mouseover'. */ - showFoldingControls?: 'always' | 'never' | 'mouseover'; + showFoldingControls?: 'always' | 'mouseover'; /** * Controls whether clicking on the empty content after a folded line will unfold the line. * Defaults to false. @@ -663,13 +659,6 @@ export interface IEditorOptions { * Configures bracket pair colorization (disabled by default). */ bracketPairColorization?: IBracketPairColorizationOptions; - - /** - * Controls dropping into the editor from an external source. - * - * When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event. - */ - dropIntoEditor?: IDropIntoEditorOptions; } /** @@ -709,11 +698,6 @@ export interface IDiffEditorBaseOptions { * Defaults to true. */ renderIndicators?: boolean; - /** - * Shows icons in the glyph margin to revert changes. - * Default to true. - */ - renderMarginRevertIcon?: boolean; /** * Original model should be editable? * Defaults to false. @@ -832,7 +816,7 @@ export interface IEditorOption { /** * Might modify `value`. */ - applyUpdate(value: V | undefined, update: V): ApplyUpdateResult; + applyUpdate(value: V, update: V): ApplyUpdateResult; } /** @@ -861,7 +845,7 @@ abstract class BaseEditorOption implements IEditor this.schema = schema; } - public applyUpdate(value: V | undefined, update: V): ApplyUpdateResult { + public applyUpdate(value: V, update: V): ApplyUpdateResult { return applyUpdate(value, update); } @@ -879,13 +863,13 @@ export class ApplyUpdateResult { ) { } } -function applyUpdate(value: T | undefined, update: T): ApplyUpdateResult { +function applyUpdate(value: T, update: T): ApplyUpdateResult { if (typeof value !== 'object' || typeof update !== 'object' || !value || !update) { return new ApplyUpdateResult(update, value !== update); } if (Array.isArray(value) || Array.isArray(update)) { const arrayEquals = Array.isArray(value) && Array.isArray(update) && arrays.equals(value, update); - return new ApplyUpdateResult(update, !arrayEquals); + return new ApplyUpdateResult(update, arrayEquals); } let didChange = false; for (const key in update) { @@ -916,7 +900,7 @@ abstract class ComputedEditorOption implements IEdito this.defaultValue = undefined; } - public applyUpdate(value: V | undefined, update: V): ApplyUpdateResult { + public applyUpdate(value: V, update: V): ApplyUpdateResult { return applyUpdate(value, update); } @@ -941,7 +925,7 @@ class SimpleEditorOption implements IEditorOption { + public applyUpdate(value: V, update: V): ApplyUpdateResult { return applyUpdate(value, update); } @@ -2340,7 +2324,6 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption { - - constructor() { - const defaults: EditorExperimentalOptions = { stickyScroll: { enabled: false } }; - super( - EditorOption.experimental, 'experimental', defaults, - { - 'editor.experimental.stickyScroll.enabled': { - type: 'boolean', - default: defaults.stickyScroll.enabled, - description: nls.localize('editor.experimental.stickyScroll', "Shows the nested current scopes during the scroll at the top of the editor.") - }, - } - ); - } - - public validate(_input: any): EditorExperimentalOptions { - if (!_input || typeof _input !== 'object') { - return this.defaultValue; - } - const input = _input as IEditorExperimentalOptions; - return { - stickyScroll: { - enabled: boolean(input.stickyScroll?.enabled, this.defaultValue.stickyScroll.enabled) - } - }; - } -} - -//#endregion - //#region inlayHints /** @@ -2589,10 +2521,11 @@ export interface IEditorInlayHintsOptions { fontFamily?: string; /** - * Enables the padding around the inlay hint. - * Defaults to false. + * The display style to render inlay hints with. + * Compact mode disables the borders and padding around the inlay hint. + * Defaults to 'standard'. */ - padding?: boolean; + displayStyle: 'standard' | 'compact'; } /** @@ -2603,7 +2536,7 @@ export type EditorInlayHintsOptions = Readonly { constructor() { - const defaults: EditorInlayHintsOptions = { enabled: 'on', fontSize: 0, fontFamily: '', padding: false }; + const defaults: EditorInlayHintsOptions = { enabled: 'on', fontSize: 0, fontFamily: '', displayStyle: 'compact' }; super( EditorOption.inlayHints, 'inlayHints', defaults, { @@ -2622,18 +2555,23 @@ class EditorInlayHints extends BaseEditorOption(input.enabled, this.defaultValue.enabled, ['on', 'off', 'offUnlessPressed', 'onUnlessPressed']), fontSize: EditorIntOption.clampedInt(input.fontSize, this.defaultValue.fontSize, 0, 100), fontFamily: EditorStringOption.string(input.fontFamily, this.defaultValue.fontFamily), - padding: boolean(input.padding, this.defaultValue.padding) + displayStyle: stringSet<'standard' | 'compact'>(input.displayStyle, this.defaultValue.displayStyle, ['standard', 'compact']) }; } } @@ -2691,10 +2629,6 @@ export interface IEditorMinimapOptions { * Defaults to true. */ enabled?: boolean; - /** - * Control the rendering of minimap. - */ - autohide?: boolean; /** * Control the side of the minimap in editor. * Defaults to 'right'. @@ -2739,7 +2673,6 @@ class EditorMinimap extends BaseEditorOption