diff --git a/.evergreen/compass_package.sh b/.evergreen/compass_package.sh index 6c68bb4fc70..078d9946cda 100755 --- a/.evergreen/compass_package.sh +++ b/.evergreen/compass_package.sh @@ -7,11 +7,8 @@ if [[ "$OSTYPE" == "cygwin" ]]; then net start MSIServer fi -# Ensure .sbom is always created with fresh data -rm -rvf .sbom && mkdir -pv .sbom - echo "Creating signed release build..." -npm run package-compass $COMPASS_DISTRIBUTION; +npm run package-compass-nocompile $COMPASS_DISTRIBUTION npm run generate-first-party-deps-json ls -la packages/compass/dist diff --git a/.evergreen/functions.yml b/.evergreen/functions.yml index 818faa44080..c448cf01812 100644 --- a/.evergreen/functions.yml +++ b/.evergreen/functions.yml @@ -410,19 +410,15 @@ functions: DEBUG: ${debug} npm_config_loglevel: ${npm_loglevel} COMPASS_DISTRIBUTION: ${compass_distribution} - SIGNING_SERVER_HOSTNAME: ${SIGNING_SERVER_HOSTNAME} - SIGNING_SERVER_PRIVATE_KEY: ${SIGNING_SERVER_PRIVATE_KEY} - SIGNING_SERVER_PRIVATE_KEY_CYGPATH: ${SIGNING_SERVER_PRIVATE_KEY_CYGPATH} - SIGNING_SERVER_USERNAME: ${SIGNING_SERVER_USERNAME} - SIGNING_SERVER_PORT: ${SIGNING_SERVER_PORT} - GITHUB_PR_NUMBER: ${github_pr_number} - PAPERTRAIL_KEY_ID: ${papertrail_key_id} - PAPERTRAIL_SECRET_KEY: ${papertrail_secret_key} script: | set -e + + # Ensure .sbom is always created with fresh data + rm -rvf .sbom && mkdir -pv .sbom + # Load environment variables eval $(.evergreen/print-compass-env.sh) - .evergreen/compass_package.sh + cd packages/compass && npm run prepackage-compass - command: shell.exec params: working_dir: src @@ -443,6 +439,29 @@ functions: set -e .evergreen/create-sbom.sh + - command: shell.exec + params: + working_dir: src + shell: bash + env: + <<: *compass-env + DEBUG: ${debug} + npm_config_loglevel: ${npm_loglevel} + COMPASS_DISTRIBUTION: ${compass_distribution} + SIGNING_SERVER_HOSTNAME: ${SIGNING_SERVER_HOSTNAME} + SIGNING_SERVER_PRIVATE_KEY: ${SIGNING_SERVER_PRIVATE_KEY} + SIGNING_SERVER_PRIVATE_KEY_CYGPATH: ${SIGNING_SERVER_PRIVATE_KEY_CYGPATH} + SIGNING_SERVER_USERNAME: ${SIGNING_SERVER_USERNAME} + SIGNING_SERVER_PORT: ${SIGNING_SERVER_PORT} + GITHUB_PR_NUMBER: ${github_pr_number} + PAPERTRAIL_KEY_ID: ${papertrail_key_id} + PAPERTRAIL_SECRET_KEY: ${papertrail_secret_key} + COMPASS_WAS_COMPILED_AND_HAS_SBOM: '1' + script: | + set -e + # Load environment variables + eval $(.evergreen/print-compass-env.sh) + .evergreen/compass_package.sh get_first_party_dependency_list: - command: s3.get diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e4d9c53ebbf..eb110cfc9a7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,10 +3,10 @@ ## Getting Started -You'll need node `^16` and npm `^8` installed on your machine to work with the repository locally. +You'll need node `^18` and npm `^10` installed on your machine to work with the repository locally. After your environment is ready, navigate to the repository and run `npm run bootstrap`, this will install dependencies and will compile all packages. -After bootstrap is finished, you should be able to run `npm run start` and see Compass application running locally. +After bootstrap is finished, you should be able to run `npm run start` and see Compass application running locally. Alternatively you can start a web version of the app by running `npm run start-web`. Compass uses a monorepo is powered by [`npm workspaces`](https://docs.npmjs.com/cli/v7/using-npm/workspaces) and [`lerna`](https://github.com/lerna/lerna#readme), although not necessary, it might be helpful to have a high level understanding of those tools. @@ -80,7 +80,7 @@ DEBUG=hadron* npm run package-compass To speed up the process you might want to disable creating installer for the application. To do that you can set `HADRON_SKIP_INSTALLER` environmental variable to `true` when running the script ```sh -HADRON_SKIP_INSTALLER=true npm run test-package-compass +HADRON_SKIP_INSTALLER=true npm run package-compass ``` ### Publishing Packages diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index fe6bb33c678..ab82031e4da 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -1,32 +1,32 @@ The following third-party software is used by and included in **Mongodb Compass**. -This document was automatically generated on Mon Jul 01 2024. +This document was automatically generated on Thu Jul 18 2024. ## List of dependencies | Package | Version | License | | --------------------------------------------------------------------------------------------------------------------------- | ------------ | ----------------------------------- | | **[@ampproject/remapping](#0dc8b6568eb743fd551ce2cf2f54be9d0f94b12167f7c34a997c864bcc7e128d)** | 2.2.0 | Apache-2.0 | -| **[@aws-sdk/client-cognito-identity](#47bea5b619f88d5a8df7d7a2e75ebf3ef3ed22e93b81223bba015da93adbc94d)** | 3.600.0 | Apache-2.0 | -| **[@aws-sdk/client-sso](#7ef3dd099b90443dbafe1904d05c3f58a290c39fc3fef843b77303096bc53bf0)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/client-sts](#cbb78f53042210aa1576d3a659c9b6f18c06a69c155a49479ba41c873a0387b1)** | 3.600.0 | Apache-2.0 | -| **[@aws-sdk/core](#d40906092cb82f9d17addebcaf0cbbfdaef6045b387178f4cf36e8ade7b7b542)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-cognito-identity](#d1574824f019f6d00315001611125388584e03a0b72e5332ae1498cc819ecad0)** | 3.600.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-env](#986873fdadbf90900a699e1e707207d128f52a8cf4389ba298c30407906a9110)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-http](#a3cfc02529dfe9fe3bf1f872e1a3bd34ea9d21cb5eb3d9b2ac0d6531e2f3bfcc)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-ini](#15b18b6979a0eb1f7f748498fa327815b0cf5da1523438282240fa77ca2c3c45)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-node](#53e9576bdfcbc35d32acc387c89563645e10e5fcb0c2314f9a0c8118205b44a9)** | 3.600.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-process](#38cd4871c82376442f544a156a813e5c7cb4a60cce4ef64a384dea0371f5fee5)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-sso](#d27472728c4e0bdab39594192ed36f028a1d96d405f4ef225679d1d19e33e35f)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-provider-web-identity](#283bd6b7713e133218120564a6f5af1e1d0ee9a575094e4069d38c66201c1970)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/credential-providers](#dc2d0fbdeb86d99d54795a7626145659d35af3ddda762263e63b25654a053080)** | 3.600.0 | Apache-2.0 | -| **[@aws-sdk/middleware-host-header](#505d95a0836d30463574a2790eabed0e5f1bcf805cbf6dca694daf95e93d62d0)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/middleware-logger](#266b3eecb943b4f1e01f45907eed2f8b83ec964279fd68f493023058caaf478d)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/middleware-recursion-detection](#a5e99c44ea545bc16d00ec674adf3f62a90dfa57ff54f5a64b11ca53a9cf3e21)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/middleware-user-agent](#a616eb50273cf4dd2ee8952badc990d77103ba0364adb975071cb8ad196c2af7)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/region-config-resolver](#81a70bf3a97cbb7670e5045654de438e29bc49087ba51d9efd54700ab774267d)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/token-providers](#513369c64b30921bd83f09b3265f58137b3d56a17c5e5595bfd4161896083616)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/util-endpoints](#1291e1b7109d5075dd86d6edcc9c9b08043c82a96407e63b9b0658476d67309e)** | 3.598.0 | Apache-2.0 | -| **[@aws-sdk/util-user-agent-node](#ae0125d68224f39697d3055fea3d10e75c472a5e0ab80261eb892c631fb572fe)** | 3.598.0 | Apache-2.0 | +| **[@aws-sdk/client-cognito-identity](#c0c0afdb60b2e34c5b82cc2bf805376070b47d5fb2c6d3ebc3006cd7f765e54b)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/client-sso](#27063b9d0b119a4074c84e09929a91d76a4bcbdc0224dbcb1d4a925ac40926b5)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/client-sts](#08023eebb5d66406f83dc01d7b964953657a498ac21db0620c57d673420e399f)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/core](#4c2e0fe4d16707642c0cb2f52c0ab0ab658eb7ff36cc57a9b3a43c762eddabfa)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-cognito-identity](#a47edc8bc7c24f7fab0722c57692b8cbbc35ffea3cba73d49c6acc7a9683daf6)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-env](#6739c2ed94a4419293b0f1a4a926d98c86c2376489867052c046af399db4ab30)** | 3.609.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-http](#e4547f253f3a2afeddce32f1462b4ba6417a9c68771f08a26fa645167450b63d)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-ini](#482893e96fb2356256c4a4cd5aa6fa6e92feca80ac026de66ecb80a403895b3a)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-node](#2b7e70c1f9cfa84fbce456caaeb43c24c1bb47e309bdf0e90701a5ec784d1375)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-process](#29fea5294ca5df9f2450dbc8d8fd2fb23204b8eecd69807af0b4426d17aa2097)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-sso](#312230a845d7322a75f0d6ab509b26cdab239d3972cc2c4bed417b37ef7b7368)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/credential-provider-web-identity](#af789cf57861b0fa0338bc933ad45fa59926e4e98757cb04de5557ffefa3d46a)** | 3.609.0 | Apache-2.0 | +| **[@aws-sdk/credential-providers](#13573227dc1cf1b3f83f710a09a1b53967fdbf5f26e15be0b2c2c0747a92b82b)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/middleware-host-header](#7aeb28519530ce1d1dffe82b20d6dbe56aba431c556821b8c74702f9c8a37ea6)** | 3.609.0 | Apache-2.0 | +| **[@aws-sdk/middleware-logger](#77971232a25c0db769f48f8c0b70d1272e792393db29953a47d319effbca9616)** | 3.609.0 | Apache-2.0 | +| **[@aws-sdk/middleware-recursion-detection](#30c1b2cdc151fb80d8d0234d050e200b63b08fb39c198e0c72cb635720bfbb71)** | 3.609.0 | Apache-2.0 | +| **[@aws-sdk/middleware-user-agent](#a09483c95bbdc4dcf425caf3eff5c7bb7dd90e49e939621ea006d6c897d49c36)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/region-config-resolver](#c707d161415ea2bbe26756eb111aa1fa6e20fe297f8357c2314200f1bc7b4812)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/token-providers](#2797e884608a8f3c4d716b944c9df465acbf619c27612fecdf21e6feac32ffd4)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/util-endpoints](#8bc3f35151624d4ab0a7c417c04111a48fc00ea5925c7078f93c6f419a374314)** | 3.614.0 | Apache-2.0 | +| **[@aws-sdk/util-user-agent-node](#78337458e259597e1af9ae36c139707b9d47d298d6b660fda8ca49f7a6039933)** | 3.614.0 | Apache-2.0 | | **[@babel/code-frame](#414cb15586d104447ca15cc1904c5779eb415e9079a4a3ca6a81ad96ba9ee4e1)** | 7.24.7 | MIT | | **[@babel/compat-data](#c387b8b259687bd33e4dad059e4c9317487ea054a71da25c13a716e64e5f45c4)** | 7.24.7 | MIT | | **[@babel/core](#c5f859753e1c47fb8300f9ee25830d5458b76162f472b6a052e4c2a6597a33ff)** | 7.16.0 | MIT | @@ -114,39 +114,39 @@ This document was automatically generated on Mon Jul 01 2024. | **[@segment/analytics-core](#ceca19940ddcc60d35099f1b04cb449caddc02f22a12fc4b6e9afab7b5b38e14)** | 1.4.0 | MIT | | **[@segment/analytics-generic-utils](#9f4e5775b541ec8bbc32077308532f03fb923e2fb19fff11ac4506ee4498af13)** | 1.1.0 | MIT | | **[@segment/analytics-node](#5e36f09aa494e968de1e219302594c1aa82f14d2287c063fe1be910021fe1879)** | 1.1.4 | MIT | -| **[@smithy/config-resolver](#e9085727b5f62985385fb7c5c9d129ad291ee9d016ae0487c90a8d9b895efdf4)** | 3.0.3 | Apache-2.0 | -| **[@smithy/core](#3c68253152da1557af6ab85ce7e2602ccdc82480558950547953c90322287bb1)** | 2.2.3 | Apache-2.0 | -| **[@smithy/credential-provider-imds](#16f2c22bc84d50e2b8de706e10f281d87081babd23fedee72434bf6192cc656b)** | 3.1.2 | Apache-2.0 | -| **[@smithy/fetch-http-handler](#9eff767e30f2e97dab537eff710651431d815a1f7537dad3388a8576806861d7)** | 3.1.0 | Apache-2.0 | -| **[@smithy/hash-node](#7e39f1e2ba565fd11658309782a0533b29a45ed6125979fb3cf46b6a5c6d0693)** | 3.0.2 | Apache-2.0 | +| **[@smithy/config-resolver](#50159dd3d75e4f4233935008371e16a6721f052e958a5c4b9c7283e5adaf8f33)** | 3.0.5 | Apache-2.0 | +| **[@smithy/core](#af7fbcf61ef4e6ccdc120ac3c69cbbbca067dac1adfa86238c68d6290b1d1be2)** | 2.2.6 | Apache-2.0 | +| **[@smithy/credential-provider-imds](#7fc324eaaa4cff223af2145907e0d5d76e2bf80a6be086b5d2b2e67cbf47021c)** | 3.1.4 | Apache-2.0 | +| **[@smithy/fetch-http-handler](#8343d3da3e0369cc62fc7f60c3bab1ae057558f600df46dfa1c6d43ad302a73b)** | 3.2.1 | Apache-2.0 | +| **[@smithy/hash-node](#391a956b0a8b9c2f7af88541150eca7a355c08e2c891e15170a0cedb66f8c843)** | 3.0.3 | Apache-2.0 | | **[@smithy/is-array-buffer](#3e840c8e473fca775cfba50e1c0832e2a2734ae3e75418b55905122f260bd73a)** | 3.0.0 | Apache-2.0 | -| **[@smithy/middleware-content-length](#d813659e000b2f1679599af30250559b030214dd3a971df82bc19c0d056f60d9)** | 3.0.2 | Apache-2.0 | -| **[@smithy/middleware-endpoint](#66ca0023d96f2a71d18525be11958bbb43f7d2264357fb96532ea7cf1d3b4bbb)** | 3.0.3 | Apache-2.0 | -| **[@smithy/middleware-retry](#22b3f3b7a8bd3bd4e228dceeebbe71296c6dc123a966abc64ddb2b806bc45e03)** | 3.0.6 | Apache-2.0 | -| **[@smithy/middleware-serde](#a101b8f4695aa87f5c9d1460e3106201f976d4012c20cc79c8e7d2653ed29914)** | 3.0.2 | Apache-2.0 | -| **[@smithy/middleware-stack](#04eaf282d7eb44285a64689d2a1be67952c3b73ab9239f511219b8e16ae1a1de)** | 3.0.2 | Apache-2.0 | -| **[@smithy/node-config-provider](#e22c4521b4156658588d301b0aee73301575067a98a5ccf2e51840e616261283)** | 3.1.2 | Apache-2.0 | -| **[@smithy/node-http-handler](#be9e38335e087c0d876a7d82713c0934a1667c4b6af9125a49b3312003d3336e)** | 3.1.0 | Apache-2.0 | -| **[@smithy/property-provider](#fc3cbd6e56e41c1b79ecced819432dbfb392b3334a5272d27c8ecac77b8bedfc)** | 3.1.2 | Apache-2.0 | -| **[@smithy/protocol-http](#13c5b050247fbdcf0f3735f40613ec5fd956995296620a33329b30c756924526)** | 4.0.2 | Apache-2.0 | -| **[@smithy/querystring-builder](#bb1501ef3b771643ea36cc1ae5cd3280b3996fefc56ab2f4180f6f6f55e7b55b)** | 3.0.2 | Apache-2.0 | -| **[@smithy/querystring-parser](#994bbec7bb22cf65eff261a9f544045264430608ec36cb4a45080646e9e43f66)** | 3.0.2 | Apache-2.0 | -| **[@smithy/service-error-classification](#d874088693e4eef5ed712776d3a90b3a687b11de53ad370f969003288101b06f)** | 3.0.2 | Apache-2.0 | -| **[@smithy/shared-ini-file-loader](#56a4dd351708e0e6264094bf05e7f26a07c882d04caaacd9855d3856ce931c96)** | 3.1.2 | Apache-2.0 | -| **[@smithy/signature-v4](#71144494dc619b7333b1f4fa7c212e3f27c0d73c493bbb0ade64301164032119)** | 3.1.1 | Apache-2.0 | -| **[@smithy/smithy-client](#1b6a0f148d37e3a2817e913a8bb56f8a5899a98c48f4820e5b4b1c0b83b5c321)** | 3.1.4 | Apache-2.0 | -| **[@smithy/types](#14a3e63eb8021210a20f73f9b4f000b24f0a121b6d849f3670a856af0ea42002)** | 3.2.0 | Apache-2.0 | -| **[@smithy/url-parser](#a8e72daad38bb1af5ddc9443af1a7c66152073695b4f9cfb22c578891c0044a8)** | 3.0.2 | Apache-2.0 | +| **[@smithy/middleware-content-length](#a4474265ad671a42922c5ae61743465fcb3a418a0b75e89602aabb7a8a1da5f8)** | 3.0.3 | Apache-2.0 | +| **[@smithy/middleware-endpoint](#b455b0a194909e087a6244a44b1bd9d870882a27027316173a36929c978116f3)** | 3.0.5 | Apache-2.0 | +| **[@smithy/middleware-retry](#68b688b0406b7ac7e3099239db17640d4d12460b195d6d35afe23f211b7ee8f0)** | 3.0.9 | Apache-2.0 | +| **[@smithy/middleware-serde](#c3675ccf95f0205d19f112c92a7a34849fe09dcf0900877b295692cdee3b1a3b)** | 3.0.3 | Apache-2.0 | +| **[@smithy/middleware-stack](#ea63c1e355c55bbf2e59545c6fb05399ca941daeeec43540feb38e2fef98e93f)** | 3.0.3 | Apache-2.0 | +| **[@smithy/node-config-provider](#f3a27d12f80a2d60af7facfff889c045d65b56e0ec20904c87b998575b7e4605)** | 3.1.4 | Apache-2.0 | +| **[@smithy/node-http-handler](#d436a33cae7638cb64c01b91a886ce6cfff439bf3753831a2cd65524938cb624)** | 3.1.2 | Apache-2.0 | +| **[@smithy/property-provider](#1af73ed46575c11cb17328c5ab023c4689b6fd3aac8e95637d8a2430c8234d4e)** | 3.1.3 | Apache-2.0 | +| **[@smithy/protocol-http](#d804cc77ac12eee410678ecff6dff0cc3784c4a0474d05c31a148c2b29314fc3)** | 4.0.3 | Apache-2.0 | +| **[@smithy/querystring-builder](#200f9715ba37573546a0ba50d6600f493501ad1fa99a1214f4652edd3f32eb6b)** | 3.0.3 | Apache-2.0 | +| **[@smithy/querystring-parser](#b2d703203bc9334d657f0cfe5e2f3ff2e029f4be60ccb9a837373f1019e30bc5)** | 3.0.3 | Apache-2.0 | +| **[@smithy/service-error-classification](#557a776a2222ef5b1930bc9c154cc80a4422644765747502c34995779de707f9)** | 3.0.3 | Apache-2.0 | +| **[@smithy/shared-ini-file-loader](#103ac7bac6c71c7909ddff4de45221eefb970300f5eee041039c35ce86e6ade0)** | 3.1.4 | Apache-2.0 | +| **[@smithy/signature-v4](#0ed1919fbbced53521a598ad5f4289e0f63b966492f09aa0f409dd4211813b39)** | 3.1.2 | Apache-2.0 | +| **[@smithy/smithy-client](#ec9bfb7ea733c1569b7a827e5a9726fc4ea9a4c42fc9ce8113be6137c59e8839)** | 3.1.7 | Apache-2.0 | +| **[@smithy/types](#66e18d9960829b34832f8284a597f0e8bc4f70149542f7533dc9f05866bb22f2)** | 3.3.0 | Apache-2.0 | +| **[@smithy/url-parser](#cc28500f1b3dbf7f305e81f81414d3f5cd733e00df104a56acdd5b82f2f19ef4)** | 3.0.3 | Apache-2.0 | | **[@smithy/util-base64](#c13f86d5882c72328221d234d624fc36da9fe0ef6270d9ed0f7a3690616bc0b7)** | 3.0.0 | Apache-2.0 | | **[@smithy/util-body-length-node](#a84f0a1a3fcd05391da50ee998d84695412ce141bdae38ca182c11a58eb7df38)** | 3.0.0 | Apache-2.0 | | **[@smithy/util-buffer-from](#33c6c26bbdc76fe4bf4ca385fe9618fa7322bd346d836ee4b18e5b322e256051)** | 3.0.0 | Apache-2.0 | | **[@smithy/util-config-provider](#c87a7523255ad59e5f721bd27137222d188dc0507d93c4cd946092736ca3b582)** | 3.0.0 | Apache-2.0 | -| **[@smithy/util-defaults-mode-node](#863e63964333037f44842c10e3f828d9b2160de2026835abc96903b7fd2bf5b4)** | 3.0.6 | Apache-2.0 | -| **[@smithy/util-endpoints](#9581aca21070280435cb73980f224166d5d709d22beec655ef2d09a7c7cb5df4)** | 2.0.3 | Apache-2.0 | +| **[@smithy/util-defaults-mode-node](#d4e235ac2da6275b6f6e0dac8e1172df7e3b36762ddc8ea4629b1dcd844299e3)** | 3.0.9 | Apache-2.0 | +| **[@smithy/util-endpoints](#6bbc52b3dfd8d143c95f7c48631d054e2b4c76ed74a0e449c36a12a4d3505279)** | 2.0.5 | Apache-2.0 | | **[@smithy/util-hex-encoding](#f797009fb996f0b306124df8c5f82a938af17ab613ee4a6d1b7e2014b26fdde7)** | 3.0.0 | Apache-2.0 | -| **[@smithy/util-middleware](#d8cb57339cc812fa9d41400e49304f08690d75c0f7c5be180b992a5faa36dd78)** | 3.0.2 | Apache-2.0 | -| **[@smithy/util-retry](#2eacb236bfde505f25a3e4a090c79707f2a46afd74913166438e94f28c0707bd)** | 3.0.2 | Apache-2.0 | -| **[@smithy/util-stream](#ae2a60e9539e2f28fb154c2ce5796d1eeb4e7e0669bbee67eea73d5c374ad682)** | 3.0.4 | Apache-2.0 | +| **[@smithy/util-middleware](#cdddd643148aefb93fd2abb8f3ea636694a4d11ed1e7e6f883fa81661a3b7dd2)** | 3.0.3 | Apache-2.0 | +| **[@smithy/util-retry](#b62c349356fcac274685aa0ab184eb71cac5084041f86ba14fd6f4cd091ee49e)** | 3.0.3 | Apache-2.0 | +| **[@smithy/util-stream](#2031a000ca09eb820042e5886e16806bea05e42159f7ea3cc118d093a0281ed4)** | 3.0.6 | Apache-2.0 | | **[@smithy/util-uri-escape](#00c89382e0278c66e8d4394996711d826b23491ef5e313b58f5681da7a07d0b6)** | 3.0.0 | Apache-2.0 | | **[@smithy/util-utf8](#c0da7acc7121c0e4e76c58d92e290275318534cfce16949c7b916cfa0301c3b9)** | 3.0.0 | Apache-2.0 | | **[@tanstack/react-table](#3472fd929bf691e34b02f3f62232cafe55163b92e3c51afc884780ba2413e67f)** | 8.14.0 | MIT | @@ -235,10 +235,9 @@ This document was automatically generated on Mon Jul 01 2024. | **[domify](#4360a769ee10e827f9ae503aa7ea9aeb9039932fa02ac938316df303704a7fb1)** | 1.4.1 | MIT | | **[dset](#0ad3cccee140cec056ad5553443d2c3609cb002e279e2820cada2d6cb85c883d)** | 3.1.3 | MIT | | **[ee-first](#e2746902c758ae8a6f91ffb9618cd53717f936cb33c6323e65b6b7b24f7ebefe)** | 1.1.1 | MIT | -| **[ejson-shell-parser](#88e1a447c02d9ef3274034c023a5ebcec8188381b1bd951de7c57c140f7f3d4b)** | 2.0.1 | MIT | | **[electron-dl](#e97e034c7b93c63e7a433d75f6f1de3e0668764225ebbd61dbde8d1b55d6f3b7)** | 3.5.0 | MIT | | **[electron-squirrel-startup](#09fb8168e8fda2e174f8d1a1c392ffd8f762c5637c788edd00d1e2486d060349)** | 1.0.1 | Apache-2.0 | -| **[electron](#23de25a47b9c95fe5de7e7d13e9ef6a17313dcbe5903b274bb4b85a165a056f2)** | 29.4.3 | MIT | +| **[electron](#2d57f0e02aec4ac92532b06902fbe13af26292bde2d718c49f75a8fe02c85fdd)** | 29.4.5 | MIT | | **[encodeurl](#b89152db475e86531e570f87b45d8a51aa5e5d87d4cc3b960cee7b8febf1d26a)** | 1.0.2 | MIT | | **[end-of-stream](#fadc10994f5fa767d06fb25cfff35fb17a895daf3bc3477c782907668ed16563)** | 1.4.4 | MIT | | **[ensure-error](#3b1eba5276d89414cef21a1007e85c4f1d6749bf57b300e082ab23975a41dbc9)** | 3.0.1 | MIT | @@ -422,8 +421,8 @@ This document was automatically generated on Mon Jul 01 2024. | **[mongodb-connection-string-url](#2e1146256a89ebd24e3398881e03807fe363d58444e6b7952ea50bd6108707bc)** | 3.0.1 | Apache-2.0 | | **[mongodb-log-writer](#c4945018f8490fc8e56e1414e262fcf1b802800e05cd15f2bd6b7a9d0b94af85)** | 1.4.2 | Apache-2.0 | | **[mongodb-ns](#68260f4d06e4d16a28d4139e391264d220e891ac6f0fb844b925a0cc37792aff)** | 2.4.2 | MIT | -| **[mongodb-query-parser](#9f3ddf73a8002fab690b67f0054b65229001a6020a697e3ea8103b39dc20dd94)** | 4.1.2 | Apache-2.0 | -| **[mongodb-redact](#f2e211a75ccc2bd1c32144837dbd44675e30fd51a9e4e60b8ba3bc0b1750af38)** | 0.2.3 | Apache-2.0 | +| **[mongodb-query-parser](#54882af81246ce19e8a17d9d9f024887e6dee6567cc6677e67678a3ed61281a3)** | 4.2.0 | Apache-2.0 | +| **[mongodb-redact](#5e6afee018104befaaf45f0b7eb3cf888cb0b1f2ce3a1ff5f74baafd43a4c627)** | 1.1.1 | Apache-2.0 | | **[mongodb-schema](#652dcef4a8a39849996a5f858fe48048e806fda4ce1aa0f757ada56bef011145)** | 12.2.0 | Apache-2.0 | | **[mongodb](#d7483daab94fde07ac4a7920bd6d7070eec5f48fdf516669acd398920978d9fe)** | 6.7.0 | Apache-2.0 | | **[ms](#484b814b85d5028e34246147c8fc901d33570202bd7cdc3703c0ed1078eba0aa)** | 2.0.0 | MIT | @@ -498,7 +497,7 @@ This document was automatically generated on Mon Jul 01 2024. | **[scheduler](#950b09ca6f4766ded0bdde81e2697b5e184ed63925d74a8f512c978cab5bda6f)** | 0.20.2 | MIT | | **[select](#12d30053a00882385c42a50004536696d477e8e694b047d6d39513947e5a39e9)** | 1.1.2 | MIT | | **[semver](#8b8f657069cf84b7ca932ab17eb24a0a55a8053ccd2a36c03185dadab64db3f8)** | 6.3.1 | ISC | -| **[semver](#71de4ee7dd984e3cd1e9f57341f55d0ac36409a24466ac2516f5e3dac67a57ff)** | 7.6.2 | ISC | +| **[semver](#2c8b8c47dd7d24873eda4559b25851062c21d7584a396735b363f9bab626dd7b)** | 7.6.3 | ISC | | **[send](#a5aa96052b8bf57c58c38d6fae3a3b7d94ec212b6100f58a8260eb2f6a8cff6d)** | 0.18.0 | MIT | | **[serve-static](#03156d123ff3a9482fa09d97af4668d5e2ae058c4e3d2c67fe4a1c0c072403f0)** | 1.15.0 | MIT | | **[set-function-length](#88ee3e1c8e8c22ac3653a290c1cdc68787d064f17a743020a070b31290bb4eb9)** | 1.2.2 | MIT | @@ -535,7 +534,7 @@ This document was automatically generated on Mon Jul 01 2024. | **[stylis](#131ca0470639719771dc1f233c9962655afffb6d27143e894c43e967517107cf)** | 4.2.0 | MIT | | **[supports-color](#113926f6cb42a3d41d1c11fb1209faf789d78f51fb458da90c61e5c1a2307a8e)** | 5.5.0 | MIT | | **[supports-color](#b97a30572cac0a03b8cf442bc01621a041d5714550984f25cb71fac2587edbd6)** | 7.2.0 | MIT | -| **[system-ca](#9e5b405b0ec07c010c543203b3ad3b444dd02a42efb8f14f4b2a19b9fe7ab48e)** | 1.0.3 | Apache-2.0 | +| **[system-ca](#c2c7305095bb1ca56f7fc09b2f13d3c299e06e8d5ed0e0e84ac0872767291401)** | 2.0.0 | Apache-2.0 | | **[tabbable](#0ebe87140b76c7f2135bbd5099e7973a5ec2b5d8fe2bec8e272608cf0b3f396a)** | 5.3.3 | MIT | | **[tar-fs](#8e5bae5073977abd61cb5549abc7581354454558aedf4a4002b91e6fd7b9830d)** | 2.1.1 | MIT | | **[tar-stream](#5605712784129d10d2559e12f8031603f0cf4e5ff206f09356e4bf1dc5ab1168)** | 1.6.2 | MIT | @@ -793,9 +792,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/client-cognito-identity](https://www.npmjs.com/package/@aws-sdk/client-cognito-identity) (version 3.600.0) +### [@aws-sdk/client-cognito-identity](https://www.npmjs.com/package/@aws-sdk/client-cognito-identity) (version 3.614.0) License tags: Apache-2.0 @@ -1005,9 +1004,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/client-sso](https://www.npmjs.com/package/@aws-sdk/client-sso) (version 3.598.0) +### [@aws-sdk/client-sso](https://www.npmjs.com/package/@aws-sdk/client-sso) (version 3.614.0) License tags: Apache-2.0 @@ -1217,9 +1216,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/client-sts](https://www.npmjs.com/package/@aws-sdk/client-sts) (version 3.600.0) +### [@aws-sdk/client-sts](https://www.npmjs.com/package/@aws-sdk/client-sts) (version 3.614.0) License tags: Apache-2.0 @@ -1429,15 +1428,15 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/core](https://www.npmjs.com/package/@aws-sdk/core) (version 3.598.0) +### [@aws-sdk/core](https://www.npmjs.com/package/@aws-sdk/core) (version 3.614.0) License tags: Apache-2.0 - + -### [@aws-sdk/credential-provider-cognito-identity](https://www.npmjs.com/package/@aws-sdk/credential-provider-cognito-identity) (version 3.600.0) +### [@aws-sdk/credential-provider-cognito-identity](https://www.npmjs.com/package/@aws-sdk/credential-provider-cognito-identity) (version 3.614.0) License tags: Apache-2.0 @@ -1647,9 +1646,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-provider-env](https://www.npmjs.com/package/@aws-sdk/credential-provider-env) (version 3.598.0) +### [@aws-sdk/credential-provider-env](https://www.npmjs.com/package/@aws-sdk/credential-provider-env) (version 3.609.0) License tags: Apache-2.0 @@ -1859,15 +1858,15 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-provider-http](https://www.npmjs.com/package/@aws-sdk/credential-provider-http) (version 3.598.0) +### [@aws-sdk/credential-provider-http](https://www.npmjs.com/package/@aws-sdk/credential-provider-http) (version 3.614.0) License tags: Apache-2.0 - + -### [@aws-sdk/credential-provider-ini](https://www.npmjs.com/package/@aws-sdk/credential-provider-ini) (version 3.598.0) +### [@aws-sdk/credential-provider-ini](https://www.npmjs.com/package/@aws-sdk/credential-provider-ini) (version 3.614.0) License tags: Apache-2.0 @@ -2077,9 +2076,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-provider-node](https://www.npmjs.com/package/@aws-sdk/credential-provider-node) (version 3.600.0) +### [@aws-sdk/credential-provider-node](https://www.npmjs.com/package/@aws-sdk/credential-provider-node) (version 3.614.0) License tags: Apache-2.0 @@ -2289,9 +2288,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-provider-process](https://www.npmjs.com/package/@aws-sdk/credential-provider-process) (version 3.598.0) +### [@aws-sdk/credential-provider-process](https://www.npmjs.com/package/@aws-sdk/credential-provider-process) (version 3.614.0) License tags: Apache-2.0 @@ -2501,9 +2500,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-provider-sso](https://www.npmjs.com/package/@aws-sdk/credential-provider-sso) (version 3.598.0) +### [@aws-sdk/credential-provider-sso](https://www.npmjs.com/package/@aws-sdk/credential-provider-sso) (version 3.614.0) License tags: Apache-2.0 @@ -2713,9 +2712,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-provider-web-identity](https://www.npmjs.com/package/@aws-sdk/credential-provider-web-identity) (version 3.598.0) +### [@aws-sdk/credential-provider-web-identity](https://www.npmjs.com/package/@aws-sdk/credential-provider-web-identity) (version 3.609.0) License tags: Apache-2.0 @@ -2925,9 +2924,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/credential-providers](https://www.npmjs.com/package/@aws-sdk/credential-providers) (version 3.600.0) +### [@aws-sdk/credential-providers](https://www.npmjs.com/package/@aws-sdk/credential-providers) (version 3.614.0) License tags: Apache-2.0 @@ -3137,9 +3136,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/middleware-host-header](https://www.npmjs.com/package/@aws-sdk/middleware-host-header) (version 3.598.0) +### [@aws-sdk/middleware-host-header](https://www.npmjs.com/package/@aws-sdk/middleware-host-header) (version 3.609.0) License tags: Apache-2.0 @@ -3349,9 +3348,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/middleware-logger](https://www.npmjs.com/package/@aws-sdk/middleware-logger) (version 3.598.0) +### [@aws-sdk/middleware-logger](https://www.npmjs.com/package/@aws-sdk/middleware-logger) (version 3.609.0) License tags: Apache-2.0 @@ -3561,9 +3560,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/middleware-recursion-detection](https://www.npmjs.com/package/@aws-sdk/middleware-recursion-detection) (version 3.598.0) +### [@aws-sdk/middleware-recursion-detection](https://www.npmjs.com/package/@aws-sdk/middleware-recursion-detection) (version 3.609.0) License tags: Apache-2.0 @@ -3773,9 +3772,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/middleware-user-agent](https://www.npmjs.com/package/@aws-sdk/middleware-user-agent) (version 3.598.0) +### [@aws-sdk/middleware-user-agent](https://www.npmjs.com/package/@aws-sdk/middleware-user-agent) (version 3.614.0) License tags: Apache-2.0 @@ -3985,9 +3984,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/region-config-resolver](https://www.npmjs.com/package/@aws-sdk/region-config-resolver) (version 3.598.0) +### [@aws-sdk/region-config-resolver](https://www.npmjs.com/package/@aws-sdk/region-config-resolver) (version 3.614.0) License tags: Apache-2.0 @@ -4197,9 +4196,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/token-providers](https://www.npmjs.com/package/@aws-sdk/token-providers) (version 3.598.0) +### [@aws-sdk/token-providers](https://www.npmjs.com/package/@aws-sdk/token-providers) (version 3.614.0) License tags: Apache-2.0 @@ -4409,9 +4408,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/util-endpoints](https://www.npmjs.com/package/@aws-sdk/util-endpoints) (version 3.598.0) +### [@aws-sdk/util-endpoints](https://www.npmjs.com/package/@aws-sdk/util-endpoints) (version 3.614.0) License tags: Apache-2.0 @@ -4621,9 +4620,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@aws-sdk/util-user-agent-node](https://www.npmjs.com/package/@aws-sdk/util-user-agent-node) (version 3.598.0) +### [@aws-sdk/util-user-agent-node](https://www.npmjs.com/package/@aws-sdk/util-user-agent-node) (version 3.614.0) License tags: Apache-2.0 @@ -9239,9 +9238,9 @@ License files: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - + -### [@smithy/config-resolver](https://www.npmjs.com/package/@smithy/config-resolver) (version 3.0.3) +### [@smithy/config-resolver](https://www.npmjs.com/package/@smithy/config-resolver) (version 3.0.5) License tags: Apache-2.0 @@ -9451,9 +9450,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/core](https://www.npmjs.com/package/@smithy/core) (version 2.2.3) +### [@smithy/core](https://www.npmjs.com/package/@smithy/core) (version 2.2.6) License tags: Apache-2.0 @@ -9663,9 +9662,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/credential-provider-imds](https://www.npmjs.com/package/@smithy/credential-provider-imds) (version 3.1.2) +### [@smithy/credential-provider-imds](https://www.npmjs.com/package/@smithy/credential-provider-imds) (version 3.1.4) License tags: Apache-2.0 @@ -9875,9 +9874,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/fetch-http-handler](https://www.npmjs.com/package/@smithy/fetch-http-handler) (version 3.1.0) +### [@smithy/fetch-http-handler](https://www.npmjs.com/package/@smithy/fetch-http-handler) (version 3.2.1) License tags: Apache-2.0 @@ -10087,9 +10086,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/hash-node](https://www.npmjs.com/package/@smithy/hash-node) (version 3.0.2) +### [@smithy/hash-node](https://www.npmjs.com/package/@smithy/hash-node) (version 3.0.3) License tags: Apache-2.0 @@ -10511,9 +10510,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/middleware-content-length](https://www.npmjs.com/package/@smithy/middleware-content-length) (version 3.0.2) +### [@smithy/middleware-content-length](https://www.npmjs.com/package/@smithy/middleware-content-length) (version 3.0.3) License tags: Apache-2.0 @@ -10723,9 +10722,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/middleware-endpoint](https://www.npmjs.com/package/@smithy/middleware-endpoint) (version 3.0.3) +### [@smithy/middleware-endpoint](https://www.npmjs.com/package/@smithy/middleware-endpoint) (version 3.0.5) License tags: Apache-2.0 @@ -10935,9 +10934,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/middleware-retry](https://www.npmjs.com/package/@smithy/middleware-retry) (version 3.0.6) +### [@smithy/middleware-retry](https://www.npmjs.com/package/@smithy/middleware-retry) (version 3.0.9) License tags: Apache-2.0 @@ -11147,9 +11146,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/middleware-serde](https://www.npmjs.com/package/@smithy/middleware-serde) (version 3.0.2) +### [@smithy/middleware-serde](https://www.npmjs.com/package/@smithy/middleware-serde) (version 3.0.3) License tags: Apache-2.0 @@ -11359,9 +11358,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/middleware-stack](https://www.npmjs.com/package/@smithy/middleware-stack) (version 3.0.2) +### [@smithy/middleware-stack](https://www.npmjs.com/package/@smithy/middleware-stack) (version 3.0.3) License tags: Apache-2.0 @@ -11571,9 +11570,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/node-config-provider](https://www.npmjs.com/package/@smithy/node-config-provider) (version 3.1.2) +### [@smithy/node-config-provider](https://www.npmjs.com/package/@smithy/node-config-provider) (version 3.1.4) License tags: Apache-2.0 @@ -11783,9 +11782,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/node-http-handler](https://www.npmjs.com/package/@smithy/node-http-handler) (version 3.1.0) +### [@smithy/node-http-handler](https://www.npmjs.com/package/@smithy/node-http-handler) (version 3.1.2) License tags: Apache-2.0 @@ -11995,9 +11994,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/property-provider](https://www.npmjs.com/package/@smithy/property-provider) (version 3.1.2) +### [@smithy/property-provider](https://www.npmjs.com/package/@smithy/property-provider) (version 3.1.3) License tags: Apache-2.0 @@ -12207,9 +12206,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/protocol-http](https://www.npmjs.com/package/@smithy/protocol-http) (version 4.0.2) +### [@smithy/protocol-http](https://www.npmjs.com/package/@smithy/protocol-http) (version 4.0.3) License tags: Apache-2.0 @@ -12419,9 +12418,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/querystring-builder](https://www.npmjs.com/package/@smithy/querystring-builder) (version 3.0.2) +### [@smithy/querystring-builder](https://www.npmjs.com/package/@smithy/querystring-builder) (version 3.0.3) License tags: Apache-2.0 @@ -12631,9 +12630,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/querystring-parser](https://www.npmjs.com/package/@smithy/querystring-parser) (version 3.0.2) +### [@smithy/querystring-parser](https://www.npmjs.com/package/@smithy/querystring-parser) (version 3.0.3) License tags: Apache-2.0 @@ -12843,9 +12842,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/service-error-classification](https://www.npmjs.com/package/@smithy/service-error-classification) (version 3.0.2) +### [@smithy/service-error-classification](https://www.npmjs.com/package/@smithy/service-error-classification) (version 3.0.3) License tags: Apache-2.0 @@ -13055,9 +13054,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/shared-ini-file-loader](https://www.npmjs.com/package/@smithy/shared-ini-file-loader) (version 3.1.2) +### [@smithy/shared-ini-file-loader](https://www.npmjs.com/package/@smithy/shared-ini-file-loader) (version 3.1.4) License tags: Apache-2.0 @@ -13267,9 +13266,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/signature-v4](https://www.npmjs.com/package/@smithy/signature-v4) (version 3.1.1) +### [@smithy/signature-v4](https://www.npmjs.com/package/@smithy/signature-v4) (version 3.1.2) License tags: Apache-2.0 @@ -13479,9 +13478,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/smithy-client](https://www.npmjs.com/package/@smithy/smithy-client) (version 3.1.4) +### [@smithy/smithy-client](https://www.npmjs.com/package/@smithy/smithy-client) (version 3.1.7) License tags: Apache-2.0 @@ -13691,9 +13690,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/types](https://www.npmjs.com/package/@smithy/types) (version 3.2.0) +### [@smithy/types](https://www.npmjs.com/package/@smithy/types) (version 3.3.0) License tags: Apache-2.0 @@ -13903,9 +13902,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/url-parser](https://www.npmjs.com/package/@smithy/url-parser) (version 3.0.2) +### [@smithy/url-parser](https://www.npmjs.com/package/@smithy/url-parser) (version 3.0.3) License tags: Apache-2.0 @@ -14963,9 +14962,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/util-defaults-mode-node](https://www.npmjs.com/package/@smithy/util-defaults-mode-node) (version 3.0.6) +### [@smithy/util-defaults-mode-node](https://www.npmjs.com/package/@smithy/util-defaults-mode-node) (version 3.0.9) License tags: Apache-2.0 @@ -15175,9 +15174,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/util-endpoints](https://www.npmjs.com/package/@smithy/util-endpoints) (version 2.0.3) +### [@smithy/util-endpoints](https://www.npmjs.com/package/@smithy/util-endpoints) (version 2.0.5) License tags: Apache-2.0 @@ -15599,9 +15598,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/util-middleware](https://www.npmjs.com/package/@smithy/util-middleware) (version 3.0.2) +### [@smithy/util-middleware](https://www.npmjs.com/package/@smithy/util-middleware) (version 3.0.3) License tags: Apache-2.0 @@ -15811,9 +15810,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/util-retry](https://www.npmjs.com/package/@smithy/util-retry) (version 3.0.2) +### [@smithy/util-retry](https://www.npmjs.com/package/@smithy/util-retry) (version 3.0.3) License tags: Apache-2.0 @@ -16023,9 +16022,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [@smithy/util-stream](https://www.npmjs.com/package/@smithy/util-stream) (version 3.0.4) +### [@smithy/util-stream](https://www.npmjs.com/package/@smithy/util-stream) (version 3.0.6) License tags: Apache-2.0 @@ -19555,12 +19554,6 @@ License files: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -### [ejson-shell-parser](https://www.npmjs.com/package/ejson-shell-parser) (version 2.0.1) - -License tags: MIT - ### [electron-dl](https://www.npmjs.com/package/electron-dl) (version 3.5.0) @@ -19793,9 +19786,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [electron](https://www.npmjs.com/package/electron) (version 29.4.3) +### [electron](https://www.npmjs.com/package/electron) (version 29.4.5) License tags: MIT @@ -27383,9 +27376,9 @@ License files: 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. - + -### [mongodb-query-parser](https://www.npmjs.com/package/mongodb-query-parser) (version 4.1.2) +### [mongodb-query-parser](https://www.npmjs.com/package/mongodb-query-parser) (version 4.2.0) License tags: Apache-2.0 @@ -27595,9 +27588,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [mongodb-redact](https://www.npmjs.com/package/mongodb-redact) (version 0.2.3) +### [mongodb-redact](https://www.npmjs.com/package/mongodb-redact) (version 1.1.1) License tags: Apache-2.0 @@ -36652,9 +36645,9 @@ License files: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - + -### [semver](https://www.npmjs.com/package/semver) (version 7.6.2) +### [semver](https://www.npmjs.com/package/semver) (version 7.6.3) License tags: ISC @@ -37875,9 +37868,9 @@ License files: 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. - + -### [system-ca](https://www.npmjs.com/package/system-ca) (version 1.0.3) +### [system-ca](https://www.npmjs.com/package/system-ca) (version 2.0.0) License tags: Apache-2.0 diff --git a/configs/eslint-config-compass/index.js b/configs/eslint-config-compass/index.js index 3ea4a6bb8ae..2e6adc138ed 100644 --- a/configs/eslint-config-compass/index.js +++ b/configs/eslint-config-compass/index.js @@ -30,6 +30,12 @@ const tsOverrides = { const tsxRules = { ...common.tsxRules, ...extraTsRules, + 'react-hooks/exhaustive-deps': [ + 'warn', + { + additionalHooks: 'useTrackOnChange', + }, + ], }; const tsxOverrides = { diff --git a/configs/eslint-config-compass/package.json b/configs/eslint-config-compass/package.json index ae6cfe03d7c..1d7c507a261 100644 --- a/configs/eslint-config-compass/package.json +++ b/configs/eslint-config-compass/package.json @@ -1,6 +1,6 @@ { "name": "@mongodb-js/eslint-config-compass", - "version": "1.1.2", + "version": "1.1.3", "description": "Shared Compass eslint configuration", "license": "SSPL", "main": "index.js", diff --git a/configs/webpack-config-compass/package.json b/configs/webpack-config-compass/package.json index 710dd4cea06..d155deab5f7 100644 --- a/configs/webpack-config-compass/package.json +++ b/configs/webpack-config-compass/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.3.11", + "version": "1.3.13", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -45,7 +45,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/cli-progress": "^3.9.2", @@ -69,13 +69,14 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", "babel-loader": "^8.2.5", "babel-plugin-istanbul": "^5.2.0", - "browserslist": "^4.23.1", + "browserslist": "^4.23.2", "chalk": "^4.1.2", "cli-progress": "^3.9.1", "core-js": "^3.17.3", "css-loader": "^4.3.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "html-webpack-plugin": "^5.3.2", + "less": "^3.13.1", "less-loader": "^10.0.1", "mini-css-extract-plugin": "^2.3.0", "node-loader": "^2.0.0", diff --git a/package-lock.json b/package-lock.json index 48198b0bb13..8ee50e5dc83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,13 +25,13 @@ "node-gyp": "^8.4.1" }, "engines": { - "node": ">=16.15.1", - "npm": ">=8.19.4" + "node": ">=18.19.1", + "npm": ">=10.2.4" } }, "configs/eslint-config-compass": { "name": "@mongodb-js/eslint-config-compass", - "version": "1.1.2", + "version": "1.1.3", "license": "SSPL", "dependencies": { "@babel/core": "^7.21.4", @@ -170,7 +170,7 @@ }, "configs/webpack-config-compass": { "name": "@mongodb-js/webpack-config-compass", - "version": "1.3.11", + "version": "1.3.13", "license": "SSPL", "dependencies": { "@babel/core": "^7.21.4", @@ -184,13 +184,14 @@ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", "babel-loader": "^8.2.5", "babel-plugin-istanbul": "^5.2.0", - "browserslist": "^4.23.1", + "browserslist": "^4.23.2", "chalk": "^4.1.2", "cli-progress": "^3.9.1", "core-js": "^3.17.3", "css-loader": "^4.3.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "html-webpack-plugin": "^5.3.2", + "less": "^3.13.1", "less-loader": "^10.0.1", "mini-css-extract-plugin": "^2.3.0", "node-loader": "^2.0.0", @@ -210,7 +211,7 @@ "webpack-compass": "bin/webpack.js" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/cli-progress": "^3.9.2", @@ -306,6 +307,56 @@ "url": "https://opencollective.com/webpack" } }, + "configs/webpack-config-compass/node_modules/browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "configs/webpack-config-compass/node_modules/caniuse-lite": { + "version": "1.0.30001641", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", + "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, "configs/webpack-config-compass/node_modules/connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -325,6 +376,11 @@ "node": ">= 10" } }, + "configs/webpack-config-compass/node_modules/electron-to-chromium": { + "version": "1.4.823", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.823.tgz", + "integrity": "sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==" + }, "configs/webpack-config-compass/node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -559,6 +615,35 @@ "webpack": "^5.0.0" } }, + "configs/webpack-config-compass/node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "configs/webpack-config-compass/node_modules/webpack-dev-middleware": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", @@ -893,49 +978,49 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.600.0.tgz", - "integrity": "sha512-8dYsnDLiD0rjujRiZZl0E57heUkHqMSFZHBi0YMs57SM8ODPxK3tahwDYZtS7bqanvFKZwGy+o9jIcij7jBOlA==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.614.0.tgz", + "integrity": "sha512-nydN0TVIMkYhYcCABkCcllmhLakzD4aN8r6ROWWG83+XFtBGgnvY2cxj2uFx+Vp7THAVnG2r6GVGKzEwvAH3pA==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.600.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/client-sso-oidc": "3.614.0", + "@aws-sdk/client-sts": "3.614.0", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -949,46 +1034,46 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/client-sso": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.598.0.tgz", - "integrity": "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.614.0.tgz", + "integrity": "sha512-p5pyYaxRzBttjBkqfc8i3K7DzBdTg3ECdVgBo6INIUxfvDy0J8QUE8vNtCgvFIkq+uPw/8M+Eo4zzln7anuO0Q==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -997,53 +1082,55 @@ } }, "node_modules/@aws-sdk/client-sso-oidc": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.600.0.tgz", - "integrity": "sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.614.0.tgz", + "integrity": "sha512-BI1NWcpppbHg/28zbUg54dZeckork8BItZIcjls12vxasy+p3iEzrJVG60jcbUTTsk3Qc1tyxNfrdcVqx0y7Ww==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-sts": "^3.614.0" } }, "node_modules/@aws-sdk/client-sso-oidc/node_modules/tslib": { @@ -1057,48 +1144,48 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/client-sts": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.600.0.tgz", - "integrity": "sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.614.0.tgz", + "integrity": "sha512-i6QmaVA1KHHYNnI2VYQy/sc31rLm4+jSp8b/YbQpFnD0w3aXsrEEHHlxek45uSkHb4Nrj1omFBVy/xp1WVYx2Q==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/client-sso-oidc": "3.614.0", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -1112,15 +1199,15 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/core": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.598.0.tgz", - "integrity": "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g==", - "dependencies": { - "@smithy/core": "^2.2.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/signature-v4": "^3.1.0", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.614.0.tgz", + "integrity": "sha512-BUuS5/1YkgmKc4J0bg83XEtMyDHVyqG2QDzfmhYe8gbOIZabUl1FlrFVwhCAthtrrI6MPGTQcERB4BtJKUSplw==", + "dependencies": { + "@smithy/core": "^2.2.6", + "@smithy/protocol-http": "^4.0.3", + "@smithy/signature-v4": "^3.1.2", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", "fast-xml-parser": "4.2.5", "tslib": "^2.6.2" }, @@ -1134,14 +1221,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.600.0.tgz", - "integrity": "sha512-AIM+B06d1+71EuBrk2UR9ZZgRS3a+ARxE3oZKMZYlfqtZ3kY8w4DkhEt7OVruc6uSsMhkrcQT6nxsOxFSi4RtA==", - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.600.0", - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.614.0.tgz", + "integrity": "sha512-Y89x4RKUlggxtCU07OhQRhvsiBBOzt0ep7OyxnnkhgPrbmY+N4tfMk3sEo02sxetqTuirLz4hRbfxwlsM5scpw==", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1154,13 +1241,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.598.0.tgz", - "integrity": "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.609.0.tgz", + "integrity": "sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1173,18 +1260,18 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.598.0.tgz", - "integrity": "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/util-stream": "^3.0.2", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.614.0.tgz", + "integrity": "sha512-YIEjlNUKb3Vo/iTnGAPdsiDC3FUUnNoex2OwU8LmR7AkYZiWdB8nx99DfgkkY+OFMUpw7nKD2PCOtuFONelfGA==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/property-provider": "^3.1.3", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -1197,27 +1284,27 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.598.0.tgz", - "integrity": "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.614.0.tgz", + "integrity": "sha512-KfLuLFGwlvFSZ2MuzYwWGPb1y5TeiwX5okIDe0aQ1h10oD3924FXbN+mabOnUHQ8EFcGAtCaWbrC86mI7ktC6A==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.609.0", + "@aws-sdk/credential-provider-http": "3.614.0", + "@aws-sdk/credential-provider-process": "3.614.0", + "@aws-sdk/credential-provider-sso": "3.614.0", + "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.598.0" + "@aws-sdk/client-sts": "^3.614.0" } }, "node_modules/@aws-sdk/credential-provider-ini/node_modules/tslib": { @@ -1226,21 +1313,21 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.600.0.tgz", - "integrity": "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw==", - "dependencies": { - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-ini": "3.598.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.614.0.tgz", + "integrity": "sha512-4J6gPEuFZP0mkWq5E//oMS1vrmMM88iNNcv7TEljYnsc6JTAlKejCyFwx6CN+nkIhmIZsl06SXIhBemzBdBPfg==", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.609.0", + "@aws-sdk/credential-provider-http": "3.614.0", + "@aws-sdk/credential-provider-ini": "3.614.0", + "@aws-sdk/credential-provider-process": "3.614.0", + "@aws-sdk/credential-provider-sso": "3.614.0", + "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1253,14 +1340,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.598.0.tgz", - "integrity": "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.614.0.tgz", + "integrity": "sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1273,16 +1360,16 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.598.0.tgz", - "integrity": "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA==", - "dependencies": { - "@aws-sdk/client-sso": "3.598.0", - "@aws-sdk/token-providers": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.614.0.tgz", + "integrity": "sha512-55+gp0JY4451cWI1qXmVMFM0GQaBKiQpXv2P0xmd9P3qLDyeFUSEW8XPh0d2lb1ICr6x4s47ynXVdGCIv2mXMg==", + "dependencies": { + "@aws-sdk/client-sso": "3.614.0", + "@aws-sdk/token-providers": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1295,20 +1382,20 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.598.0.tgz", - "integrity": "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.609.0.tgz", + "integrity": "sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sts": "^3.598.0" + "@aws-sdk/client-sts": "^3.609.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/tslib": { @@ -1317,25 +1404,25 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.600.0.tgz", - "integrity": "sha512-cC9uqmX0rgx1efiJGqeR+i0EXr8RQ5SAzH7M45WNBZpYiLEe6reWgIYJY9hmOxuaoMdWSi8kekuN3IjTIORRjw==", - "dependencies": { - "@aws-sdk/client-cognito-identity": "3.600.0", - "@aws-sdk/client-sso": "3.598.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/credential-provider-cognito-identity": "3.600.0", - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-ini": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.614.0.tgz", + "integrity": "sha512-mgb6bcLiOig9ZWxuAF4g0QwLGuqSleYFAyPWyWo30XafCAGB2MfCwxksVWRH+cuX86fCnAF8XgYnaSs38fBOXA==", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.614.0", + "@aws-sdk/client-sso": "3.614.0", + "@aws-sdk/client-sts": "3.614.0", + "@aws-sdk/credential-provider-cognito-identity": "3.614.0", + "@aws-sdk/credential-provider-env": "3.609.0", + "@aws-sdk/credential-provider-http": "3.614.0", + "@aws-sdk/credential-provider-ini": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/credential-provider-process": "3.614.0", + "@aws-sdk/credential-provider-sso": "3.614.0", + "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1348,13 +1435,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.598.0.tgz", - "integrity": "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.609.0.tgz", + "integrity": "sha512-iTKfo158lc4jLDfYeZmYMIBHsn8m6zX+XB6birCSNZ/rrlzAkPbGE43CNdKfvjyWdqgLMRXF+B+OcZRvqhMXPQ==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1367,12 +1454,12 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.598.0.tgz", - "integrity": "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", + "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1385,13 +1472,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.598.0.tgz", - "integrity": "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.609.0.tgz", + "integrity": "sha512-6sewsYB7/o/nbUfA99Aa/LokM+a/u4Wpm/X2o0RxOsDtSB795ObebLJe2BxY5UssbGaWkn7LswyfvrdZNXNj1w==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1404,14 +1491,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.598.0.tgz", - "integrity": "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.614.0.tgz", + "integrity": "sha512-xUxh0UPQiMTG6E31Yvu6zVYlikrIcFDKljM11CaatInzvZubGTGiX0DjpqRlfGzUNsuPc/zNrKwRP2+wypgqIw==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1424,15 +1511,15 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.598.0.tgz", - "integrity": "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", + "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.1", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "engines": { @@ -1445,21 +1532,21 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/token-providers": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.598.0.tgz", - "integrity": "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA==", - "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", + "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", + "dependencies": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { "node": ">=16.0.0" }, "peerDependencies": { - "@aws-sdk/client-sso-oidc": "^3.598.0" + "@aws-sdk/client-sso-oidc": "^3.614.0" } }, "node_modules/@aws-sdk/token-providers/node_modules/tslib": { @@ -1468,11 +1555,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/types": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.598.0.tgz", - "integrity": "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", + "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", "dependencies": { - "@smithy/types": "^3.1.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -1485,13 +1572,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/util-endpoints": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.598.0.tgz", - "integrity": "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", + "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "@smithy/util-endpoints": "^2.0.2", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "@smithy/util-endpoints": "^2.0.5", "tslib": "^2.6.2" }, "engines": { @@ -1520,12 +1607,12 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.598.0.tgz", - "integrity": "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", + "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } @@ -1536,13 +1623,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.598.0.tgz", - "integrity": "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", + "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", "dependencies": { - "@aws-sdk/types": "3.598.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -7459,15 +7546,15 @@ "link": true }, "node_modules/@mongodb-js/devtools-connect": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.0.1.tgz", - "integrity": "sha512-xbk/eGHPQTQz4VSpGb5oRqSSbzipcFDODrAc4YtYFrb0980buOAopO71NozCbQoVnoiO1pYVIqcnrZMHkdaJzg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.0.2.tgz", + "integrity": "sha512-wBxbMQ4Ny2V1lCI/Or4e0NUpTX4E2DkEEkehzs3c2MF9uDtf9iWZm5edDjY4A9WhCD4GQ15UlGAQBf+wBN/TLQ==", "dependencies": { "@mongodb-js/oidc-http-server-pages": "1.1.1", "lodash.merge": "^4.6.2", "mongodb-connection-string-url": "^3.0.0", "socks": "^2.7.3", - "system-ca": "^1.0.2" + "system-ca": "^2.0.0" }, "optionalDependencies": { "kerberos": "^2.1.0", @@ -7793,9 +7880,9 @@ } }, "node_modules/@mongodb-js/mongodb-constants": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-constants/-/mongodb-constants-0.10.1.tgz", - "integrity": "sha512-zs6LSjci2JwkEgc43nmwI4LM0fYRnJpID2tw1NJ2IlqpmW9x1dQFjv1IG401yPr+eoB+Ktzy+EezDrTKl1fMbA==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-constants/-/mongodb-constants-0.10.2.tgz", + "integrity": "sha512-ss0c6IxhSJZwDiY18We3vjFwrCL+1HJntMInFSthJ6oM61yiCCz5m8TfUjNGJQCXhPqok7sM9RSRcKrn43u0cg==", "dependencies": { "semver": "^7.5.4" } @@ -8365,6 +8452,17 @@ "node": ">=8" } }, + "node_modules/@mongodb-js/shell-bson-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/shell-bson-parser/-/shell-bson-parser-1.1.0.tgz", + "integrity": "sha512-zcTFBRrAiKLOhc2MJSmzAB5FlqN0kL5bXi1ehTg1MXvCT61lvWssiK7EWvwPd3mIUTI9NSjEfdDessS8dMxA1w==", + "dependencies": { + "acorn": "^8.1.0" + }, + "peerDependencies": { + "bson": "^4.6.3 || ^5 || ^6" + } + }, "node_modules/@mongodb-js/signing-utils": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@mongodb-js/signing-utils/-/signing-utils-0.3.1.tgz", @@ -8396,12 +8494,12 @@ "link": true }, "node_modules/@mongosh/arg-parser": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/arg-parser/-/arg-parser-2.2.10.tgz", - "integrity": "sha512-QvXziAmACrFty7id5I0s3ZOetIc1wWhjtpytGMtchEiusTQOO+NJy74UMrxK+NGxKPDRL0MroRIo05/LEfPkJg==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/arg-parser/-/arg-parser-2.2.12.tgz", + "integrity": "sha512-JayM6b5QnSMopt484MMD3u9uPtjNLlmTNlkbBSYxtTYpvom2WHGdrHmb1dQ50cPZ6sidH5aQ25MlzyYxcaopxQ==", "dependencies": { - "@mongosh/errors": "2.2.10", - "@mongosh/i18n": "2.2.10", + "@mongosh/errors": "2.2.12", + "@mongosh/i18n": "2.2.12", "mongodb-connection-string-url": "^3.0.1" }, "engines": { @@ -8409,9 +8507,9 @@ } }, "node_modules/@mongosh/async-rewriter2": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/async-rewriter2/-/async-rewriter2-2.2.10.tgz", - "integrity": "sha512-ssY+WxY/oOHPZAIjrYzUYhCr1K2towzshxQpYw3nk5JyjTdvN4gc0xnrWMNLJonEOD/ADTdlneFshQhuh/V1vQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/async-rewriter2/-/async-rewriter2-2.2.12.tgz", + "integrity": "sha512-BNZYYpfLiiX+Z+9Svf0OtxuW6lHCvdn4rjSZkdOgUQMYI93I897aW3HmDRhde5yMF/QMaT7STBjmBvC2TXAkCQ==", "dependencies": { "@babel/core": "^7.22.8", "@babel/plugin-transform-destructuring": "^7.22.5", @@ -8480,12 +8578,12 @@ } }, "node_modules/@mongosh/autocomplete": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/autocomplete/-/autocomplete-2.2.10.tgz", - "integrity": "sha512-iLrZ1vfA67jKwEWtSKGYAZ7QM5beYFo4AsmiV+KCXwtcZref3dX1OgcjBvRW8dRvSonz8/7RnN9r8QtsTyw2xw==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/autocomplete/-/autocomplete-2.2.12.tgz", + "integrity": "sha512-LFB4eFN2jH9q6ZAN3kt3ZdKjLBNJ8dqgagKV3IDM6gc9bQRxaI53MUWDxwUqA0xLFLLe7nchjmlQqOgo6nvH1g==", "dependencies": { "@mongodb-js/mongodb-constants": "^0.10.1", - "@mongosh/shell-api": "2.2.10", + "@mongosh/shell-api": "2.2.12", "semver": "^7.5.4" }, "engines": { @@ -8493,16 +8591,16 @@ } }, "node_modules/@mongosh/browser-repl": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/browser-repl/-/browser-repl-2.2.10.tgz", - "integrity": "sha512-h5Kf806rarRxb5nN1unUlzQG73bAU/jJeG/DC13MQ4YeFipcN0b4KOKXbNUkRK2zgyFjlOyf9TBTUiK0sUDYOQ==", - "dependencies": { - "@mongosh/browser-runtime-core": "2.2.10", - "@mongosh/errors": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/i18n": "2.2.10", - "@mongosh/node-runtime-worker-thread": "2.2.10", - "@mongosh/service-provider-core": "2.2.10", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/browser-repl/-/browser-repl-2.2.12.tgz", + "integrity": "sha512-8AMA0mZvdeWjqBkUrwbd30nbKlyMT7KPElv8JzkcaCr+G0SsqGU8vi/TeoMA1MnxPQT5sloPOjOm8AfJAna4Og==", + "dependencies": { + "@mongosh/browser-runtime-core": "2.2.12", + "@mongosh/errors": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/i18n": "2.2.12", + "@mongosh/node-runtime-worker-thread": "2.2.12", + "@mongosh/service-provider-core": "2.2.12", "numeral": "^2.0.6", "text-table": "^0.2.0" }, @@ -8526,85 +8624,85 @@ } }, "node_modules/@mongosh/browser-runtime-core": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/browser-runtime-core/-/browser-runtime-core-2.2.10.tgz", - "integrity": "sha512-tN2TwbA/ANuZllWBQaZPYKjGS4M+F8UbPkHS7b08DeixbJB457Dh2HNDXztmADuLPht82DurRxx6nS0suNFNXQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/browser-runtime-core/-/browser-runtime-core-2.2.12.tgz", + "integrity": "sha512-sBqFKyU37FIf+TSyLCPKfRYEE1RmBNbxyDii4Wa3vlA2CHR3PZwagpenf8LwIUp7iYiyd34f+mvfxAHouW/MNg==", "dependencies": { - "@mongosh/autocomplete": "2.2.10", - "@mongosh/service-provider-core": "2.2.10", - "@mongosh/shell-api": "2.2.10", - "@mongosh/shell-evaluator": "2.2.10" + "@mongosh/autocomplete": "2.2.12", + "@mongosh/service-provider-core": "2.2.12", + "@mongosh/shell-api": "2.2.12", + "@mongosh/shell-evaluator": "2.2.12" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/errors": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/errors/-/errors-2.2.10.tgz", - "integrity": "sha512-jR8dv9MYYRwr+Yri/KI6HAuob0zdVBQOrMvjc+ygBbTIkL3wh1iOrjZKZuYUsjei1FDxLA8NywftAoHDchq2Tg==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/errors/-/errors-2.2.12.tgz", + "integrity": "sha512-7Ns3xOFXhQil99wmU5HAC+GzJljzWV1X5a5khdCU/xq2oRKNJc92JGJMRfG6MK8YXB8rhkjYBoqssPdBaeE5gA==", "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/history": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/history/-/history-2.2.10.tgz", - "integrity": "sha512-EmMKvsytTXq/1tAwxZUvl+6+gCrarWdEDB9mO9vTCFneOgB0ao2jpo7KA9Jc63r8RYhDH78dtjFsSuFeox3AiA==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/history/-/history-2.2.12.tgz", + "integrity": "sha512-JcNSwB/HnVK2RJRJY3MwtTNuWA9aeXWY5mc+wNYYIQ77dXtrphXpIxzSaLL0EXMrQZQBeCibxoYzBFZx4n2jFg==", "dependencies": { "mongodb-connection-string-url": "^3.0.1", - "mongodb-redact": "^0.2.3" + "mongodb-redact": "^1.1.0" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/i18n": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/i18n/-/i18n-2.2.10.tgz", - "integrity": "sha512-TxyFOhdXqCN0AXGcWziPzZ+YBf8KthnZIbOVSyA+C1a0jynfMf+XBnLnNpwvKfGZUeQ1VyZkrKLPopG7e2nuIA==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/i18n/-/i18n-2.2.12.tgz", + "integrity": "sha512-2A59O56WG/fwtNs0VjS/tvsen0MKXSHCSn9w51PGbdLYFCD8RQUetPSSfLcEuqlsXn88NDFsiQbkSsRo4sEMXw==", "dependencies": { - "@mongosh/errors": "2.2.10" + "@mongosh/errors": "2.2.12" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/logging": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/logging/-/logging-2.2.10.tgz", - "integrity": "sha512-0z3L23rtaASh1E2hV/wSWxDTycxktbD2XVUnSW1YbyRfePd7YOwVeUhNeFYUf1Qq2q2KeTdxgMaP5/BodY+h5A==", - "dependencies": { - "@mongodb-js/devtools-connect": "^3.0.1", - "@mongosh/errors": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/types": "2.2.10", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/logging/-/logging-2.2.12.tgz", + "integrity": "sha512-fSBO0dLfzRQ0ZtflKqWwDLLWn6t7ZYjUBCsDIpTVhvJlexvZQ/71izD3yEN4k2MRZyTFiTM5lYGURSqTldppNA==", + "dependencies": { + "@mongodb-js/devtools-connect": "^3.0.2", + "@mongosh/errors": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/types": "2.2.12", "mongodb-log-writer": "^1.4.2", - "mongodb-redact": "^0.2.3" + "mongodb-redact": "^1.1.0" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/node-runtime-worker-thread": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/node-runtime-worker-thread/-/node-runtime-worker-thread-2.2.10.tgz", - "integrity": "sha512-u1S455FA5/wLw2/Izfmpaw7XOsDYmXe0BYolEAHHiuEt1wTQ6A7b9qs8rjwA/yXN15SbL7BMYHnv4fLVQhEO7w==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/node-runtime-worker-thread/-/node-runtime-worker-thread-2.2.12.tgz", + "integrity": "sha512-hqaW/1MziELPFcJJEQnXblHa6ueI6kbGUju/tbYkaY8x+vJVic2Fobd71Mx66awJwIuI7zmjOq0HE6UkKdZ2jw==", "dependencies": { "interruptor": "^1.0.1", - "system-ca": "^1.0.3" + "system-ca": "^2.0.0" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/service-provider-core": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/service-provider-core/-/service-provider-core-2.2.10.tgz", - "integrity": "sha512-XB+G24WjTIYXnHoToJhDJMwMV7pCcgCwgme0MiE6lzcYs5HwlHhk9tzBwv0+i+3NcCb5SMqU38iUMuGG6jKJdQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/service-provider-core/-/service-provider-core-2.2.12.tgz", + "integrity": "sha512-pYd2KKlNFn/6fn9w5vSlkFUUkKoK8F+UAhy8TqjfYBA9cSQKLD+Et5qClC09APIAcVyk0Xd66n7KHG0Qb0vaxA==", "dependencies": { "@aws-sdk/credential-providers": "^3.525.0", - "@mongosh/errors": "2.2.10", + "@mongosh/errors": "2.2.12", "bson": "^6.7.0", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2" @@ -8617,40 +8715,40 @@ } }, "node_modules/@mongosh/shell-api": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/shell-api/-/shell-api-2.2.10.tgz", - "integrity": "sha512-Cgcb0U5wqzmTmwAmMkSqhZ3fR4PjqNJ2px61i/9JzWAgIEDSbv9Xni3mcfDRQd/qjLHCEUlAPFgEBu7Cpk0qBQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/shell-api/-/shell-api-2.2.12.tgz", + "integrity": "sha512-sjy6di7W5h0MbQ4lPXYOModwSnebiwWYDJVv6wtj9TvCz8Bua19fIr9jnW4GTjA/MLaWO0DjYh6MFg34SqvoLQ==", "dependencies": { - "@mongosh/arg-parser": "2.2.10", - "@mongosh/errors": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/i18n": "2.2.10", - "@mongosh/service-provider-core": "2.2.10", - "mongodb-redact": "^0.2.3" + "@mongosh/arg-parser": "2.2.12", + "@mongosh/errors": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/i18n": "2.2.12", + "@mongosh/service-provider-core": "2.2.12", + "mongodb-redact": "^1.1.0" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/shell-evaluator": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/shell-evaluator/-/shell-evaluator-2.2.10.tgz", - "integrity": "sha512-9v/p5WDu+Ur7+jhXajkBOvpINcRORA1UpdMOV4sBGQ623VbmoDd7xFeFPoi0uWzV50qW5yNRlh3+dvsG/jdKmQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/shell-evaluator/-/shell-evaluator-2.2.12.tgz", + "integrity": "sha512-oSxx996l1vumeBDNZ2XYOWSmbPKA5b1XLL9YEFpsS27WLnxwvBiAb2qu6pJ8fDmJh9nDDAkWP5jlf2zYBitByA==", "dependencies": { - "@mongosh/async-rewriter2": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/shell-api": "2.2.10" + "@mongosh/async-rewriter2": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/shell-api": "2.2.12" }, "engines": { "node": ">=14.15.1" } }, "node_modules/@mongosh/types": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/types/-/types-2.2.10.tgz", - "integrity": "sha512-BfCcmbC3givNCgYZxf6aUJy+/nHg2By6Hs9gZ/WMGgiedMuL5fRE18dGlwy3Aog7Jc6tVkBCMtOpYgjVnUPoxQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/types/-/types-2.2.12.tgz", + "integrity": "sha512-19LPOUVDy1FE01U6CvOjplv5U8prY0RZa3Cf0QSTpHQlnzWcrzMIHqPWS3luXFwGSKhQU/GxFfEJesqdE8C7HQ==", "dependencies": { - "@mongodb-js/devtools-connect": "^3.0.1" + "@mongodb-js/devtools-connect": "^3.0.2" }, "engines": { "node": ">=14.15.1" @@ -11890,11 +11988,11 @@ "dev": true }, "node_modules/@smithy/abort-controller": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.0.tgz", - "integrity": "sha512-XOm4LkuC0PsK1sf2bBJLIlskn5ghmVxiEBVlo/jg0R8hxASBKYYgOoJEhKWgOr4vWGkN+5rC+oyBAqHYtxjnwQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", + "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -11907,14 +12005,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/config-resolver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.3.tgz", - "integrity": "sha512-4wHqCMkdfVDP4qmr4fVPYOFOH+vKhOv3X4e6KEU9wIC8xXUQ24tnF4CW+sddGDX1zU86GGyQ7A+rg2xmUD6jpQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", + "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/types": "^3.2.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.2", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "engines": { @@ -11927,17 +12025,17 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/core": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.3.tgz", - "integrity": "sha512-SpyLOL2vgE6sUYM6nQfu82OirCPkCDKctyG3aMgjMlDPTJpUlmlNH0ttu9ZWwzEjrzzr8uABmPjJTRI7gk1HFQ==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.0.3", - "@smithy/middleware-retry": "^3.0.6", - "@smithy/middleware-serde": "^3.0.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "@smithy/util-middleware": "^3.0.2", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.6.tgz", + "integrity": "sha512-tBbVIv/ui7/lLTKayYJJvi8JLVL2SwOQTbNFEOrvzSE3ktByvsa1erwBOnAMo8N5Vu30g7lN4lLStrU75oDGuw==", + "dependencies": { + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "engines": { @@ -11950,14 +12048,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/credential-provider-imds": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.2.tgz", - "integrity": "sha512-gqVmUaNoeqyrOAjgZg+rTmFLsphh/vS59LCMdFfVpthVS0jbfBzvBmEPktBd+y9ME4DYMGHFAMSYJDK8q0noOQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.4.tgz", + "integrity": "sha512-NKyH01m97Xa5xf3pB2QOF3lnuE8RIK0hTVNU5zvZAwZU8uspYO4DHQVlK+Y5gwSrujTfHvbfd1D9UFJAc0iYKQ==", "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/property-provider": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/url-parser": "^3.0.2", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "tslib": "^2.6.2" }, "engines": { @@ -11970,13 +12068,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/fetch-http-handler": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.1.0.tgz", - "integrity": "sha512-s7oQjEOUH9TYjctpITtWF4qxOdg7pBrP9eigEQ8SBsxF3dRFV0S28pGMllC83DUr7ECmErhO/BUwnULfoNhKgQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.1.tgz", + "integrity": "sha512-0w0bgUvZmfa0vHN8a+moByhCJT07WN6AHKEhFSOLsDpnszm+5dLVv5utGaqbhOrZ/aF5x3xuPMs/oMCd+4O5xg==", "dependencies": { - "@smithy/protocol-http": "^4.0.2", - "@smithy/querystring-builder": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" } @@ -11987,11 +12085,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/hash-node": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.2.tgz", - "integrity": "sha512-43uGA6o6QJQdXwAogybdTDHDd3SCdKyoiHIHb8PpdE2rKmVicjG9b1UgVwdgO8QPytmVqHFaUw27M3LZKwu8Yg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", + "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -12006,11 +12104,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/invalid-dependency": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.2.tgz", - "integrity": "sha512-+BAY3fMhomtq470tswXyrdVBSUhiLuhBVT+rOmpbz5e04YX+s1dX4NxTLzZGwBjCpeWZNtTxP8zbIvvFk81gUg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", + "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, @@ -12036,12 +12134,12 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/middleware-content-length": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.2.tgz", - "integrity": "sha512-/Havz3PkYIEmwpqkyRTR21yJsWnFbD1ec4H1pUL+TkDnE7RCQkAVUQepLL/UeCaZeCBXvfdoKbOjSbV01xIinQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.3.tgz", + "integrity": "sha512-Dbz2bzexReYIQDWMr+gZhpwBetNXzbhnEMhYKA6urqmojO14CsXjnsoPYO8UL/xxcawn8ZsuVU61ElkLSltIUQ==", "dependencies": { - "@smithy/protocol-http": "^4.0.2", - "@smithy/types": "^3.2.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12054,16 +12152,16 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/middleware-endpoint": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.3.tgz", - "integrity": "sha512-ARAXHodhj4tttKa9y75zvENdSoHq6VGsSi7XS3+yLutrnxttJs6N10UMInCC1yi3/bopT8xug3iOP/y9R6sKJQ==", - "dependencies": { - "@smithy/middleware-serde": "^3.0.2", - "@smithy/node-config-provider": "^3.1.2", - "@smithy/shared-ini-file-loader": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/url-parser": "^3.0.2", - "@smithy/util-middleware": "^3.0.2", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.5.tgz", + "integrity": "sha512-V4acqqrh5tDxUEGVTOgf2lYMZqPQsoGntCrjrJZEeBzEzDry2d2vcI1QCXhGltXPPY+BMc6eksZMguA9fIY8vA==", + "dependencies": { + "@smithy/middleware-serde": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "engines": { @@ -12076,17 +12174,17 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/middleware-retry": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.6.tgz", - "integrity": "sha512-ICsFKp8eAyIMmxN5UT3IU37S6886L879TKtgxPsn/VD/laYNwqTLmJaCAn5//+2fRIrV0dnHp6LFlMwdXlWoUQ==", - "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/service-error-classification": "^3.0.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "@smithy/util-middleware": "^3.0.2", - "@smithy/util-retry": "^3.0.2", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.9.tgz", + "integrity": "sha512-Mrv9omExU1gA7Y0VEJG2LieGfPYtwwcEiOnVGZ54a37NEMr66TJ0glFslOJFuKWG6izg5DpKIUmDV9rRxjm47Q==", + "dependencies": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.0.3", + "@smithy/service-error-classification": "^3.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -12112,11 +12210,11 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.2.tgz", - "integrity": "sha512-oT2abV5zLhBucJe1LIIFEcRgIBDbZpziuMPswTMbBQNcaEUycLFvX63zsFmqfwG+/ZQKsNx+BSE8W51CMuK7Yw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", + "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12129,11 +12227,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/middleware-stack": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.2.tgz", - "integrity": "sha512-6fRcxomlNKBPIy/YjcnC7YHpMAjRvGUYlYVJAfELqZjkW0vQegNcImjY7T1HgYA6u3pAcCxKVBLYnkTw8z/l0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", + "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12146,13 +12244,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/node-config-provider": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.2.tgz", - "integrity": "sha512-388fEAa7+6ORj/BDC70peg3fyFBTTXJyXfXJ0Bwd6FYsRltePr2oGzIcm5AuC1WUSLtZ/dF+hYOnfTMs04rLvA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", + "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", "dependencies": { - "@smithy/property-provider": "^3.1.2", - "@smithy/shared-ini-file-loader": "^3.1.2", - "@smithy/types": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12165,14 +12263,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/node-http-handler": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.0.tgz", - "integrity": "sha512-pOpgB6B+VLXLwAyyvRz+ZAVXABlbAsJ2xvn3WZvrppAPImxwQOPFbeSUzWYMhpC8Tr7yQ3R8fG990QDhskkf1Q==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.2.tgz", + "integrity": "sha512-Td3rUNI7qqtoSLTsJBtsyfoG4cF/XMFmJr6Z2dX8QNzIi6tIW6YmuyFml8mJ2cNpyWNqITKbROMOFrvQjmsOvw==", "dependencies": { - "@smithy/abort-controller": "^3.1.0", - "@smithy/protocol-http": "^4.0.2", - "@smithy/querystring-builder": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/abort-controller": "^3.1.1", + "@smithy/protocol-http": "^4.0.3", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12185,11 +12283,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/property-provider": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.2.tgz", - "integrity": "sha512-Hzp32BpeFFexBpO1z+ts8okbq/VLzJBadxanJAo/Wf2CmvXMBp6Q/TLWr7Js6IbMEcr0pDZ02V3u1XZkuQUJaA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", + "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12202,11 +12300,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/protocol-http": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.2.tgz", - "integrity": "sha512-X/90xNWIOqSR2tLUyWxVIBdatpm35DrL44rI/xoeBWUuanE0iyCXJpTcnqlOpnEzgcu0xCKE06+g70TTu2j7RQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.3.tgz", + "integrity": "sha512-x5jmrCWwQlx+Zv4jAtc33ijJ+vqqYN+c/ZkrnpvEe/uDas7AT7A/4Rc2CdfxgWv4WFGmEqODIrrUToPN6DDkGw==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12219,11 +12317,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/querystring-builder": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.2.tgz", - "integrity": "sha512-xhv1+HacDYsOLdNt7zW+8Fe779KYAzmWvzs9bC5NlKM8QGYCwwuFwDBynhlU4D5twgi2pZ14Lm4h6RiAazCtmA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" }, @@ -12237,11 +12335,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/querystring-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.2.tgz", - "integrity": "sha512-C5hyRKgrZGPNh5QqIWzXnW+LXVrPmVQO0iJKjHeb5v3C61ZkP9QhrKmbfchcTyg/VnaE0tMNf/nmLpQlWuiqpg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", + "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12254,22 +12352,22 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/service-error-classification": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.2.tgz", - "integrity": "sha512-cu0WV2XRttItsuXlcM0kq5MKdphbMMmSd2CXF122dJ75NrFE0o7rruXFGfxAp3BKzgF/DMxX+PllIA/cj4FHMw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", + "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", "dependencies": { - "@smithy/types": "^3.2.0" + "@smithy/types": "^3.3.0" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.2.tgz", - "integrity": "sha512-tgnXrXbLMO8vo6VeuqabMw/eTzQHlLmZx0TC0TjtjJghnD0Xl4pEnJtBjTJr6XF5fHMNrt5BcczDXHJT9yNQnA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", + "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12282,14 +12380,14 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/signature-v4": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.1.tgz", - "integrity": "sha512-2/vlG86Sr489XX8TA/F+VDA+P04ESef04pSz0wRtlQBExcSPjqO08rvrkcas2zLnJ51i+7ukOURCkgqixBYjSQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz", + "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==", "dependencies": { "@smithy/is-array-buffer": "^3.0.0", - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.2", + "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -12304,15 +12402,15 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/smithy-client": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.4.tgz", - "integrity": "sha512-y6xJROGrIoitjpwXLY7P9luDHvuT9jWpAluliuSFdBymFxcl6iyQjo9U/JhYfRHFNTruqsvKOrOESVuPGEcRmQ==", - "dependencies": { - "@smithy/middleware-endpoint": "^3.0.3", - "@smithy/middleware-stack": "^3.0.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/types": "^3.2.0", - "@smithy/util-stream": "^3.0.4", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.7.tgz", + "integrity": "sha512-nZbJZB0XI3YnaFBWGDBr7kjaew6O0oNYNmopyIz6gKZEbxzrtH7rwvU1GcVxcSFoOwWecLJEe79fxEMljHopFQ==", + "dependencies": { + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.0.6", "tslib": "^2.6.2" }, "engines": { @@ -12325,9 +12423,9 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/types": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.2.0.tgz", - "integrity": "sha512-cKyeKAPazZRVqm7QPvcPD2jEIt2wqDPAL1KJKb0f/5I7uhollvsWZuZKLclmyP6a+Jwmr3OV3t+X0pZUUHS9BA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "dependencies": { "tslib": "^2.6.2" }, @@ -12341,12 +12439,12 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/url-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.2.tgz", - "integrity": "sha512-pRiPHrgibeAr4avtXDoBHmTLtthwA4l8jKYRfZjNgp+bBPyxDMPRg2TMJaYxqbKemvrOkHu9MIBTv2RkdNfD6w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", + "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", "dependencies": { - "@smithy/querystring-parser": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/querystring-parser": "^3.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" } }, @@ -12436,13 +12534,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.6.tgz", - "integrity": "sha512-tAgoc++Eq+KL7g55+k108pn7nAob3GLWNEMbXhZIQyBcBNaE/o3+r4AEbae0A8bWvLRvArVsjeiuhMykGa04/A==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.9.tgz", + "integrity": "sha512-WKPcElz92MAQG09miBdb0GxEH/MwD5GfE8g07WokITq5g6J1ROQfYCKC1wNnkqAGfrSywT7L0rdvvqlBplqiyA==", "dependencies": { - "@smithy/property-provider": "^3.1.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -12456,16 +12554,16 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.6.tgz", - "integrity": "sha512-UNerul6/E8aiCyFTBHk+RSIZCo7m96d/N5K3FeO/wFeZP6oy5HAicLzxqa85Wjv7MkXSxSySX29L/LwTV/QMag==", - "dependencies": { - "@smithy/config-resolver": "^3.0.3", - "@smithy/credential-provider-imds": "^3.1.2", - "@smithy/node-config-provider": "^3.1.2", - "@smithy/property-provider": "^3.1.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.9.tgz", + "integrity": "sha512-dQLrUqFxqpf0GvEKEuFdgXcdZwz6oFm752h4d6C7lQz+RLddf761L2r7dSwGWzESMMB3wKj0jL+skRhEGlecjw==", + "dependencies": { + "@smithy/config-resolver": "^3.0.5", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12478,12 +12576,12 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/util-endpoints": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.3.tgz", - "integrity": "sha512-Dyi+pfLglDHSGsKSYunuUUSFM5V0tz7UDgv1Ex97yg+Xkn0Eb0rH0rcvl1n0MaJ11fac3HKDOH0DkALyQYCQag==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", + "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", "dependencies": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/types": "^3.2.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12512,11 +12610,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/util-middleware": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.2.tgz", - "integrity": "sha512-7WW5SD0XVrpfqljBYzS5rLR+EiDzl7wCVJZ9Lo6ChNFV4VYDk37Z1QI5w/LnYtU/QKnSawYoHRd7VjSyC8QRQQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", + "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", "dependencies": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12529,12 +12627,12 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/util-retry": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.2.tgz", - "integrity": "sha512-HUVOb1k8p/IH6WFUjsLa+L9H1Zi/FAAB2CDOpWuffI1b2Txi6sknau8kNfC46Xrt39P1j2KDzCE1UlLa2eW5+A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", + "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", "dependencies": { - "@smithy/service-error-classification": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/service-error-classification": "^3.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "engines": { @@ -12547,13 +12645,13 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@smithy/util-stream": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.4.tgz", - "integrity": "sha512-CcMioiaOOsEVdb09pS7ux1ij7QcQ2jE/cE1+iin1DXMeRgAEQN/47m7Xztu7KFQuQsj0A5YwB2UN45q97CqKCg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.6.tgz", + "integrity": "sha512-w9i//7egejAIvplX821rPWWgaiY1dxsQUw0hXX7qwa/uZ9U3zplqTQ871jWadkcVB9gFDhkPWYVZf4yfFbZ0xA==", "dependencies": { - "@smithy/fetch-http-handler": "^3.1.0", - "@smithy/node-http-handler": "^3.1.0", - "@smithy/types": "^3.2.0", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/types": "^3.3.0", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", @@ -18332,11 +18430,14 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "node_modules/copy-anything": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz", - "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "dependencies": { - "is-what": "^3.12.0" + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" } }, "node_modules/core-js": { @@ -20689,24 +20790,10 @@ "node": ">=0.10.0" } }, - "node_modules/ejson-shell-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ejson-shell-parser/-/ejson-shell-parser-2.0.1.tgz", - "integrity": "sha512-ZTDIeoRBWSrGgHMYlBn4PymQdtNCsnFUK/cSVwZREPNC3Mr+E3arO08DapVjBVDGTE08kkpqRll1Y+lwe5ZvCQ==", - "dependencies": { - "acorn": "^8.1.0" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "bson": "^4.6.3 || ^5 || ^6" - } - }, "node_modules/electron": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-29.4.3.tgz", - "integrity": "sha512-Fr/D7Iru7zGFK5DtNf3Ck/DBxLHtP/o/32pRXsSoGTVqyHKu2genIiSUiOhbxdu+gQZw4Do+BDDR6inkyr4CGQ==", + "version": "29.4.5", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.4.5.tgz", + "integrity": "sha512-DlEuzGbWBYl1Qr0qUYgNZdoixJg4YGHy2HC6fkRjSXSlb01UrQ5ORi8hNLzelzyYx8rNQyyE3zDUuk9EnZwYuA==", "hasInstallScript": true, "dependencies": { "@electron/get": "^2.0.0", @@ -24187,44 +24274,6 @@ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" }, - "node_modules/fs-plus": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", - "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", - "dependencies": { - "async": "^1.5.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2", - "underscore-plus": "1.x" - } - }, - "node_modules/fs-plus/node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "node_modules/fs-plus/node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/fs-plus/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/fs-temp": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", @@ -29990,21 +30039,10 @@ "source-map": "~0.6.0" } }, - "node_modules/less-cache": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/less-cache/-/less-cache-1.1.1.tgz", - "integrity": "sha512-cl7K2sUMu9m6lNHUd3XV3/C2IF76GOrsck2C9cf81Ymu6wbHrQI6NSJUejfcnR8MttdLpK6XdUYDNe+GDJdqJg==", - "dependencies": { - "fs-plus": "^3.1.1", - "less": "^3.12.2", - "underscore-plus": "^1.7.0", - "walkdir": "^0.4.1" - } - }, "node_modules/less/node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "optional": true, "bin": { "image-size": "bin/image-size.js" @@ -32445,12 +32483,12 @@ "integrity": "sha512-gYJjEYG4v4a1WSXgUf81OBoBRlj+Z1SlnQVO392fC/4a1CN7CLWDITajZWPFTPh/yRozYk6sHHtZwZmQhodBEA==" }, "node_modules/mongodb-query-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/mongodb-query-parser/-/mongodb-query-parser-4.1.2.tgz", - "integrity": "sha512-MfXJlYQcCgHKXo/OUo4x5eeJTN0XbZh9BD78xSsJ2pRnBo5/3Sx6H9Lw3NtdlTN/fJwypvJH24Qm2S2RmeRlFw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mongodb-query-parser/-/mongodb-query-parser-4.2.0.tgz", + "integrity": "sha512-VsrB2rJzKh3kEMApAz5EipA19G2LLZlnV9X1Ov9ERtnUkozm01sHP9YOGX//T1j/dZx96kbt5Aw2co5R5f6Bkw==", "dependencies": { + "@mongodb-js/shell-bson-parser": "^1.1.0", "debug": "^4.3.4", - "ejson-shell-parser": "^2.0.0", "javascript-stringify": "^2.1.0", "lodash": "^4.17.21" } @@ -32460,11 +32498,11 @@ "link": true }, "node_modules/mongodb-redact": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mongodb-redact/-/mongodb-redact-0.2.3.tgz", - "integrity": "sha512-a6ZPWlC9yf6F/n6ylKyyTO2PXZeD6nPKWwBmAIlOtOH4v82DIfsgO4Bpml10/YSwFxF1+VY8NHohmxofzpB4Yw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mongodb-redact/-/mongodb-redact-1.1.1.tgz", + "integrity": "sha512-j39aojyFmiEBb8KLgNC+oAb1ZTjLYjzFgyEzeNkW4bDFFlqBo0nqC6SXsU1q0+8yb4TQ6OzQD+KHd8yx7AnsGA==", "dependencies": { - "lodash": "^4.17.15" + "lodash": "^4.17.21" } }, "node_modules/mongodb-runner": { @@ -32715,9 +32753,9 @@ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "node_modules/native-request": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz", - "integrity": "sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", + "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", "optional": true }, "node_modules/natural-compare": { @@ -37018,7 +37056,7 @@ "node_modules/prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, "node_modules/ps-list": { @@ -38980,9 +39018,9 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "bin": { "semver": "bin/semver.js" }, @@ -40713,12 +40751,12 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "node_modules/system-ca": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/system-ca/-/system-ca-1.0.3.tgz", - "integrity": "sha512-FHwdyDHM/J6SjHNVEp532J5rWsO0oPB/szZGsP/8I2s78mPLQhE0WwKTGi/RJulqTICekINsczg5q44n/1b+lQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/system-ca/-/system-ca-2.0.0.tgz", + "integrity": "sha512-eEWsCZHEyXdRPPMO680gLUhb9x8RK7YlXvv+I0zCvmGg9zf9OCchJxDf5NHqGPwAzLDEFpLXL5qv9KEU62N4Nw==", "optionalDependencies": { "macos-export-certificate-and-key": "^1.1.1", - "win-export-certificate-and-key": "^1.1.1" + "win-export-certificate-and-key": "^2.0.0" } }, "node_modules/tabbable": { @@ -41982,19 +42020,6 @@ "through": "^2.3.8" } }, - "node_modules/underscore-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", - "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", - "dependencies": { - "underscore": "^1.9.1" - } - }, - "node_modules/underscore-plus/node_modules/underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -42475,14 +42500,6 @@ "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-1.0.0.tgz", "integrity": "sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==" }, - "node_modules/walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -43326,9 +43343,9 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, "node_modules/win-export-certificate-and-key": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/win-export-certificate-and-key/-/win-export-certificate-and-key-1.1.2.tgz", - "integrity": "sha512-3Su7Xdt9UR8pZicWQDcGSWNL6We/NzAGxe7AeQ1Z/zAeGHWlTKAh3HemGvIvxLRPsk4NW9D/QL3cL6SIvFcTvQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/win-export-certificate-and-key/-/win-export-certificate-and-key-2.0.1.tgz", + "integrity": "sha512-GsPUuIn95CepWgfiaqyIBWlj1uzr0LMfWIHBESSa+f84Zll9SjIX7Jj0+xNs/FlhH5zEkPO6k+SRQX1dfv3zPg==", "hasInstallScript": true, "optional": true, "os": [ @@ -43336,8 +43353,7 @@ ], "dependencies": { "bindings": "^1.5.0", - "node-addon-api": "^3.1.0", - "node-forge": "^1.2.1" + "node-addon-api": "^3.1.0" } }, "node_modules/win-export-certificate-and-key/node_modules/node-addon-api": { @@ -43346,15 +43362,6 @@ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "optional": true }, - "node_modules/win-export-certificate-and-key/node_modules/node-forge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz", - "integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==", - "optional": true, - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", @@ -43893,30 +43900,30 @@ }, "packages/atlas-service": { "name": "@mongodb-js/atlas-service", - "version": "0.22.0", + "version": "0.25.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", "@mongodb-js/devtools-connect": "^3.0.1", "@mongodb-js/oidc-plugin": "^1.0.0", - "compass-preferences-model": "^2.23.1", - "electron": "^29.4.3", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "compass-preferences-model": "^2.25.0", + "electron": "^29.4.5", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "node-fetch": "^2.7.0", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", "redux-thunk": "^2.4.2", - "system-ca": "^1.0.2" + "system-ca": "^2.0.0" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -43981,7 +43988,7 @@ } }, "packages/bson-transpilers": { - "version": "3.0.4", + "version": "3.0.5", "license": "SSPL", "dependencies": { "antlr4": "4.7.2", @@ -43989,7 +43996,7 @@ "js-yaml": "^3.13.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "chai": "^4.3.4", "depcheck": "^1.4.1", "eslint": "^7.25.0", @@ -44018,16 +44025,16 @@ }, "packages/collection-model": { "name": "mongodb-collection-model", - "version": "5.21.1", + "version": "5.22.1", "license": "SSPL", "dependencies": { "ampersand-collection": "^2.0.2", "ampersand-model": "^8.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", @@ -44042,58 +44049,58 @@ "hasInstallScript": true, "license": "SSPL", "dependencies": { - "@mongosh/node-runtime-worker-thread": "^2.2.10", + "@mongosh/node-runtime-worker-thread": "^2.2.12", "clipboard": "^2.0.6", "kerberos": "^2.1.0", "keytar": "^7.9.0", "mongodb-client-encryption": "^6.0.0", "os-dns-native": "^1.2.1", - "system-ca": "^1.0.3" + "system-ca": "^2.0.0" }, "devDependencies": { "@electron/rebuild": "^3.6.0", "@electron/remote": "^2.1.2", - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-aggregations": "^9.35.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connection-import-export": "^0.29.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-databases-collections": "^1.32.0", - "@mongodb-js/compass-explain-plan": "^6.33.0", - "@mongodb-js/compass-export-to-language": "^9.9.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-find-in-page": "^4.26.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-import-export": "^7.32.0", - "@mongodb-js/compass-indexes": "^5.32.0", - "@mongodb-js/compass-intercom": "^0.7.1", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-saved-aggregations-queries": "^1.33.0", - "@mongodb-js/compass-schema": "^6.34.0", - "@mongodb-js/compass-schema-validation": "^6.33.0", - "@mongodb-js/compass-serverstats": "^16.32.0", - "@mongodb-js/compass-settings": "^0.34.0", - "@mongodb-js/compass-shell": "^3.32.0", - "@mongodb-js/compass-sidebar": "^5.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-welcome": "^0.31.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-aggregations": "^9.38.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connection-import-export": "^0.32.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-databases-collections": "^1.35.0", + "@mongodb-js/compass-explain-plan": "^6.36.0", + "@mongodb-js/compass-export-to-language": "^9.12.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-find-in-page": "^4.29.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-import-export": "^7.35.0", + "@mongodb-js/compass-indexes": "^5.35.0", + "@mongodb-js/compass-intercom": "^0.9.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-saved-aggregations-queries": "^1.36.0", + "@mongodb-js/compass-schema": "^6.37.0", + "@mongodb-js/compass-schema-validation": "^6.36.0", + "@mongodb-js/compass-serverstats": "^16.35.0", + "@mongodb-js/compass-settings": "^0.37.0", + "@mongodb-js/compass-shell": "^3.35.0", + "@mongodb-js/compass-sidebar": "^5.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-welcome": "^0.34.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/get-os-info": "^0.3.24", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-downloader": "^0.3.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/sbom-tools": "^0.7.0", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/webpack-config-compass": "^1.3.11", + "@mongodb-js/webpack-config-compass": "^1.3.13", "@segment/analytics-node": "^1.1.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -44101,19 +44108,19 @@ "chai": "^4.3.4", "chalk": "^4.1.2", "clean-stack": "^2.0.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-devtools-installer": "^3.2.0", "electron-dl": "^3.5.0", "electron-mocha": "^12.2.0", "electron-squirrel-startup": "^1.0.1", "ensure-error": "^3.0.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-build": "^25.5.3", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-build": "^25.5.5", + "hadron-ipc": "^3.2.18", "local-links": "^1.4.0", "make-fetch-happen": "^8.0.14", "marky": "^1.2.1", @@ -44121,8 +44128,8 @@ "mongodb-build-info": "^1.7.2", "mongodb-cloud-info": "^2.1.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-log-writer": "^1.4.2", "mongodb-ns": "^2.4.2", "node-fetch": "^2.7.0", @@ -44138,12 +44145,12 @@ }, "optionalDependencies": { "macos-export-certificate-and-key": "^1.1.2", - "win-export-certificate-and-key": "^1.1.2" + "win-export-certificate-and-key": "^2.0.1" } }, "packages/compass-aggregations": { "name": "@mongodb-js/compass-aggregations", - "version": "9.35.0", + "version": "9.38.0", "license": "SSPL", "dependencies": { "@babel/generator": "^7.19.5", @@ -44152,36 +44159,36 @@ "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/explain-plan-helper": "^1.1.13", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/explain-plan-helper": "^1.1.14", "@mongodb-js/mongodb-constants": "^0.10.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", + "@mongodb-js/shell-bson-parser": "^1.1.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "mongodb-schema": "^12.2.0", "prop-types": "^15.7.2", "re-resizable": "^6.9.0", @@ -44192,7 +44199,7 @@ "semver": "^7.6.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44255,22 +44262,22 @@ }, "packages/compass-app-stores": { "name": "@mongodb-js/compass-app-stores", - "version": "7.19.0", + "version": "7.22.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/connection-info": "^0.4.1", - "hadron-app-registry": "^9.1.12", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/connection-info": "^0.5.1", + "hadron-app-registry": "^9.2.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44320,19 +44327,20 @@ }, "packages/compass-collection": { "name": "@mongodb-js/compass-collection", - "version": "4.32.0", + "version": "4.35.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", - "mongodb-collection-model": "^5.21.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/mongodb-constants": "^0.10.2", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "mongodb-collection-model": "^5.22.1", "mongodb-ns": "^2.4.2", "numeral": "^2.0.6", "react": "^17.0.2", @@ -44341,7 +44349,7 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44404,7 +44412,7 @@ }, "packages/compass-components": { "name": "@mongodb-js/compass-components", - "version": "1.26.0", + "version": "1.28.0", "license": "SSPL", "dependencies": { "@dnd-kit/core": "^6.0.7", @@ -44456,7 +44464,7 @@ "@react-stately/tooltip": "^3.0.5", "bson": "^6.7.0", "focus-trap-react": "^9.0.2", - "hadron-document": "^8.5.4", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "is-electron-renderer": "^2.0.1", "lodash": "^4.17.21", @@ -44469,7 +44477,7 @@ }, "devDependencies": { "@emotion/css": "^11.11.2", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44520,18 +44528,18 @@ }, "packages/compass-connection-import-export": { "name": "@mongodb-js/compass-connection-import-export", - "version": "0.29.0", + "version": "0.32.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/connection-storage": "^0.14.1", - "compass-preferences-model": "^2.23.1", - "hadron-ipc": "^3.2.16", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/connection-storage": "^0.16.0", + "compass-preferences-model": "^2.25.0", + "hadron-ipc": "^3.2.18", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44585,27 +44593,27 @@ }, "packages/compass-connections": { "name": "@mongodb-js/compass-connections", - "version": "1.33.0", + "version": "1.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb-build-info": "^1.7.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44633,22 +44641,22 @@ }, "packages/compass-connections-navigation": { "name": "@mongodb-js/compass-connections-navigation", - "version": "1.32.0", + "version": "1.35.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "compass-preferences-model": "^2.23.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "compass-preferences-model": "^2.25.0", "mongodb-build-info": "^1.7.2", "react": "^17.0.2", "react-virtualized-auto-sizer": "^1.0.6", "react-window": "^1.8.6" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44729,43 +44737,43 @@ }, "packages/compass-crud": { "name": "@mongodb-js/compass-crud", - "version": "13.33.0", + "version": "13.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/explain-plan-helper": "^1.1.13", - "@mongodb-js/my-queries-storage": "^0.10.0", - "@mongodb-js/reflux-state-mixin": "^1.0.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/explain-plan-helper": "^1.1.14", + "@mongodb-js/my-queries-storage": "^0.13.0", + "@mongodb-js/reflux-state-mixin": "^1.0.3", + "@mongodb-js/shell-bson-parser": "^1.1.0", "ag-grid-community": "^20.2.0", "ag-grid-react": "^20.2.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "jsondiffpatch": "^0.5.0", "lodash": "^4.17.21", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "prop-types": "^15.7.2", "react": "^17.0.2", "reflux": "^0.4.1", "semver": "^7.6.2" }, "devDependencies": { - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44775,12 +44783,12 @@ "chai": "^4.1.2", "chai-as-promised": "^7.1.1", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "nyc": "^15.1.0", "react-dom": "^17.0.2", "sinon": "^8.1.1", @@ -44824,12 +44832,12 @@ } }, "packages/compass-e2e-tests": { - "version": "1.21.7", + "version": "1.23.1", "devDependencies": { "@electron/rebuild": "^3.6.0", - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/oidc-mock-provider": "^0.9.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44841,15 +44849,15 @@ "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "clipboardy": "^2.3.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "cross-spawn": "^7.0.3", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "fast-glob": "^3.2.7", "glob": "^10.2.5", - "hadron-build": "^25.5.3", + "hadron-build": "^25.5.5", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", @@ -45106,7 +45114,7 @@ }, "packages/compass-editor": { "name": "@mongodb-js/compass-editor", - "version": "0.25.0", + "version": "0.27.0", "license": "SSPL", "dependencies": { "@codemirror/autocomplete": "^6.4.0", @@ -45118,14 +45126,15 @@ "@codemirror/state": "^6.1.4", "@codemirror/view": "^6.7.1", "@lezer/highlight": "^1.1.3", - "@mongodb-js/compass-components": "^1.26.0", + "@mongodb-js/compass-components": "^1.28.0", "@mongodb-js/mongodb-constants": "^0.10.0", + "mongodb-query-parser": "^4.2.0", "polished": "^4.2.2", "prettier": "^2.7.1", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45171,21 +45180,21 @@ }, "packages/compass-explain-plan": { "name": "@mongodb-js/compass-explain-plan", - "version": "6.33.0", + "version": "6.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/explain-plan-helper": "^1.1.13", - "compass-preferences-model": "^2.23.1", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/explain-plan-helper": "^1.1.14", + "compass-preferences-model": "^2.25.0", "d3": "^3.5.17", "d3-flextree": "^2.1.2", "d3-hierarchy": "^3.1.2", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", "react": "^17.0.2", @@ -45194,7 +45203,7 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45204,7 +45213,7 @@ "@types/d3-hierarchy": "^3.1.2", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -45250,27 +45259,27 @@ }, "packages/compass-export-to-language": { "name": "@mongodb-js/compass-export-to-language", - "version": "9.9.0", + "version": "9.12.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "bson-transpilers": "^3.0.4", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/shell-bson-parser": "^1.1.0", + "bson-transpilers": "^3.0.5", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1" }, "devDependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45315,11 +45324,11 @@ }, "packages/compass-field-store": { "name": "@mongodb-js/compass-field-store", - "version": "9.8.0", + "version": "9.11.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-connections": "^1.33.0", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-connections": "^1.36.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb-schema": "^12.2.0", "react": "^17.0.2", @@ -45327,7 +45336,7 @@ "redux": "^4.2.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45377,19 +45386,19 @@ }, "packages/compass-find-in-page": { "name": "@mongodb-js/compass-find-in-page", - "version": "4.26.0", + "version": "4.29.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "@mongodb-js/compass-components": "^1.28.0", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45403,7 +45412,7 @@ "@types/sinon-chai": "^3.2.5", "chai": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -45444,24 +45453,25 @@ }, "packages/compass-generative-ai": { "name": "@mongodb-js/compass-generative-ai", - "version": "0.16.0", + "version": "0.19.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-intercom": "^0.7.1", - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-intercom": "^0.9.0", + "@mongodb-js/compass-logging": "^1.4.1", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "mongodb": "^6.7.0", "mongodb-schema": "^12.2.0", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -45477,7 +45487,6 @@ "decomment": "^0.9.5", "depcheck": "^1.4.1", "digest-fetch": "^2.0.3", - "ejson-shell-parser": "^2.0.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -45646,29 +45655,29 @@ }, "packages/compass-import-export": { "name": "@mongodb-js/compass-import-export", - "version": "7.32.0", + "version": "7.35.0", "license": "SSPL", "dependencies": { "@electron/remote": "^2.1.2", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "debug": "^4.3.4", - "electron": "^29.4.3", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", - "hadron-ipc": "^3.2.16", + "electron": "^29.4.5", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "mongodb-schema": "^12.2.0", "papaparse": "^5.3.2", "react": "^17.0.2", @@ -45679,8 +45688,8 @@ "strip-bom-stream": "^4.0.0" }, "devDependencies": { - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45741,28 +45750,28 @@ }, "packages/compass-indexes": { "name": "@mongodb-js/compass-indexes", - "version": "5.32.0", + "version": "5.35.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", "@mongodb-js/mongodb-constants": "^0.10.0", + "@mongodb-js/shell-bson-parser": "^1.1.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-data-service": "^22.21.1", - "mongodb-query-parser": "^4.1.2", + "mongodb-data-service": "^22.22.1", + "mongodb-query-parser": "^4.2.0", "numeral": "^2.0.6", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -45771,7 +45780,7 @@ "semver": "^7.6.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45779,7 +45788,7 @@ "@testing-library/user-event": "^13.5.0", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -45869,14 +45878,14 @@ }, "packages/compass-intercom": { "name": "@mongodb-js/compass-intercom", - "version": "0.7.1", + "version": "0.9.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "compass-preferences-model": "^2.23.1" + "@mongodb-js/compass-logging": "^1.4.1", + "compass-preferences-model": "^2.25.0" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -45976,18 +45985,18 @@ }, "packages/compass-logging": { "name": "@mongodb-js/compass-logging", - "version": "1.3.1", + "version": "1.4.1", "license": "SSPL", "dependencies": { "debug": "^4.3.4", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "is-electron-renderer": "^2.0.1", "mongodb-log-writer": "^1.4.2", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46034,14 +46043,14 @@ }, "packages/compass-maybe-protect-connection-string": { "name": "@mongodb-js/compass-maybe-protect-connection-string", - "version": "0.21.1", + "version": "0.23.0", "license": "SSPL", "dependencies": { - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "mongodb-connection-string-url": "^3.0.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46087,14 +46096,14 @@ } }, "packages/compass-preferences-model": { - "version": "2.23.1", + "version": "2.25.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-user-data": "^0.2.1", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-user-data": "^0.3.1", "bson": "^6.7.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "react": "^17.0.2", @@ -46102,7 +46111,7 @@ "zod": "^3.22.3" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@testing-library/react": "^12.1.5", "@types/js-yaml": "^4.0.5", @@ -46151,30 +46160,30 @@ }, "packages/compass-query-bar": { "name": "@mongodb-js/compass-query-bar", - "version": "8.34.0", + "version": "8.37.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", "@mongodb-js/mongodb-constants": "^0.10.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", - "mongodb-query-util": "^2.2.3", + "mongodb-query-parser": "^4.2.0", + "mongodb-query-util": "^2.2.4", "mongodb-schema": "^12.2.0", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -46182,7 +46191,7 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46191,7 +46200,7 @@ "@testing-library/user-event": "^13.5.0", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -46231,22 +46240,22 @@ }, "packages/compass-saved-aggregations-queries": { "name": "@mongodb-js/compass-saved-aggregations-queries", - "version": "1.33.0", + "version": "1.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/my-queries-storage": "^0.13.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "fuse.js": "^6.5.3", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -46254,8 +46263,8 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46310,30 +46319,30 @@ }, "packages/compass-schema": { "name": "@mongodb-js/compass-schema", - "version": "6.34.0", + "version": "6.37.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/reflux-state-mixin": "^1.0.2", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/reflux-state-mixin": "^1.0.3", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "d3": "^3.5.17", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "leaflet": "^1.5.1", "leaflet-defaulticon-compatibility": "^0.1.1", "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", "moment": "^2.29.4", "mongodb": "^6.7.0", - "mongodb-query-util": "^2.2.3", + "mongodb-query-util": "^2.2.4", "mongodb-schema": "^12.2.0", "numeral": "^1.5.6", "prop-types": "^15.7.2", @@ -46343,9 +46352,9 @@ "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", @@ -46370,25 +46379,25 @@ }, "packages/compass-schema-validation": { "name": "@mongodb-js/compass-schema-validation", - "version": "6.33.0", + "version": "6.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "javascript-stringify": "^2.0.1", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "prop-types": "^15.7.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -46397,19 +46406,19 @@ "semver": "^7.6.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-ipc": "^3.2.16", + "hadron-ipc": "^3.2.18", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "nyc": "^15.1.0", "react-dom": "^17.0.2", "sinon": "^8.1.1", @@ -46445,18 +46454,18 @@ }, "packages/compass-serverstats": { "name": "@mongodb-js/compass-serverstats", - "version": "16.32.0", + "version": "16.35.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", "d3": "^3.5.17", "d3-timer": "^1.0.3", "debug": "^4.3.4", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", "prop-types": "^15.7.2", @@ -46464,7 +46473,7 @@ "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46494,23 +46503,23 @@ }, "packages/compass-settings": { "name": "@mongodb-js/compass-settings", - "version": "0.34.0", + "version": "0.37.0", "license": "SSPL", "dependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46564,35 +46573,36 @@ }, "packages/compass-shell": { "name": "@mongodb-js/compass-shell", - "version": "3.32.0", + "version": "3.35.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongosh/browser-repl": "^2.2.10", - "@mongosh/logging": "^2.2.10", - "@mongosh/node-runtime-worker-thread": "^2.2.10", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", - "prop-types": "^15.7.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongosh/browser-repl": "^2.2.12", + "@mongosh/logging": "^2.2.12", + "@mongosh/node-runtime-worker-thread": "^2.2.12", + "bson": "^6.7.0", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "react": "^17.0.2", "react-redux": "^8.1.3", - "redux": "^4.2.1" + "redux": "^4.2.1", + "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", @@ -46632,26 +46642,26 @@ }, "packages/compass-sidebar": { "name": "@mongodb-js/compass-sidebar", - "version": "5.33.0", + "version": "5.36.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connection-import-export": "^0.29.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-connections-navigation": "^1.32.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connection-import-export": "^0.32.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-connections-navigation": "^1.35.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -46659,8 +46669,8 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46678,7 +46688,7 @@ "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "prettier": "^2.7.1", "react-dom": "^17.0.2", @@ -46746,16 +46756,16 @@ }, "packages/compass-telemetry": { "name": "@mongodb-js/compass-telemetry", - "version": "1.0.1", + "version": "1.1.1", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "@mongodb-js/compass-logging": "^1.4.1", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46856,13 +46866,13 @@ }, "packages/compass-test-server": { "name": "@mongodb-js/compass-test-server", - "version": "0.1.17", + "version": "0.1.18", "license": "SSPL", "dependencies": { "mongodb-runner": "^5.6.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46907,16 +46917,16 @@ }, "packages/compass-user-data": { "name": "@mongodb-js/compass-user-data", - "version": "0.2.1", + "version": "0.3.1", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-utils": "^0.6.7", "write-file-atomic": "^5.0.1", "zod": "^3.22.3" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -46987,14 +46997,14 @@ }, "packages/compass-utils": { "name": "@mongodb-js/compass-utils", - "version": "0.6.5", + "version": "0.6.7", "license": "SSPL", "dependencies": { "@electron/remote": "^2.1.2", - "electron": "^29.4.3" + "electron": "^29.4.5" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -47041,35 +47051,35 @@ }, "packages/compass-web": { "name": "@mongodb-js/compass-web", - "version": "0.5.1", + "version": "0.5.5", "license": "SSPL", "devDependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-aggregations": "^9.35.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-databases-collections": "^1.32.0", - "@mongodb-js/compass-explain-plan": "^6.33.0", - "@mongodb-js/compass-export-to-language": "^9.9.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-indexes": "^5.32.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-schema": "^6.34.0", - "@mongodb-js/compass-schema-validation": "^6.33.0", - "@mongodb-js/compass-sidebar": "^5.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-aggregations": "^9.38.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-databases-collections": "^1.35.0", + "@mongodb-js/compass-explain-plan": "^6.36.0", + "@mongodb-js/compass-export-to-language": "^9.12.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-indexes": "^5.35.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-schema": "^6.37.0", + "@mongodb-js/compass-schema-validation": "^6.36.0", + "@mongodb-js/compass-sidebar": "^5.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/webpack-config-compass": "^1.3.11", + "@mongodb-js/webpack-config-compass": "^1.3.13", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", "@testing-library/user-event": "^13.5.0", @@ -47084,23 +47094,23 @@ "bson": "^6.2.0", "buffer": "^6.0.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "crypto-browserify": "^3.12.0", "debug": "^4.3.4", "depcheck": "^1.4.1", "dns-query": "^0.11.2", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "events": "^3.3.0", "express": "^4.19.2", "express-http-proxy": "^2.0.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "is-ip": "^5.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", @@ -47364,21 +47374,21 @@ }, "packages/compass-welcome": { "name": "@mongodb-js/compass-welcome", - "version": "0.31.0", + "version": "0.34.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "react": "^17.0.2", "redux": "^4.2.1", "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -47432,18 +47442,18 @@ }, "packages/compass-workspaces": { "name": "@mongodb-js/compass-workspaces", - "version": "0.14.0", + "version": "0.17.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", "bson": "^6.7.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -47451,7 +47461,7 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -47625,24 +47635,24 @@ }, "packages/connection-form": { "name": "@mongodb-js/connection-form", - "version": "1.31.0", + "version": "1.34.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/connection-info": "^0.4.1", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/shell-bson-parser": "^1.1.0", + "compass-preferences-model": "^2.25.0", "lodash": "^4.17.21", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", - "mongodb-query-parser": "^4.1.2", + "mongodb-data-service": "^22.22.1", + "mongodb-query-parser": "^4.2.0", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -47697,16 +47707,16 @@ }, "packages/connection-info": { "name": "@mongodb-js/connection-info", - "version": "0.4.1", + "version": "0.5.1", "license": "SSPL", "dependencies": { "lodash": "^4.17.21", "mongodb": "^6.7.0", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1" + "mongodb-data-service": "^22.22.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -47823,26 +47833,26 @@ }, "packages/connection-storage": { "name": "@mongodb-js/connection-storage", - "version": "0.14.1", + "version": "0.16.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/connection-info": "^0.4.1", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/connection-info": "^0.5.1", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "electron": "^29.4.3", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "compass-preferences-model": "^2.25.0", + "electron": "^29.4.5", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "keytar": "^7.9.0", "lodash": "^4.17.21", "mongodb-connection-string-url": "^3.0.1", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -47888,13 +47898,13 @@ }, "packages/data-service": { "name": "mongodb-data-service", - "version": "22.21.1", + "version": "22.22.1", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-utils": "^0.6.7", "@mongodb-js/devtools-connect": "^3.0.1", - "@mongodb-js/ssh-tunnel": "^2.2.1", + "@mongodb-js/ssh-tunnel": "^2.3.1", "bson": "^6.7.0", "lodash": "^4.17.21", "mongodb": "^6.7.0", @@ -47903,9 +47913,9 @@ "mongodb-ns": "^2.4.2" }, "devDependencies": { - "@mongodb-js/compass-test-server": "^0.1.17", + "@mongodb-js/compass-test-server": "^0.1.18", "@mongodb-js/devtools-docker-test-envs": "^1.3.2", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/oidc-plugin": "^1.0.0", "@mongodb-js/prettier-config-compass": "^1.0.2", @@ -47957,16 +47967,16 @@ }, "packages/database-model": { "name": "mongodb-database-model", - "version": "2.21.1", + "version": "2.22.1", "license": "SSPL", "dependencies": { "ampersand-collection": "^2.0.2", "ampersand-model": "^8.0.1", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1" + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "depcheck": "^1.4.1", "eslint": "^7.25.0", @@ -48024,27 +48034,26 @@ }, "packages/databases-collections": { "name": "@mongodb-js/compass-databases-collections", - "version": "1.32.0", + "version": "1.35.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/databases-collections-list": "^1.30.0", - "@mongodb-js/my-queries-storage": "^0.10.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/databases-collections-list": "^1.33.0", + "@mongodb-js/my-queries-storage": "^0.13.0", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "prop-types": "^15.7.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -48053,7 +48062,7 @@ "semver": "^7.6.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -48073,16 +48082,20 @@ }, "packages/databases-collections-list": { "name": "@mongodb-js/databases-collections-list", - "version": "1.30.0", + "version": "1.33.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "compass-preferences-model": "^2.23.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "compass-preferences-model": "^2.25.0", + "mongodb-ns": "^2.4.2", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -48189,13 +48202,13 @@ }, "packages/explain-plan-helper": { "name": "@mongodb-js/explain-plan-helper", - "version": "1.1.13", + "version": "1.1.14", "license": "SSPL", "dependencies": { "mongodb-explain-compat": "^3.0.4" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -48267,7 +48280,7 @@ } }, "packages/hadron-app-registry": { - "version": "9.1.12", + "version": "9.2.1", "license": "SSPL", "dependencies": { "eventemitter3": "^4.0.0", @@ -48277,7 +48290,7 @@ "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -48323,7 +48336,7 @@ } }, "packages/hadron-build": { - "version": "25.5.3", + "version": "25.5.5", "hasInstallScript": true, "license": "SSPL", "dependencies": { @@ -48336,13 +48349,12 @@ "@octokit/rest": "^18.6.2", "asar": "^3.0.3", "async": "^3.2.2", - "bluebird": "^3.7.2", "chalk": "^4.1.2", "cli-table": "^0.3.1", "debug": "^4.3.4", "del": "^2.0.2", "download": "^8.0.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-packager": "^15.5.1", "electron-packager-plugin-non-proprietary-codecs-ffmpeg": "^1.0.2", "flatnest": "^1.0.0", @@ -48353,7 +48365,6 @@ "js-yaml": "^4.1.0", "json-diff": "^0.9.0", "jszip": "^3.5.0", - "less-cache": "^1.1.0", "lodash": "^4.17.21", "moment": "^2.29.4", "mongodb-js-cli": "^0.0.3", @@ -48371,7 +48382,7 @@ "hadron-build": "cli.js" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "chai": "^4.2.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", @@ -49039,7 +49050,7 @@ } }, "packages/hadron-document": { - "version": "8.5.4", + "version": "8.5.5", "license": "SSPL", "dependencies": { "bson": "^6.7.0", @@ -49048,7 +49059,7 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -49159,15 +49170,15 @@ } }, "packages/hadron-ipc": { - "version": "3.2.16", + "version": "3.2.18", "license": "SSPL", "dependencies": { "debug": "^4.3.4", - "electron": "^29.4.3", + "electron": "^29.4.5", "is-electron-renderer": "^2.0.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -49230,16 +49241,16 @@ }, "packages/instance-model": { "name": "mongodb-instance-model", - "version": "12.22.1", + "version": "12.23.1", "license": "SSPL", "dependencies": { "ampersand-model": "^8.0.1", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1", - "mongodb-database-model": "^2.21.1" + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-database-model": "^2.22.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "chai": "^4.3.4", "depcheck": "^1.4.1", @@ -49264,14 +49275,14 @@ } }, "packages/mongodb-query-util": { - "version": "2.2.3", + "version": "2.2.4", "license": "SSPL", "dependencies": { "bson": "^6.7.0", "lodash": "^4.17.21" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -49507,17 +49518,17 @@ }, "packages/my-queries-storage": { "name": "@mongodb-js/my-queries-storage", - "version": "0.10.0", + "version": "0.13.0", "license": "SSPL", "dependencies": { - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-user-data": "^0.2.1", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-user-data": "^0.3.1", "bson": "^6.7.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -49585,13 +49596,13 @@ }, "packages/reflux-state-mixin": { "name": "@mongodb-js/reflux-state-mixin", - "version": "1.0.2", + "version": "1.0.3", "license": "SSPL", "dependencies": { "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -50093,15 +50104,15 @@ }, "packages/ssh-tunnel": { "name": "@mongodb-js/ssh-tunnel", - "version": "2.2.1", + "version": "2.3.1", "license": "Apache-2.0", "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/compass-logging": "^1.4.1", "socksv5": "0.0.6", "ssh2": "^1.12.0" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -50174,13 +50185,13 @@ }, "scripts": { "name": "@mongodb-js/compass-scripts", - "version": "0.16.13", + "version": "0.16.15", "license": "SSPL", "dependencies": { "@babel/core": "^7.24.3", "@mongodb-js/monorepo-tools": "^1.1.1", "commander": "^11.0.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "jsdom": "^21.1.0", "make-fetch-happen": "^8.0.14", "pacote": "^11.3.5", @@ -50193,7 +50204,7 @@ "compass-scripts": "cli.js" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "depcheck": "^1.4.1", "eslint": "^7.25.0", @@ -50567,49 +50578,49 @@ } }, "@aws-sdk/client-cognito-identity": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.600.0.tgz", - "integrity": "sha512-8dYsnDLiD0rjujRiZZl0E57heUkHqMSFZHBi0YMs57SM8ODPxK3tahwDYZtS7bqanvFKZwGy+o9jIcij7jBOlA==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.614.0.tgz", + "integrity": "sha512-nydN0TVIMkYhYcCABkCcllmhLakzD4aN8r6ROWWG83+XFtBGgnvY2cxj2uFx+Vp7THAVnG2r6GVGKzEwvAH3pA==", "requires": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.600.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/client-sso-oidc": "3.614.0", + "@aws-sdk/client-sts": "3.614.0", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -50622,46 +50633,46 @@ } }, "@aws-sdk/client-sso": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.598.0.tgz", - "integrity": "sha512-nOI5lqPYa+YZlrrzwAJywJSw3MKVjvu6Ge2fCqQUNYMfxFB0NAaDFnl0EPjXi+sEbtCuz/uWE77poHbqiZ+7Iw==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.614.0.tgz", + "integrity": "sha512-p5pyYaxRzBttjBkqfc8i3K7DzBdTg3ECdVgBo6INIUxfvDy0J8QUE8vNtCgvFIkq+uPw/8M+Eo4zzln7anuO0Q==", "requires": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -50674,48 +50685,47 @@ } }, "@aws-sdk/client-sso-oidc": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.600.0.tgz", - "integrity": "sha512-7+I8RWURGfzvChyNQSyj5/tKrqRbzRl7H+BnTOf/4Vsw1nFOi5ROhlhD4X/Y0QCTacxnaoNcIrqnY7uGGvVRzw==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.614.0.tgz", + "integrity": "sha512-BI1NWcpppbHg/28zbUg54dZeckork8BItZIcjls12vxasy+p3iEzrJVG60jcbUTTsk3Qc1tyxNfrdcVqx0y7Ww==", "requires": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -50728,48 +50738,48 @@ } }, "@aws-sdk/client-sts": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.600.0.tgz", - "integrity": "sha512-KQG97B7LvTtTiGmjlrG1LRAY8wUvCQzrmZVV5bjrJ/1oXAU7DITYwVbSJeX9NWg6hDuSk0VE3MFwIXS2SvfLIA==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.614.0.tgz", + "integrity": "sha512-i6QmaVA1KHHYNnI2VYQy/sc31rLm4+jSp8b/YbQpFnD0w3aXsrEEHHlxek45uSkHb4Nrj1omFBVy/xp1WVYx2Q==", "requires": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/client-sso-oidc": "3.600.0", - "@aws-sdk/core": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/middleware-host-header": "3.598.0", - "@aws-sdk/middleware-logger": "3.598.0", - "@aws-sdk/middleware-recursion-detection": "3.598.0", - "@aws-sdk/middleware-user-agent": "3.598.0", - "@aws-sdk/region-config-resolver": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@aws-sdk/util-user-agent-browser": "3.598.0", - "@aws-sdk/util-user-agent-node": "3.598.0", - "@smithy/config-resolver": "^3.0.2", - "@smithy/core": "^2.2.1", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/hash-node": "^3.0.1", - "@smithy/invalid-dependency": "^3.0.1", - "@smithy/middleware-content-length": "^3.0.1", - "@smithy/middleware-endpoint": "^3.0.2", - "@smithy/middleware-retry": "^3.0.4", - "@smithy/middleware-serde": "^3.0.1", - "@smithy/middleware-stack": "^3.0.1", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/url-parser": "^3.0.1", + "@aws-sdk/client-sso-oidc": "3.614.0", + "@aws-sdk/core": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/middleware-host-header": "3.609.0", + "@aws-sdk/middleware-logger": "3.609.0", + "@aws-sdk/middleware-recursion-detection": "3.609.0", + "@aws-sdk/middleware-user-agent": "3.614.0", + "@aws-sdk/region-config-resolver": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@aws-sdk/util-user-agent-browser": "3.609.0", + "@aws-sdk/util-user-agent-node": "3.614.0", + "@smithy/config-resolver": "^3.0.5", + "@smithy/core": "^2.2.6", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/hash-node": "^3.0.3", + "@smithy/invalid-dependency": "^3.0.3", + "@smithy/middleware-content-length": "^3.0.3", + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "@smithy/util-base64": "^3.0.0", "@smithy/util-body-length-browser": "^3.0.0", "@smithy/util-body-length-node": "^3.0.0", - "@smithy/util-defaults-mode-browser": "^3.0.4", - "@smithy/util-defaults-mode-node": "^3.0.4", - "@smithy/util-endpoints": "^2.0.2", - "@smithy/util-middleware": "^3.0.1", - "@smithy/util-retry": "^3.0.1", + "@smithy/util-defaults-mode-browser": "^3.0.9", + "@smithy/util-defaults-mode-node": "^3.0.9", + "@smithy/util-endpoints": "^2.0.5", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" }, @@ -50782,15 +50792,15 @@ } }, "@aws-sdk/core": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.598.0.tgz", - "integrity": "sha512-HaSjt7puO5Cc7cOlrXFCW0rtA0BM9lvzjl56x0A20Pt+0wxXGeTOZZOkXQIepbrFkV2e/HYukuT9e99vXDm59g==", - "requires": { - "@smithy/core": "^2.2.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/signature-v4": "^3.1.0", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.614.0.tgz", + "integrity": "sha512-BUuS5/1YkgmKc4J0bg83XEtMyDHVyqG2QDzfmhYe8gbOIZabUl1FlrFVwhCAthtrrI6MPGTQcERB4BtJKUSplw==", + "requires": { + "@smithy/core": "^2.2.6", + "@smithy/protocol-http": "^4.0.3", + "@smithy/signature-v4": "^3.1.2", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", "fast-xml-parser": "4.2.5", "tslib": "^2.6.2" }, @@ -50803,14 +50813,14 @@ } }, "@aws-sdk/credential-provider-cognito-identity": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.600.0.tgz", - "integrity": "sha512-AIM+B06d1+71EuBrk2UR9ZZgRS3a+ARxE3oZKMZYlfqtZ3kY8w4DkhEt7OVruc6uSsMhkrcQT6nxsOxFSi4RtA==", - "requires": { - "@aws-sdk/client-cognito-identity": "3.600.0", - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.614.0.tgz", + "integrity": "sha512-Y89x4RKUlggxtCU07OhQRhvsiBBOzt0ep7OyxnnkhgPrbmY+N4tfMk3sEo02sxetqTuirLz4hRbfxwlsM5scpw==", + "requires": { + "@aws-sdk/client-cognito-identity": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50822,13 +50832,13 @@ } }, "@aws-sdk/credential-provider-env": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.598.0.tgz", - "integrity": "sha512-vi1khgn7yXzLCcgSIzQrrtd2ilUM0dWodxj3PQ6BLfP0O+q1imO3hG1nq7DVyJtq7rFHs6+9N8G4mYvTkxby2w==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.609.0.tgz", + "integrity": "sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50840,18 +50850,18 @@ } }, "@aws-sdk/credential-provider-http": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.598.0.tgz", - "integrity": "sha512-N7cIafi4HVlQvEgvZSo1G4T9qb/JMLGMdBsDCT5XkeJrF0aptQWzTFH0jIdZcLrMYvzPcuEyO3yCBe6cy/ba0g==", - "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/fetch-http-handler": "^3.0.2", - "@smithy/node-http-handler": "^3.0.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/protocol-http": "^4.0.1", - "@smithy/smithy-client": "^3.1.2", - "@smithy/types": "^3.1.0", - "@smithy/util-stream": "^3.0.2", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.614.0.tgz", + "integrity": "sha512-YIEjlNUKb3Vo/iTnGAPdsiDC3FUUnNoex2OwU8LmR7AkYZiWdB8nx99DfgkkY+OFMUpw7nKD2PCOtuFONelfGA==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/property-provider": "^3.1.3", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.0.6", "tslib": "^2.6.2" }, "dependencies": { @@ -50863,20 +50873,20 @@ } }, "@aws-sdk/credential-provider-ini": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.598.0.tgz", - "integrity": "sha512-/ppcIVUbRwDIwJDoYfp90X3+AuJo2mvE52Y1t2VSrvUovYn6N4v95/vXj6LS8CNDhz2jvEJYmu+0cTMHdhI6eA==", - "requires": { - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.614.0.tgz", + "integrity": "sha512-KfLuLFGwlvFSZ2MuzYwWGPb1y5TeiwX5okIDe0aQ1h10oD3924FXbN+mabOnUHQ8EFcGAtCaWbrC86mI7ktC6A==", + "requires": { + "@aws-sdk/credential-provider-env": "3.609.0", + "@aws-sdk/credential-provider-http": "3.614.0", + "@aws-sdk/credential-provider-process": "3.614.0", + "@aws-sdk/credential-provider-sso": "3.614.0", + "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50888,21 +50898,21 @@ } }, "@aws-sdk/credential-provider-node": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.600.0.tgz", - "integrity": "sha512-1pC7MPMYD45J7yFjA90SxpR0yaSvy+yZiq23aXhAPZLYgJBAxHLu0s0mDCk/piWGPh8+UGur5K0bVdx4B1D5hw==", - "requires": { - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-ini": "3.598.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.614.0.tgz", + "integrity": "sha512-4J6gPEuFZP0mkWq5E//oMS1vrmMM88iNNcv7TEljYnsc6JTAlKejCyFwx6CN+nkIhmIZsl06SXIhBemzBdBPfg==", + "requires": { + "@aws-sdk/credential-provider-env": "3.609.0", + "@aws-sdk/credential-provider-http": "3.614.0", + "@aws-sdk/credential-provider-ini": "3.614.0", + "@aws-sdk/credential-provider-process": "3.614.0", + "@aws-sdk/credential-provider-sso": "3.614.0", + "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50914,14 +50924,14 @@ } }, "@aws-sdk/credential-provider-process": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.598.0.tgz", - "integrity": "sha512-rM707XbLW8huMk722AgjVyxu2tMZee++fNA8TJVNgs1Ma02Wx6bBrfIvlyK0rCcIRb0WdQYP6fe3Xhiu4e8IBA==", - "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.614.0.tgz", + "integrity": "sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50933,16 +50943,16 @@ } }, "@aws-sdk/credential-provider-sso": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.598.0.tgz", - "integrity": "sha512-5InwUmrAuqQdOOgxTccRayMMkSmekdLk6s+az9tmikq0QFAHUCtofI+/fllMXSR9iL6JbGYi1940+EUmS4pHJA==", - "requires": { - "@aws-sdk/client-sso": "3.598.0", - "@aws-sdk/token-providers": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.614.0.tgz", + "integrity": "sha512-55+gp0JY4451cWI1qXmVMFM0GQaBKiQpXv2P0xmd9P3qLDyeFUSEW8XPh0d2lb1ICr6x4s47ynXVdGCIv2mXMg==", + "requires": { + "@aws-sdk/client-sso": "3.614.0", + "@aws-sdk/token-providers": "3.614.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50954,13 +50964,13 @@ } }, "@aws-sdk/credential-provider-web-identity": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.598.0.tgz", - "integrity": "sha512-GV5GdiMbz5Tz9JO4NJtRoFXjW0GPEujA0j+5J/B723rTN+REHthJu48HdBKouHGhdzkDWkkh1bu52V02Wprw8w==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.609.0.tgz", + "integrity": "sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -50972,25 +50982,25 @@ } }, "@aws-sdk/credential-providers": { - "version": "3.600.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.600.0.tgz", - "integrity": "sha512-cC9uqmX0rgx1efiJGqeR+i0EXr8RQ5SAzH7M45WNBZpYiLEe6reWgIYJY9hmOxuaoMdWSi8kekuN3IjTIORRjw==", - "requires": { - "@aws-sdk/client-cognito-identity": "3.600.0", - "@aws-sdk/client-sso": "3.598.0", - "@aws-sdk/client-sts": "3.600.0", - "@aws-sdk/credential-provider-cognito-identity": "3.600.0", - "@aws-sdk/credential-provider-env": "3.598.0", - "@aws-sdk/credential-provider-http": "3.598.0", - "@aws-sdk/credential-provider-ini": "3.598.0", - "@aws-sdk/credential-provider-node": "3.600.0", - "@aws-sdk/credential-provider-process": "3.598.0", - "@aws-sdk/credential-provider-sso": "3.598.0", - "@aws-sdk/credential-provider-web-identity": "3.598.0", - "@aws-sdk/types": "3.598.0", - "@smithy/credential-provider-imds": "^3.1.1", - "@smithy/property-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.614.0.tgz", + "integrity": "sha512-mgb6bcLiOig9ZWxuAF4g0QwLGuqSleYFAyPWyWo30XafCAGB2MfCwxksVWRH+cuX86fCnAF8XgYnaSs38fBOXA==", + "requires": { + "@aws-sdk/client-cognito-identity": "3.614.0", + "@aws-sdk/client-sso": "3.614.0", + "@aws-sdk/client-sts": "3.614.0", + "@aws-sdk/credential-provider-cognito-identity": "3.614.0", + "@aws-sdk/credential-provider-env": "3.609.0", + "@aws-sdk/credential-provider-http": "3.614.0", + "@aws-sdk/credential-provider-ini": "3.614.0", + "@aws-sdk/credential-provider-node": "3.614.0", + "@aws-sdk/credential-provider-process": "3.614.0", + "@aws-sdk/credential-provider-sso": "3.614.0", + "@aws-sdk/credential-provider-web-identity": "3.609.0", + "@aws-sdk/types": "3.609.0", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51002,13 +51012,13 @@ } }, "@aws-sdk/middleware-host-header": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.598.0.tgz", - "integrity": "sha512-WiaG059YBQwQraNejLIi0gMNkX7dfPZ8hDIhvMr5aVPRbaHH8AYF3iNSsXYCHvA2Cfa1O9haYXsuMF9flXnCmA==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.609.0.tgz", + "integrity": "sha512-iTKfo158lc4jLDfYeZmYMIBHsn8m6zX+XB6birCSNZ/rrlzAkPbGE43CNdKfvjyWdqgLMRXF+B+OcZRvqhMXPQ==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51020,12 +51030,12 @@ } }, "@aws-sdk/middleware-logger": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.598.0.tgz", - "integrity": "sha512-bxBjf/VYiu3zfu8SYM2S9dQQc3tz5uBAOcPz/Bt8DyyK3GgOpjhschH/2XuUErsoUO1gDJqZSdGOmuHGZQn00Q==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.609.0.tgz", + "integrity": "sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51037,13 +51047,13 @@ } }, "@aws-sdk/middleware-recursion-detection": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.598.0.tgz", - "integrity": "sha512-vjT9BeFY9FeN0f8hm2l6F53tI0N5bUq6RcDkQXKNabXBnQxKptJRad6oP2X5y3FoVfBLOuDkQgiC2940GIPxtQ==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.609.0.tgz", + "integrity": "sha512-6sewsYB7/o/nbUfA99Aa/LokM+a/u4Wpm/X2o0RxOsDtSB795ObebLJe2BxY5UssbGaWkn7LswyfvrdZNXNj1w==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51055,14 +51065,14 @@ } }, "@aws-sdk/middleware-user-agent": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.598.0.tgz", - "integrity": "sha512-4tjESlHG5B5MdjUaLK7tQs/miUtHbb6deauQx8ryqSBYOhfHVgb1ZnzvQR0bTrhpqUg0WlybSkDaZAICf9xctg==", - "requires": { - "@aws-sdk/types": "3.598.0", - "@aws-sdk/util-endpoints": "3.598.0", - "@smithy/protocol-http": "^4.0.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.614.0.tgz", + "integrity": "sha512-xUxh0UPQiMTG6E31Yvu6zVYlikrIcFDKljM11CaatInzvZubGTGiX0DjpqRlfGzUNsuPc/zNrKwRP2+wypgqIw==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@aws-sdk/util-endpoints": "3.614.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51074,15 +51084,15 @@ } }, "@aws-sdk/region-config-resolver": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.598.0.tgz", - "integrity": "sha512-oYXhmTokSav4ytmWleCr3rs/1nyvZW/S0tdi6X7u+dLNL5Jee+uMxWGzgOrWK6wrQOzucLVjS4E/wA11Kv2GTw==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.614.0.tgz", + "integrity": "sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.1", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "dependencies": { @@ -51094,14 +51104,14 @@ } }, "@aws-sdk/token-providers": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.598.0.tgz", - "integrity": "sha512-TKY1EVdHVBnZqpyxyTHdpZpa1tUpb6nxVeRNn1zWG8QB5MvH4ALLd/jR+gtmWDNQbIG4cVuBOZFVL8hIYicKTA==", - "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/property-provider": "^3.1.1", - "@smithy/shared-ini-file-loader": "^3.1.1", - "@smithy/types": "^3.1.0", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.614.0.tgz", + "integrity": "sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==", + "requires": { + "@aws-sdk/types": "3.609.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51113,11 +51123,11 @@ } }, "@aws-sdk/types": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.598.0.tgz", - "integrity": "sha512-742uRl6z7u0LFmZwDrFP6r1wlZcgVPw+/TilluDJmCAR8BgRw3IR+743kUXKBGd8QZDRW2n6v/PYsi/AWCDDMQ==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.609.0.tgz", + "integrity": "sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==", "requires": { - "@smithy/types": "^3.1.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -51129,13 +51139,13 @@ } }, "@aws-sdk/util-endpoints": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.598.0.tgz", - "integrity": "sha512-Qo9UoiVVZxcOEdiOMZg3xb1mzkTxrhd4qSlg5QQrfWPJVx/QOg+Iy0NtGxPtHtVZNHZxohYwDwV/tfsnDSE2gQ==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.614.0.tgz", + "integrity": "sha512-wK2cdrXHH4oz4IomV/yrGkftU9A+ITB6nFL+rxxyO78is2ifHJpFdV4aqk4LSkXYPi6CXWNru/Dqc7yiKXgJPw==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", - "@smithy/util-endpoints": "^2.0.2", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", + "@smithy/util-endpoints": "^2.0.5", "tslib": "^2.6.2" }, "dependencies": { @@ -51162,12 +51172,12 @@ } }, "@aws-sdk/util-user-agent-browser": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.598.0.tgz", - "integrity": "sha512-36Sxo6F+ykElaL1mWzWjlg+1epMpSe8obwhCN1yGE7Js9ywy5U6k6l+A3q3YM9YRbm740sNxncbwLklMvuhTKw==", + "version": "3.609.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.609.0.tgz", + "integrity": "sha512-fojPU+mNahzQ0YHYBsx0ZIhmMA96H+ZIZ665ObU9tl+SGdbLneVZVikGve+NmHTQwHzwkFsZYYnVKAkreJLAtA==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/types": "^3.3.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -51180,13 +51190,13 @@ } }, "@aws-sdk/util-user-agent-node": { - "version": "3.598.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.598.0.tgz", - "integrity": "sha512-oyWGcOlfTdzkC6SVplyr0AGh54IMrDxbhg5RxJ5P+V4BKfcDoDcZV9xenUk9NsOi9MuUjxMumb9UJGkDhM1m0A==", + "version": "3.614.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.614.0.tgz", + "integrity": "sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==", "requires": { - "@aws-sdk/types": "3.598.0", - "@smithy/node-config-provider": "^3.1.1", - "@smithy/types": "^3.1.0", + "@aws-sdk/types": "3.609.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -55548,13 +55558,13 @@ "@mongodb-js/atlas-service": { "version": "file:packages/atlas-service", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", "@mongodb-js/devtools-connect": "^3.0.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/oidc-plugin": "^1.0.0", "@mongodb-js/prettier-config-compass": "^1.0.2", @@ -55564,12 +55574,12 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "mocha": "^10.2.0", "node-fetch": "^2.7.0", @@ -55580,7 +55590,7 @@ "redux": "^4.2.1", "redux-thunk": "^2.4.2", "sinon": "^9.2.3", - "system-ca": "^1.0.2", + "system-ca": "^2.0.0", "typescript": "^5.0.4" }, "dependencies": { @@ -55623,25 +55633,26 @@ "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", - "@mongodb-js/explain-plan-helper": "^1.1.13", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", + "@mongodb-js/explain-plan-helper": "^1.1.14", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-constants": "^0.10.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -55650,24 +55661,23 @@ "@types/semver": "^7.3.9", "bson": "^6.7.0", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "ejson-shell-parser": "^2.0.1", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "mongodb-schema": "^12.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -55714,11 +55724,11 @@ "@mongodb-js/compass-app-stores": { "version": "file:packages/compass-app-stores", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -55731,11 +55741,11 @@ "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -55770,15 +55780,16 @@ "@mongodb-js/compass-collection": { "version": "file:packages/compass-collection", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", + "@mongodb-js/mongodb-constants": "^0.10.2", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", @@ -55791,13 +55802,13 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", - "mongodb-collection-model": "^5.21.1", + "mongodb-collection-model": "^5.22.1", "mongodb-ns": "^2.4.2", "numeral": "^2.0.6", "nyc": "^15.1.0", @@ -55885,7 +55896,7 @@ "@leafygreen-ui/tokens": "^2.5.1", "@leafygreen-ui/tooltip": "^11.0.2", "@leafygreen-ui/typography": "^18.2.3", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -55906,7 +55917,7 @@ "chai": "^4.3.4", "eslint": "^7.25.0", "focus-trap-react": "^9.0.2", - "hadron-document": "^8.5.4", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "is-electron-renderer": "^2.0.1", "lodash": "^4.17.21", @@ -55951,10 +55962,10 @@ "@mongodb-js/compass-connection-import-export": { "version": "file:packages/compass-connection-import-export", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -55967,11 +55978,11 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", "gen-esm-wrapper": "^1.1.0", - "hadron-ipc": "^3.2.16", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "mocha": "^10.2.0", "nyc": "^15.1.0", @@ -56009,14 +56020,14 @@ "@mongodb-js/compass-connections": { "version": "file:packages/compass-connections", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56032,16 +56043,16 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.7.0", "chai": "^4.3.4", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-build-info": "^1.7.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "prettier": "^2.7.1", "react": "^17.0.2", @@ -56077,12 +56088,12 @@ "@mongodb-js/compass-connections-navigation": { "version": "file:packages/compass-connections-navigation", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56097,7 +56108,7 @@ "@types/react-window": "^1.8.5", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.4", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -56139,23 +56150,24 @@ "@mongodb-js/compass-crud": { "version": "file:packages/compass-crud", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", - "@mongodb-js/explain-plan-helper": "^1.1.13", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", + "@mongodb-js/explain-plan-helper": "^1.1.14", "@mongodb-js/mocha-config-compass": "^1.3.9", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", - "@mongodb-js/reflux-state-mixin": "^1.0.2", + "@mongodb-js/reflux-state-mixin": "^1.0.3", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -56165,23 +56177,22 @@ "bson": "^6.7.0", "chai": "^4.1.2", "chai-as-promised": "^7.1.1", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "ejson-shell-parser": "^2.0.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "jsondiffpatch": "^0.5.0", "lodash": "^4.17.21", "mocha": "^10.2.0", - "mongodb-data-service": "^22.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "nyc": "^15.1.0", "prop-types": "^15.7.2", "react": "^17.0.2", @@ -56195,36 +56206,35 @@ "@mongodb-js/compass-databases-collections": { "version": "file:packages/databases-collections", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/databases-collections-list": "^1.30.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/databases-collections-list": "^1.33.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", "bson": "^6.7.0", "chai": "^4.2.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "nyc": "^15.1.0", "prop-types": "^15.7.2", "react": "^17.0.2", @@ -56271,8 +56281,8 @@ "@codemirror/state": "^6.1.4", "@codemirror/view": "^6.7.1", "@lezer/highlight": "^1.1.3", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-constants": "^0.10.0", "@mongodb-js/prettier-config-compass": "^1.0.2", @@ -56285,6 +56295,7 @@ "depcheck": "^1.4.1", "eslint": "^7.25.0", "mocha": "^10.2.0", + "mongodb-query-parser": "^4.2.0", "nyc": "^15.1.0", "polished": "^4.2.2", "prettier": "^2.7.1", @@ -56320,14 +56331,14 @@ "@mongodb-js/compass-explain-plan": { "version": "file:packages/compass-explain-plan", "requires": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", - "@mongodb-js/explain-plan-helper": "^1.1.13", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", + "@mongodb-js/explain-plan-helper": "^1.1.14", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56336,15 +56347,15 @@ "@types/d3-flextree": "^2.1.0", "@types/d3-hierarchy": "^3.1.2", "chai": "^4.2.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "d3": "^3.5.17", "d3-flextree": "^2.1.2", "d3-hierarchy": "^3.1.2", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", @@ -56390,26 +56401,26 @@ "@mongodb-js/compass-export-to-language": { "version": "file:packages/compass-export-to-language", "requires": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", - "bson-transpilers": "^3.0.4", + "bson-transpilers": "^3.0.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "ejson-shell-parser": "^2.0.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", @@ -56448,8 +56459,8 @@ "@mongodb-js/compass-field-store": { "version": "file:packages/compass-field-store", "requires": { - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56462,7 +56473,7 @@ "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-schema": "^12.2.0", @@ -56501,8 +56512,8 @@ "@mongodb-js/compass-find-in-page": { "version": "file:packages/compass-find-in-page", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56516,11 +56527,11 @@ "@types/sinon-chai": "^3.2.5", "chai": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "mocha": "^10.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -56561,13 +56572,14 @@ "@mongodb-js/compass-generative-ai": { "version": "file:packages/compass-generative-ai", "requires": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-intercom": "^0.7.1", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-intercom": "^0.9.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -56581,14 +56593,13 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.7.0", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "decomment": "^0.9.5", "depcheck": "^1.4.1", "digest-fetch": "^2.0.3", - "ejson-shell-parser": "^2.0.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", "mongodb": "^6.7.0", "mongodb-runner": "^5.6.2", @@ -56662,15 +56673,15 @@ "version": "file:packages/compass-import-export", "requires": { "@electron/remote": "^2.1.2", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56689,21 +56700,21 @@ "bson": "^6.7.0", "chai": "^4.3.6", "chai-as-promised": "^7.1.1", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "mongodb-schema": "^12.2.0", "nyc": "^15.1.0", "papaparse": "^5.3.2", @@ -56747,37 +56758,37 @@ "@mongodb-js/compass-indexes": { "version": "file:packages/compass-indexes", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-constants": "^0.10.0", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", "bson": "^6.7.0", "chai": "^4.2.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "ejson-shell-parser": "^2.0.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", - "mongodb-data-service": "^22.21.1", - "mongodb-query-parser": "^4.1.2", + "mongodb-data-service": "^22.22.1", + "mongodb-query-parser": "^4.2.0", "numeral": "^2.0.6", "nyc": "^15.1.0", "react": "^17.0.2", @@ -56823,8 +56834,8 @@ "@mongodb-js/compass-intercom": { "version": "file:packages/compass-intercom", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56832,7 +56843,7 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", "gen-esm-wrapper": "^1.1.0", @@ -56926,7 +56937,7 @@ "@mongodb-js/compass-logging": { "version": "file:packages/compass-logging", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56938,8 +56949,8 @@ "debug": "^4.3.4", "depcheck": "^1.4.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "is-electron-renderer": "^2.0.1", "mocha": "^10.2.0", "mongodb-log-writer": "^1.4.2", @@ -56977,7 +56988,7 @@ "@mongodb-js/compass-maybe-protect-connection-string": { "version": "file:packages/compass-maybe-protect-connection-string", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56985,7 +56996,7 @@ "@types/mocha": "^9.0.0", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", "gen-esm-wrapper": "^1.1.0", @@ -57024,20 +57035,20 @@ "@mongodb-js/compass-query-bar": { "version": "file:packages/compass-query-bar", "requires": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-constants": "^0.10.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", @@ -57045,19 +57056,19 @@ "@testing-library/user-event": "^13.5.0", "bson": "^6.7.0", "chai": "^4.2.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", - "mongodb-query-util": "^2.2.3", + "mongodb-query-parser": "^4.2.0", + "mongodb-query-util": "^2.2.4", "mongodb-schema": "^12.2.0", "nyc": "^15.1.0", "react": "^17.0.2", @@ -57095,18 +57106,18 @@ "@mongodb-js/compass-saved-aggregations-queries": { "version": "file:packages/compass-saved-aggregations-queries", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", @@ -57120,12 +57131,12 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.7.0", "chai": "^4.3.4", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "fuse.js": "^6.5.3", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", @@ -57167,19 +57178,19 @@ "@mongodb-js/compass-schema": { "version": "file:packages/compass-schema", "requires": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", - "@mongodb-js/reflux-state-mixin": "^1.0.2", + "@mongodb-js/reflux-state-mixin": "^1.0.3", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -57191,13 +57202,13 @@ "@types/react-dom": "^17.0.10", "bson": "^6.7.0", "chai": "^4.3.4", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "d3": "^3.5.17", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "leaflet": "^1.5.1", "leaflet-defaulticon-compatibility": "^0.1.1", "leaflet-draw": "^1.0.4", @@ -57205,7 +57216,7 @@ "mocha": "^10.2.0", "moment": "^2.29.4", "mongodb": "^6.7.0", - "mongodb-query-util": "^2.2.3", + "mongodb-query-util": "^2.2.4", "mongodb-schema": "^12.2.0", "numeral": "^1.5.6", "nyc": "^15.1.0", @@ -57245,35 +57256,35 @@ "@mongodb-js/compass-schema-validation": { "version": "file:packages/compass-schema-validation", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "bson": "^6.7.0", "chai": "^4.2.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "javascript-stringify": "^2.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "nyc": "^15.1.0", "prop-types": "^15.7.2", "react": "^17.0.2", @@ -57290,12 +57301,12 @@ "version": "file:scripts", "requires": { "@babel/core": "^7.24.3", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/monorepo-tools": "^1.1.1", "@mongodb-js/prettier-config-compass": "^1.0.2", "commander": "^11.0.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "jsdom": "^21.1.0", "make-fetch-happen": "^8.0.14", @@ -57491,12 +57502,12 @@ "@mongodb-js/compass-serverstats": { "version": "file:packages/compass-serverstats", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57510,7 +57521,7 @@ "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb-ns": "^2.4.2", @@ -57538,11 +57549,11 @@ "@mongodb-js/compass-settings": { "version": "file:packages/compass-settings", "requires": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57555,12 +57566,12 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "mocha": "^10.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -57601,36 +57612,37 @@ "@mongodb-js/compass-shell": { "version": "file:packages/compass-shell", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongosh/browser-repl": "^2.2.10", - "@mongosh/logging": "^2.2.10", - "@mongosh/node-runtime-worker-thread": "^2.2.10", + "@mongosh/browser-repl": "^2.2.12", + "@mongosh/logging": "^2.2.12", + "@mongosh/node-runtime-worker-thread": "^2.2.12", + "bson": "^6.7.0", "chai": "^4.2.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", "nyc": "^15.1.0", - "prop-types": "^15.7.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", + "redux-thunk": "^2.4.2", "sinon": "^9.2.3", "typescript": "^5.0.4" }, @@ -57660,19 +57672,19 @@ "@mongodb-js/compass-sidebar": { "version": "file:packages/compass-sidebar", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connection-import-export": "^0.29.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-connections-navigation": "^1.32.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connection-import-export": "^0.32.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-connections-navigation": "^1.35.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57686,17 +57698,17 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", - "mongodb-data-service": "^22.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -57746,8 +57758,8 @@ "@mongodb-js/compass-telemetry": { "version": "file:packages/compass-telemetry", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57758,8 +57770,8 @@ "depcheck": "^1.4.1", "eslint": "^7.25.0", "gen-esm-wrapper": "^1.1.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "mocha": "^10.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -57852,7 +57864,7 @@ "@mongodb-js/compass-test-server": { "version": "file:packages/compass-test-server", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57894,9 +57906,9 @@ "@mongodb-js/compass-user-data": { "version": "file:packages/compass-user-data", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57957,7 +57969,7 @@ "version": "file:packages/compass-utils", "requires": { "@electron/remote": "^2.1.2", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57966,7 +57978,7 @@ "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "gen-esm-wrapper": "^1.1.0", "mocha": "^10.2.0", @@ -58003,32 +58015,32 @@ "@mongodb-js/compass-web": { "version": "file:packages/compass-web", "requires": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-aggregations": "^9.35.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-databases-collections": "^1.32.0", - "@mongodb-js/compass-explain-plan": "^6.33.0", - "@mongodb-js/compass-export-to-language": "^9.9.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-indexes": "^5.32.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-schema": "^6.34.0", - "@mongodb-js/compass-schema-validation": "^6.33.0", - "@mongodb-js/compass-sidebar": "^5.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-aggregations": "^9.38.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-databases-collections": "^1.35.0", + "@mongodb-js/compass-explain-plan": "^6.36.0", + "@mongodb-js/compass-export-to-language": "^9.12.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-indexes": "^5.35.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-schema": "^6.37.0", + "@mongodb-js/compass-schema-validation": "^6.36.0", + "@mongodb-js/compass-sidebar": "^5.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/webpack-config-compass": "^1.3.11", + "@mongodb-js/webpack-config-compass": "^1.3.13", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", "@testing-library/user-event": "^13.5.0", @@ -58043,23 +58055,23 @@ "bson": "^6.2.0", "buffer": "^6.0.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "crypto-browserify": "^3.12.0", "debug": "^4.3.4", "depcheck": "^1.4.1", "dns-query": "^0.11.2", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "events": "^3.3.0", "express": "^4.19.2", "express-http-proxy": "^2.0.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "is-ip": "^5.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", @@ -58259,11 +58271,11 @@ "@mongodb-js/compass-welcome": { "version": "file:packages/compass-welcome", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -58276,11 +58288,11 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -58320,11 +58332,11 @@ "@mongodb-js/compass-workspaces": { "version": "file:packages/compass-workspaces", "requires": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -58342,11 +58354,11 @@ "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mocha": "^10.2.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -58472,12 +58484,13 @@ "@mongodb-js/connection-form": { "version": "file:packages/connection-form", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/shell-bson-parser": "^1.1.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", @@ -58490,9 +58503,8 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.7.0", "chai": "^4.3.4", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "ejson-shell-parser": "^2.0.1", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "lodash": "^4.17.21", @@ -58500,8 +58512,8 @@ "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", - "mongodb-query-parser": "^4.1.2", + "mongodb-data-service": "^22.22.1", + "mongodb-query-parser": "^4.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", "react": "^17.0.2", @@ -58537,7 +58549,7 @@ "@mongodb-js/connection-info": { "version": "file:packages/connection-info", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -58553,7 +58565,7 @@ "mocha": "^10.2.0", "mongodb": "^6.7.0", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "prettier": "^2.7.1", "sinon": "^17.0.1", @@ -58663,12 +58675,12 @@ "@mongodb-js/connection-storage": { "version": "file:packages/connection-storage", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -58677,12 +58689,12 @@ "@types/sinon-chai": "^3.2.5", "bson": "^6.7.0", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "keytar": "^7.9.0", "lodash": "^4.17.21", "mocha": "^10.2.0", @@ -58719,9 +58731,12 @@ "@mongodb-js/databases-collections-list": { "version": "file:packages/databases-collections-list", "requires": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -58734,10 +58749,11 @@ "@types/react-dom": "^17.0.10", "@types/sinon-chai": "^3.2.5", "chai": "^4.3.4", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", "mocha": "^10.2.0", + "mongodb-ns": "^2.4.2", "nyc": "^15.1.0", "prettier": "^2.7.1", "react": "^17.0.2", @@ -58771,9 +58787,9 @@ } }, "@mongodb-js/devtools-connect": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.0.1.tgz", - "integrity": "sha512-xbk/eGHPQTQz4VSpGb5oRqSSbzipcFDODrAc4YtYFrb0980buOAopO71NozCbQoVnoiO1pYVIqcnrZMHkdaJzg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.0.2.tgz", + "integrity": "sha512-wBxbMQ4Ny2V1lCI/Or4e0NUpTX4E2DkEEkehzs3c2MF9uDtf9iWZm5edDjY4A9WhCD4GQ15UlGAQBf+wBN/TLQ==", "requires": { "@mongodb-js/oidc-http-server-pages": "1.1.1", "kerberos": "^2.1.0", @@ -58783,7 +58799,7 @@ "os-dns-native": "^1.2.0", "resolve-mongodb-srv": "^1.1.1", "socks": "^2.7.3", - "system-ca": "^1.0.2" + "system-ca": "^2.0.0" } }, "@mongodb-js/devtools-docker-test-envs": { @@ -59065,7 +59081,7 @@ "@mongodb-js/explain-plan-helper": { "version": "file:packages/explain-plan-helper", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -59154,9 +59170,9 @@ } }, "@mongodb-js/mongodb-constants": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-constants/-/mongodb-constants-0.10.1.tgz", - "integrity": "sha512-zs6LSjci2JwkEgc43nmwI4LM0fYRnJpID2tw1NJ2IlqpmW9x1dQFjv1IG401yPr+eoB+Ktzy+EezDrTKl1fMbA==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@mongodb-js/mongodb-constants/-/mongodb-constants-0.10.2.tgz", + "integrity": "sha512-ss0c6IxhSJZwDiY18We3vjFwrCL+1HJntMInFSthJ6oM61yiCCz5m8TfUjNGJQCXhPqok7sM9RSRcKrn43u0cg==", "requires": { "semver": "^7.5.4" } @@ -59285,9 +59301,9 @@ "@mongodb-js/my-queries-storage": { "version": "file:packages/my-queries-storage", "requires": { - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -59299,7 +59315,7 @@ "depcheck": "^1.4.1", "eslint": "^7.25.0", "gen-esm-wrapper": "^1.1.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mocha": "^10.2.0", "nyc": "^15.1.0", "prettier": "^2.7.1", @@ -59437,7 +59453,7 @@ "@mongodb-js/reflux-state-mixin": { "version": "file:packages/reflux-state-mixin", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -59639,6 +59655,14 @@ } } }, + "@mongodb-js/shell-bson-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mongodb-js/shell-bson-parser/-/shell-bson-parser-1.1.0.tgz", + "integrity": "sha512-zcTFBRrAiKLOhc2MJSmzAB5FlqN0kL5bXi1ehTg1MXvCT61lvWssiK7EWvwPd3mIUTI9NSjEfdDessS8dMxA1w==", + "requires": { + "acorn": "^8.1.0" + } + }, "@mongodb-js/signing-utils": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@mongodb-js/signing-utils/-/signing-utils-0.3.1.tgz", @@ -59652,8 +59676,8 @@ "@mongodb-js/ssh-tunnel": { "version": "file:packages/ssh-tunnel", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -59736,7 +59760,7 @@ "@babel/preset-typescript": "^7.21.4", "@babel/runtime": "^7.21.0", "@cerner/duplicate-package-checker-webpack-plugin": "^2.1.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.5", @@ -59746,15 +59770,16 @@ "@types/webpack-bundle-analyzer": "^4.4.1", "babel-loader": "^8.2.5", "babel-plugin-istanbul": "^5.2.0", - "browserslist": "^4.23.1", + "browserslist": "^4.23.2", "chalk": "^4.1.2", "cli-progress": "^3.9.1", "core-js": "^3.17.3", "css-loader": "^4.3.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "html-webpack-plugin": "^5.3.2", + "less": "^3.13.1", "less-loader": "^10.0.1", "mini-css-extract-plugin": "^2.3.0", "node-loader": "^2.0.0", @@ -59830,6 +59855,22 @@ } } }, + "browserslist": { + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "requires": { + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.1.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001641", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz", + "integrity": "sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==" + }, "connect-history-api-fallback": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", @@ -59843,6 +59884,11 @@ "execa": "^5.0.0" } }, + "electron-to-chromium": { + "version": "1.4.823", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.823.tgz", + "integrity": "sha512-4h+oPeAiGQOHFyUJOqpoEcPj/xxlicxBzOErVeYVMMmAiXUXsGpsFd0QXBMaUUbnD8hhSfLf9uw+MlsoIA7j5w==" + }, "find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -59977,6 +60023,15 @@ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.2.1.tgz", "integrity": "sha512-1k9ZosJCRFaRbY6hH49JFlRB0fVSbmnyq1iTPjNxUmGVjBNEmwrrHPenhlp+Lgo51BojHSf6pl2FcqYaN3PfVg==" }, + "update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "requires": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + } + }, "webpack-dev-middleware": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", @@ -60108,19 +60163,19 @@ } }, "@mongosh/arg-parser": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/arg-parser/-/arg-parser-2.2.10.tgz", - "integrity": "sha512-QvXziAmACrFty7id5I0s3ZOetIc1wWhjtpytGMtchEiusTQOO+NJy74UMrxK+NGxKPDRL0MroRIo05/LEfPkJg==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/arg-parser/-/arg-parser-2.2.12.tgz", + "integrity": "sha512-JayM6b5QnSMopt484MMD3u9uPtjNLlmTNlkbBSYxtTYpvom2WHGdrHmb1dQ50cPZ6sidH5aQ25MlzyYxcaopxQ==", "requires": { - "@mongosh/errors": "2.2.10", - "@mongosh/i18n": "2.2.10", + "@mongosh/errors": "2.2.12", + "@mongosh/i18n": "2.2.12", "mongodb-connection-string-url": "^3.0.1" } }, "@mongosh/async-rewriter2": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/async-rewriter2/-/async-rewriter2-2.2.10.tgz", - "integrity": "sha512-ssY+WxY/oOHPZAIjrYzUYhCr1K2towzshxQpYw3nk5JyjTdvN4gc0xnrWMNLJonEOD/ADTdlneFshQhuh/V1vQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/async-rewriter2/-/async-rewriter2-2.2.12.tgz", + "integrity": "sha512-BNZYYpfLiiX+Z+9Svf0OtxuW6lHCvdn4rjSZkdOgUQMYI93I897aW3HmDRhde5yMF/QMaT7STBjmBvC2TXAkCQ==", "requires": { "@babel/core": "^7.22.8", "@babel/plugin-transform-destructuring": "^7.22.5", @@ -60169,26 +60224,26 @@ } }, "@mongosh/autocomplete": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/autocomplete/-/autocomplete-2.2.10.tgz", - "integrity": "sha512-iLrZ1vfA67jKwEWtSKGYAZ7QM5beYFo4AsmiV+KCXwtcZref3dX1OgcjBvRW8dRvSonz8/7RnN9r8QtsTyw2xw==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/autocomplete/-/autocomplete-2.2.12.tgz", + "integrity": "sha512-LFB4eFN2jH9q6ZAN3kt3ZdKjLBNJ8dqgagKV3IDM6gc9bQRxaI53MUWDxwUqA0xLFLLe7nchjmlQqOgo6nvH1g==", "requires": { "@mongodb-js/mongodb-constants": "^0.10.1", - "@mongosh/shell-api": "2.2.10", + "@mongosh/shell-api": "2.2.12", "semver": "^7.5.4" } }, "@mongosh/browser-repl": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/browser-repl/-/browser-repl-2.2.10.tgz", - "integrity": "sha512-h5Kf806rarRxb5nN1unUlzQG73bAU/jJeG/DC13MQ4YeFipcN0b4KOKXbNUkRK2zgyFjlOyf9TBTUiK0sUDYOQ==", - "requires": { - "@mongosh/browser-runtime-core": "2.2.10", - "@mongosh/errors": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/i18n": "2.2.10", - "@mongosh/node-runtime-worker-thread": "2.2.10", - "@mongosh/service-provider-core": "2.2.10", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/browser-repl/-/browser-repl-2.2.12.tgz", + "integrity": "sha512-8AMA0mZvdeWjqBkUrwbd30nbKlyMT7KPElv8JzkcaCr+G0SsqGU8vi/TeoMA1MnxPQT5sloPOjOm8AfJAna4Og==", + "requires": { + "@mongosh/browser-runtime-core": "2.2.12", + "@mongosh/errors": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/i18n": "2.2.12", + "@mongosh/node-runtime-worker-thread": "2.2.12", + "@mongosh/service-provider-core": "2.2.12", "numeral": "^2.0.6", "text-table": "^0.2.0" }, @@ -60201,67 +60256,67 @@ } }, "@mongosh/browser-runtime-core": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/browser-runtime-core/-/browser-runtime-core-2.2.10.tgz", - "integrity": "sha512-tN2TwbA/ANuZllWBQaZPYKjGS4M+F8UbPkHS7b08DeixbJB457Dh2HNDXztmADuLPht82DurRxx6nS0suNFNXQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/browser-runtime-core/-/browser-runtime-core-2.2.12.tgz", + "integrity": "sha512-sBqFKyU37FIf+TSyLCPKfRYEE1RmBNbxyDii4Wa3vlA2CHR3PZwagpenf8LwIUp7iYiyd34f+mvfxAHouW/MNg==", "requires": { - "@mongosh/autocomplete": "2.2.10", - "@mongosh/service-provider-core": "2.2.10", - "@mongosh/shell-api": "2.2.10", - "@mongosh/shell-evaluator": "2.2.10" + "@mongosh/autocomplete": "2.2.12", + "@mongosh/service-provider-core": "2.2.12", + "@mongosh/shell-api": "2.2.12", + "@mongosh/shell-evaluator": "2.2.12" } }, "@mongosh/errors": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/errors/-/errors-2.2.10.tgz", - "integrity": "sha512-jR8dv9MYYRwr+Yri/KI6HAuob0zdVBQOrMvjc+ygBbTIkL3wh1iOrjZKZuYUsjei1FDxLA8NywftAoHDchq2Tg==" + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/errors/-/errors-2.2.12.tgz", + "integrity": "sha512-7Ns3xOFXhQil99wmU5HAC+GzJljzWV1X5a5khdCU/xq2oRKNJc92JGJMRfG6MK8YXB8rhkjYBoqssPdBaeE5gA==" }, "@mongosh/history": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/history/-/history-2.2.10.tgz", - "integrity": "sha512-EmMKvsytTXq/1tAwxZUvl+6+gCrarWdEDB9mO9vTCFneOgB0ao2jpo7KA9Jc63r8RYhDH78dtjFsSuFeox3AiA==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/history/-/history-2.2.12.tgz", + "integrity": "sha512-JcNSwB/HnVK2RJRJY3MwtTNuWA9aeXWY5mc+wNYYIQ77dXtrphXpIxzSaLL0EXMrQZQBeCibxoYzBFZx4n2jFg==", "requires": { "mongodb-connection-string-url": "^3.0.1", - "mongodb-redact": "^0.2.3" + "mongodb-redact": "^1.1.0" } }, "@mongosh/i18n": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/i18n/-/i18n-2.2.10.tgz", - "integrity": "sha512-TxyFOhdXqCN0AXGcWziPzZ+YBf8KthnZIbOVSyA+C1a0jynfMf+XBnLnNpwvKfGZUeQ1VyZkrKLPopG7e2nuIA==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/i18n/-/i18n-2.2.12.tgz", + "integrity": "sha512-2A59O56WG/fwtNs0VjS/tvsen0MKXSHCSn9w51PGbdLYFCD8RQUetPSSfLcEuqlsXn88NDFsiQbkSsRo4sEMXw==", "requires": { - "@mongosh/errors": "2.2.10" + "@mongosh/errors": "2.2.12" } }, "@mongosh/logging": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/logging/-/logging-2.2.10.tgz", - "integrity": "sha512-0z3L23rtaASh1E2hV/wSWxDTycxktbD2XVUnSW1YbyRfePd7YOwVeUhNeFYUf1Qq2q2KeTdxgMaP5/BodY+h5A==", - "requires": { - "@mongodb-js/devtools-connect": "^3.0.1", - "@mongosh/errors": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/types": "2.2.10", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/logging/-/logging-2.2.12.tgz", + "integrity": "sha512-fSBO0dLfzRQ0ZtflKqWwDLLWn6t7ZYjUBCsDIpTVhvJlexvZQ/71izD3yEN4k2MRZyTFiTM5lYGURSqTldppNA==", + "requires": { + "@mongodb-js/devtools-connect": "^3.0.2", + "@mongosh/errors": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/types": "2.2.12", "mongodb-log-writer": "^1.4.2", - "mongodb-redact": "^0.2.3" + "mongodb-redact": "^1.1.0" } }, "@mongosh/node-runtime-worker-thread": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/node-runtime-worker-thread/-/node-runtime-worker-thread-2.2.10.tgz", - "integrity": "sha512-u1S455FA5/wLw2/Izfmpaw7XOsDYmXe0BYolEAHHiuEt1wTQ6A7b9qs8rjwA/yXN15SbL7BMYHnv4fLVQhEO7w==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/node-runtime-worker-thread/-/node-runtime-worker-thread-2.2.12.tgz", + "integrity": "sha512-hqaW/1MziELPFcJJEQnXblHa6ueI6kbGUju/tbYkaY8x+vJVic2Fobd71Mx66awJwIuI7zmjOq0HE6UkKdZ2jw==", "requires": { "interruptor": "^1.0.1", - "system-ca": "^1.0.3" + "system-ca": "^2.0.0" } }, "@mongosh/service-provider-core": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/service-provider-core/-/service-provider-core-2.2.10.tgz", - "integrity": "sha512-XB+G24WjTIYXnHoToJhDJMwMV7pCcgCwgme0MiE6lzcYs5HwlHhk9tzBwv0+i+3NcCb5SMqU38iUMuGG6jKJdQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/service-provider-core/-/service-provider-core-2.2.12.tgz", + "integrity": "sha512-pYd2KKlNFn/6fn9w5vSlkFUUkKoK8F+UAhy8TqjfYBA9cSQKLD+Et5qClC09APIAcVyk0Xd66n7KHG0Qb0vaxA==", "requires": { "@aws-sdk/credential-providers": "^3.525.0", - "@mongosh/errors": "2.2.10", + "@mongosh/errors": "2.2.12", "bson": "^6.7.0", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", @@ -60269,34 +60324,34 @@ } }, "@mongosh/shell-api": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/shell-api/-/shell-api-2.2.10.tgz", - "integrity": "sha512-Cgcb0U5wqzmTmwAmMkSqhZ3fR4PjqNJ2px61i/9JzWAgIEDSbv9Xni3mcfDRQd/qjLHCEUlAPFgEBu7Cpk0qBQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/shell-api/-/shell-api-2.2.12.tgz", + "integrity": "sha512-sjy6di7W5h0MbQ4lPXYOModwSnebiwWYDJVv6wtj9TvCz8Bua19fIr9jnW4GTjA/MLaWO0DjYh6MFg34SqvoLQ==", "requires": { - "@mongosh/arg-parser": "2.2.10", - "@mongosh/errors": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/i18n": "2.2.10", - "@mongosh/service-provider-core": "2.2.10", - "mongodb-redact": "^0.2.3" + "@mongosh/arg-parser": "2.2.12", + "@mongosh/errors": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/i18n": "2.2.12", + "@mongosh/service-provider-core": "2.2.12", + "mongodb-redact": "^1.1.0" } }, "@mongosh/shell-evaluator": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/shell-evaluator/-/shell-evaluator-2.2.10.tgz", - "integrity": "sha512-9v/p5WDu+Ur7+jhXajkBOvpINcRORA1UpdMOV4sBGQ623VbmoDd7xFeFPoi0uWzV50qW5yNRlh3+dvsG/jdKmQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/shell-evaluator/-/shell-evaluator-2.2.12.tgz", + "integrity": "sha512-oSxx996l1vumeBDNZ2XYOWSmbPKA5b1XLL9YEFpsS27WLnxwvBiAb2qu6pJ8fDmJh9nDDAkWP5jlf2zYBitByA==", "requires": { - "@mongosh/async-rewriter2": "2.2.10", - "@mongosh/history": "2.2.10", - "@mongosh/shell-api": "2.2.10" + "@mongosh/async-rewriter2": "2.2.12", + "@mongosh/history": "2.2.12", + "@mongosh/shell-api": "2.2.12" } }, "@mongosh/types": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@mongosh/types/-/types-2.2.10.tgz", - "integrity": "sha512-BfCcmbC3givNCgYZxf6aUJy+/nHg2By6Hs9gZ/WMGgiedMuL5fRE18dGlwy3Aog7Jc6tVkBCMtOpYgjVnUPoxQ==", + "version": "2.2.12", + "resolved": "https://registry.npmjs.org/@mongosh/types/-/types-2.2.12.tgz", + "integrity": "sha512-19LPOUVDy1FE01U6CvOjplv5U8prY0RZa3Cf0QSTpHQlnzWcrzMIHqPWS3luXFwGSKhQU/GxFfEJesqdE8C7HQ==", "requires": { - "@mongodb-js/devtools-connect": "^3.0.1" + "@mongodb-js/devtools-connect": "^3.0.2" } }, "@nicolo-ribaudo/eslint-scope-5-internals": { @@ -62740,11 +62795,11 @@ "dev": true }, "@smithy/abort-controller": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.0.tgz", - "integrity": "sha512-XOm4LkuC0PsK1sf2bBJLIlskn5ghmVxiEBVlo/jg0R8hxASBKYYgOoJEhKWgOr4vWGkN+5rC+oyBAqHYtxjnwQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.1.tgz", + "integrity": "sha512-MBJBiidoe+0cTFhyxT8g+9g7CeVccLM0IOKKUMCNQ1CNMJ/eIfoo0RTfVrXOONEI1UCN1W+zkiHSbzUNE9dZtQ==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -62756,14 +62811,14 @@ } }, "@smithy/config-resolver": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.3.tgz", - "integrity": "sha512-4wHqCMkdfVDP4qmr4fVPYOFOH+vKhOv3X4e6KEU9wIC8xXUQ24tnF4CW+sddGDX1zU86GGyQ7A+rg2xmUD6jpQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.5.tgz", + "integrity": "sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==", "requires": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/types": "^3.2.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "@smithy/util-config-provider": "^3.0.0", - "@smithy/util-middleware": "^3.0.2", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "dependencies": { @@ -62775,17 +62830,17 @@ } }, "@smithy/core": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.3.tgz", - "integrity": "sha512-SpyLOL2vgE6sUYM6nQfu82OirCPkCDKctyG3aMgjMlDPTJpUlmlNH0ttu9ZWwzEjrzzr8uABmPjJTRI7gk1HFQ==", - "requires": { - "@smithy/middleware-endpoint": "^3.0.3", - "@smithy/middleware-retry": "^3.0.6", - "@smithy/middleware-serde": "^3.0.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "@smithy/util-middleware": "^3.0.2", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.2.6.tgz", + "integrity": "sha512-tBbVIv/ui7/lLTKayYJJvi8JLVL2SwOQTbNFEOrvzSE3ktByvsa1erwBOnAMo8N5Vu30g7lN4lLStrU75oDGuw==", + "requires": { + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-retry": "^3.0.9", + "@smithy/middleware-serde": "^3.0.3", + "@smithy/protocol-http": "^4.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "dependencies": { @@ -62797,14 +62852,14 @@ } }, "@smithy/credential-provider-imds": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.2.tgz", - "integrity": "sha512-gqVmUaNoeqyrOAjgZg+rTmFLsphh/vS59LCMdFfVpthVS0jbfBzvBmEPktBd+y9ME4DYMGHFAMSYJDK8q0noOQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.1.4.tgz", + "integrity": "sha512-NKyH01m97Xa5xf3pB2QOF3lnuE8RIK0hTVNU5zvZAwZU8uspYO4DHQVlK+Y5gwSrujTfHvbfd1D9UFJAc0iYKQ==", "requires": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/property-provider": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/url-parser": "^3.0.2", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", "tslib": "^2.6.2" }, "dependencies": { @@ -62816,13 +62871,13 @@ } }, "@smithy/fetch-http-handler": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.1.0.tgz", - "integrity": "sha512-s7oQjEOUH9TYjctpITtWF4qxOdg7pBrP9eigEQ8SBsxF3dRFV0S28pGMllC83DUr7ECmErhO/BUwnULfoNhKgQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-3.2.1.tgz", + "integrity": "sha512-0w0bgUvZmfa0vHN8a+moByhCJT07WN6AHKEhFSOLsDpnszm+5dLVv5utGaqbhOrZ/aF5x3xuPMs/oMCd+4O5xg==", "requires": { - "@smithy/protocol-http": "^4.0.2", - "@smithy/querystring-builder": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", "@smithy/util-base64": "^3.0.0", "tslib": "^2.6.2" }, @@ -62835,11 +62890,11 @@ } }, "@smithy/hash-node": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.2.tgz", - "integrity": "sha512-43uGA6o6QJQdXwAogybdTDHDd3SCdKyoiHIHb8PpdE2rKmVicjG9b1UgVwdgO8QPytmVqHFaUw27M3LZKwu8Yg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.3.tgz", + "integrity": "sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -62853,11 +62908,11 @@ } }, "@smithy/invalid-dependency": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.2.tgz", - "integrity": "sha512-+BAY3fMhomtq470tswXyrdVBSUhiLuhBVT+rOmpbz5e04YX+s1dX4NxTLzZGwBjCpeWZNtTxP8zbIvvFk81gUg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.3.tgz", + "integrity": "sha512-ID1eL/zpDULmHJbflb864k72/SNOZCADRc9i7Exq3RUNJw6raWUSlFEQ+3PX3EYs++bTxZB2dE9mEHTQLv61tw==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -62884,12 +62939,12 @@ } }, "@smithy/middleware-content-length": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.2.tgz", - "integrity": "sha512-/Havz3PkYIEmwpqkyRTR21yJsWnFbD1ec4H1pUL+TkDnE7RCQkAVUQepLL/UeCaZeCBXvfdoKbOjSbV01xIinQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.3.tgz", + "integrity": "sha512-Dbz2bzexReYIQDWMr+gZhpwBetNXzbhnEMhYKA6urqmojO14CsXjnsoPYO8UL/xxcawn8ZsuVU61ElkLSltIUQ==", "requires": { - "@smithy/protocol-http": "^4.0.2", - "@smithy/types": "^3.2.0", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -62901,16 +62956,16 @@ } }, "@smithy/middleware-endpoint": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.3.tgz", - "integrity": "sha512-ARAXHodhj4tttKa9y75zvENdSoHq6VGsSi7XS3+yLutrnxttJs6N10UMInCC1yi3/bopT8xug3iOP/y9R6sKJQ==", - "requires": { - "@smithy/middleware-serde": "^3.0.2", - "@smithy/node-config-provider": "^3.1.2", - "@smithy/shared-ini-file-loader": "^3.1.2", - "@smithy/types": "^3.2.0", - "@smithy/url-parser": "^3.0.2", - "@smithy/util-middleware": "^3.0.2", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.0.5.tgz", + "integrity": "sha512-V4acqqrh5tDxUEGVTOgf2lYMZqPQsoGntCrjrJZEeBzEzDry2d2vcI1QCXhGltXPPY+BMc6eksZMguA9fIY8vA==", + "requires": { + "@smithy/middleware-serde": "^3.0.3", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", + "@smithy/url-parser": "^3.0.3", + "@smithy/util-middleware": "^3.0.3", "tslib": "^2.6.2" }, "dependencies": { @@ -62922,17 +62977,17 @@ } }, "@smithy/middleware-retry": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.6.tgz", - "integrity": "sha512-ICsFKp8eAyIMmxN5UT3IU37S6886L879TKtgxPsn/VD/laYNwqTLmJaCAn5//+2fRIrV0dnHp6LFlMwdXlWoUQ==", - "requires": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/service-error-classification": "^3.0.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", - "@smithy/util-middleware": "^3.0.2", - "@smithy/util-retry": "^3.0.2", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.9.tgz", + "integrity": "sha512-Mrv9omExU1gA7Y0VEJG2LieGfPYtwwcEiOnVGZ54a37NEMr66TJ0glFslOJFuKWG6izg5DpKIUmDV9rRxjm47Q==", + "requires": { + "@smithy/node-config-provider": "^3.1.4", + "@smithy/protocol-http": "^4.0.3", + "@smithy/service-error-classification": "^3.0.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", + "@smithy/util-middleware": "^3.0.3", + "@smithy/util-retry": "^3.0.3", "tslib": "^2.6.2", "uuid": "^9.0.1" }, @@ -62950,11 +63005,11 @@ } }, "@smithy/middleware-serde": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.2.tgz", - "integrity": "sha512-oT2abV5zLhBucJe1LIIFEcRgIBDbZpziuMPswTMbBQNcaEUycLFvX63zsFmqfwG+/ZQKsNx+BSE8W51CMuK7Yw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", + "integrity": "sha512-puUbyJQBcg9eSErFXjKNiGILJGtiqmuuNKEYNYfUD57fUl4i9+mfmThtQhvFXU0hCVG0iEJhvQUipUf+/SsFdA==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -62966,11 +63021,11 @@ } }, "@smithy/middleware-stack": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.2.tgz", - "integrity": "sha512-6fRcxomlNKBPIy/YjcnC7YHpMAjRvGUYlYVJAfELqZjkW0vQegNcImjY7T1HgYA6u3pAcCxKVBLYnkTw8z/l0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.3.tgz", + "integrity": "sha512-r4klY9nFudB0r9UdSMaGSyjyQK5adUyPnQN/ZM6M75phTxOdnc/AhpvGD1fQUvgmqjQEBGCwpnPbDm8pH5PapA==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -62982,13 +63037,13 @@ } }, "@smithy/node-config-provider": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.2.tgz", - "integrity": "sha512-388fEAa7+6ORj/BDC70peg3fyFBTTXJyXfXJ0Bwd6FYsRltePr2oGzIcm5AuC1WUSLtZ/dF+hYOnfTMs04rLvA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.4.tgz", + "integrity": "sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==", "requires": { - "@smithy/property-provider": "^3.1.2", - "@smithy/shared-ini-file-loader": "^3.1.2", - "@smithy/types": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/shared-ini-file-loader": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63000,14 +63055,14 @@ } }, "@smithy/node-http-handler": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.0.tgz", - "integrity": "sha512-pOpgB6B+VLXLwAyyvRz+ZAVXABlbAsJ2xvn3WZvrppAPImxwQOPFbeSUzWYMhpC8Tr7yQ3R8fG990QDhskkf1Q==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.1.2.tgz", + "integrity": "sha512-Td3rUNI7qqtoSLTsJBtsyfoG4cF/XMFmJr6Z2dX8QNzIi6tIW6YmuyFml8mJ2cNpyWNqITKbROMOFrvQjmsOvw==", "requires": { - "@smithy/abort-controller": "^3.1.0", - "@smithy/protocol-http": "^4.0.2", - "@smithy/querystring-builder": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/abort-controller": "^3.1.1", + "@smithy/protocol-http": "^4.0.3", + "@smithy/querystring-builder": "^3.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63019,11 +63074,11 @@ } }, "@smithy/property-provider": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.2.tgz", - "integrity": "sha512-Hzp32BpeFFexBpO1z+ts8okbq/VLzJBadxanJAo/Wf2CmvXMBp6Q/TLWr7Js6IbMEcr0pDZ02V3u1XZkuQUJaA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.3.tgz", + "integrity": "sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63035,11 +63090,11 @@ } }, "@smithy/protocol-http": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.2.tgz", - "integrity": "sha512-X/90xNWIOqSR2tLUyWxVIBdatpm35DrL44rI/xoeBWUuanE0iyCXJpTcnqlOpnEzgcu0xCKE06+g70TTu2j7RQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.0.3.tgz", + "integrity": "sha512-x5jmrCWwQlx+Zv4jAtc33ijJ+vqqYN+c/ZkrnpvEe/uDas7AT7A/4Rc2CdfxgWv4WFGmEqODIrrUToPN6DDkGw==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63051,11 +63106,11 @@ } }, "@smithy/querystring-builder": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.2.tgz", - "integrity": "sha512-xhv1+HacDYsOLdNt7zW+8Fe779KYAzmWvzs9bC5NlKM8QGYCwwuFwDBynhlU4D5twgi2pZ14Lm4h6RiAazCtmA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.3.tgz", + "integrity": "sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "@smithy/util-uri-escape": "^3.0.0", "tslib": "^2.6.2" }, @@ -63068,11 +63123,11 @@ } }, "@smithy/querystring-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.2.tgz", - "integrity": "sha512-C5hyRKgrZGPNh5QqIWzXnW+LXVrPmVQO0iJKjHeb5v3C61ZkP9QhrKmbfchcTyg/VnaE0tMNf/nmLpQlWuiqpg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.3.tgz", + "integrity": "sha512-zahM1lQv2YjmznnfQsWbYojFe55l0SLG/988brlLv1i8z3dubloLF+75ATRsqPBboUXsW6I9CPGE5rQgLfY0vQ==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63084,19 +63139,19 @@ } }, "@smithy/service-error-classification": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.2.tgz", - "integrity": "sha512-cu0WV2XRttItsuXlcM0kq5MKdphbMMmSd2CXF122dJ75NrFE0o7rruXFGfxAp3BKzgF/DMxX+PllIA/cj4FHMw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.3.tgz", + "integrity": "sha512-Jn39sSl8cim/VlkLsUhRFq/dKDnRUFlfRkvhOJaUbLBXUsLRLNf9WaxDv/z9BjuQ3A6k/qE8af1lsqcwm7+DaQ==", "requires": { - "@smithy/types": "^3.2.0" + "@smithy/types": "^3.3.0" } }, "@smithy/shared-ini-file-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.2.tgz", - "integrity": "sha512-tgnXrXbLMO8vo6VeuqabMw/eTzQHlLmZx0TC0TjtjJghnD0Xl4pEnJtBjTJr6XF5fHMNrt5BcczDXHJT9yNQnA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.4.tgz", + "integrity": "sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63108,14 +63163,14 @@ } }, "@smithy/signature-v4": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.1.tgz", - "integrity": "sha512-2/vlG86Sr489XX8TA/F+VDA+P04ESef04pSz0wRtlQBExcSPjqO08rvrkcas2zLnJ51i+7ukOURCkgqixBYjSQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-3.1.2.tgz", + "integrity": "sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==", "requires": { "@smithy/is-array-buffer": "^3.0.0", - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "@smithy/util-hex-encoding": "^3.0.0", - "@smithy/util-middleware": "^3.0.2", + "@smithy/util-middleware": "^3.0.3", "@smithy/util-uri-escape": "^3.0.0", "@smithy/util-utf8": "^3.0.0", "tslib": "^2.6.2" @@ -63129,15 +63184,15 @@ } }, "@smithy/smithy-client": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.4.tgz", - "integrity": "sha512-y6xJROGrIoitjpwXLY7P9luDHvuT9jWpAluliuSFdBymFxcl6iyQjo9U/JhYfRHFNTruqsvKOrOESVuPGEcRmQ==", - "requires": { - "@smithy/middleware-endpoint": "^3.0.3", - "@smithy/middleware-stack": "^3.0.2", - "@smithy/protocol-http": "^4.0.2", - "@smithy/types": "^3.2.0", - "@smithy/util-stream": "^3.0.4", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.1.7.tgz", + "integrity": "sha512-nZbJZB0XI3YnaFBWGDBr7kjaew6O0oNYNmopyIz6gKZEbxzrtH7rwvU1GcVxcSFoOwWecLJEe79fxEMljHopFQ==", + "requires": { + "@smithy/middleware-endpoint": "^3.0.5", + "@smithy/middleware-stack": "^3.0.3", + "@smithy/protocol-http": "^4.0.3", + "@smithy/types": "^3.3.0", + "@smithy/util-stream": "^3.0.6", "tslib": "^2.6.2" }, "dependencies": { @@ -63149,9 +63204,9 @@ } }, "@smithy/types": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.2.0.tgz", - "integrity": "sha512-cKyeKAPazZRVqm7QPvcPD2jEIt2wqDPAL1KJKb0f/5I7uhollvsWZuZKLclmyP6a+Jwmr3OV3t+X0pZUUHS9BA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.3.0.tgz", + "integrity": "sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==", "requires": { "tslib": "^2.6.2" }, @@ -63164,12 +63219,12 @@ } }, "@smithy/url-parser": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.2.tgz", - "integrity": "sha512-pRiPHrgibeAr4avtXDoBHmTLtthwA4l8jKYRfZjNgp+bBPyxDMPRg2TMJaYxqbKemvrOkHu9MIBTv2RkdNfD6w==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.3.tgz", + "integrity": "sha512-pw3VtZtX2rg+s6HMs6/+u9+hu6oY6U7IohGhVNnjbgKy86wcIsSZwgHrFR+t67Uyxvp4Xz3p3kGXXIpTNisq8A==", "requires": { - "@smithy/querystring-parser": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/querystring-parser": "^3.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63259,13 +63314,13 @@ } }, "@smithy/util-defaults-mode-browser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.6.tgz", - "integrity": "sha512-tAgoc++Eq+KL7g55+k108pn7nAob3GLWNEMbXhZIQyBcBNaE/o3+r4AEbae0A8bWvLRvArVsjeiuhMykGa04/A==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.9.tgz", + "integrity": "sha512-WKPcElz92MAQG09miBdb0GxEH/MwD5GfE8g07WokITq5g6J1ROQfYCKC1wNnkqAGfrSywT7L0rdvvqlBplqiyA==", "requires": { - "@smithy/property-provider": "^3.1.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", "bowser": "^2.11.0", "tslib": "^2.6.2" }, @@ -63278,16 +63333,16 @@ } }, "@smithy/util-defaults-mode-node": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.6.tgz", - "integrity": "sha512-UNerul6/E8aiCyFTBHk+RSIZCo7m96d/N5K3FeO/wFeZP6oy5HAicLzxqa85Wjv7MkXSxSySX29L/LwTV/QMag==", - "requires": { - "@smithy/config-resolver": "^3.0.3", - "@smithy/credential-provider-imds": "^3.1.2", - "@smithy/node-config-provider": "^3.1.2", - "@smithy/property-provider": "^3.1.2", - "@smithy/smithy-client": "^3.1.4", - "@smithy/types": "^3.2.0", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.9.tgz", + "integrity": "sha512-dQLrUqFxqpf0GvEKEuFdgXcdZwz6oFm752h4d6C7lQz+RLddf761L2r7dSwGWzESMMB3wKj0jL+skRhEGlecjw==", + "requires": { + "@smithy/config-resolver": "^3.0.5", + "@smithy/credential-provider-imds": "^3.1.4", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", + "@smithy/smithy-client": "^3.1.7", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63299,12 +63354,12 @@ } }, "@smithy/util-endpoints": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.3.tgz", - "integrity": "sha512-Dyi+pfLglDHSGsKSYunuUUSFM5V0tz7UDgv1Ex97yg+Xkn0Eb0rH0rcvl1n0MaJ11fac3HKDOH0DkALyQYCQag==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.0.5.tgz", + "integrity": "sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==", "requires": { - "@smithy/node-config-provider": "^3.1.2", - "@smithy/types": "^3.2.0", + "@smithy/node-config-provider": "^3.1.4", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63331,11 +63386,11 @@ } }, "@smithy/util-middleware": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.2.tgz", - "integrity": "sha512-7WW5SD0XVrpfqljBYzS5rLR+EiDzl7wCVJZ9Lo6ChNFV4VYDk37Z1QI5w/LnYtU/QKnSawYoHRd7VjSyC8QRQQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.3.tgz", + "integrity": "sha512-l+StyYYK/eO3DlVPbU+4Bi06Jjal+PFLSMmlWM1BEwyLxZ3aKkf1ROnoIakfaA7mC6uw3ny7JBkau4Yc+5zfWw==", "requires": { - "@smithy/types": "^3.2.0", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63347,12 +63402,12 @@ } }, "@smithy/util-retry": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.2.tgz", - "integrity": "sha512-HUVOb1k8p/IH6WFUjsLa+L9H1Zi/FAAB2CDOpWuffI1b2Txi6sknau8kNfC46Xrt39P1j2KDzCE1UlLa2eW5+A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.3.tgz", + "integrity": "sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==", "requires": { - "@smithy/service-error-classification": "^3.0.2", - "@smithy/types": "^3.2.0", + "@smithy/service-error-classification": "^3.0.3", + "@smithy/types": "^3.3.0", "tslib": "^2.6.2" }, "dependencies": { @@ -63364,13 +63419,13 @@ } }, "@smithy/util-stream": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.4.tgz", - "integrity": "sha512-CcMioiaOOsEVdb09pS7ux1ij7QcQ2jE/cE1+iin1DXMeRgAEQN/47m7Xztu7KFQuQsj0A5YwB2UN45q97CqKCg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.0.6.tgz", + "integrity": "sha512-w9i//7egejAIvplX821rPWWgaiY1dxsQUw0hXX7qwa/uZ9U3zplqTQ871jWadkcVB9gFDhkPWYVZf4yfFbZ0xA==", "requires": { - "@smithy/fetch-http-handler": "^3.1.0", - "@smithy/node-http-handler": "^3.1.0", - "@smithy/types": "^3.2.0", + "@smithy/fetch-http-handler": "^3.2.1", + "@smithy/node-http-handler": "^3.1.2", + "@smithy/types": "^3.3.0", "@smithy/util-base64": "^3.0.0", "@smithy/util-buffer-from": "^3.0.0", "@smithy/util-hex-encoding": "^3.0.0", @@ -67080,7 +67135,7 @@ "bson-transpilers": { "version": "file:packages/bson-transpilers", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "antlr4": "4.7.2", "bson": "^6.2.0", "chai": "^4.3.4", @@ -67827,9 +67882,9 @@ "version": "file:packages/compass-e2e-tests", "requires": { "@electron/rebuild": "^3.6.0", - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/oidc-mock-provider": "^0.9.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -67841,15 +67896,15 @@ "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "clipboardy": "^2.3.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "cross-spawn": "^7.0.3", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "fast-glob": "^3.2.7", "glob": "^10.2.5", - "hadron-build": "^25.5.3", + "hadron-build": "^25.5.5", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", @@ -68041,9 +68096,9 @@ "compass-preferences-model": { "version": "file:packages/compass-preferences-model", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@testing-library/react": "^12.1.5", "@types/js-yaml": "^4.0.5", @@ -68052,8 +68107,8 @@ "chai": "^4.3.6", "depcheck": "^1.4.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "mocha": "^10.2.0", @@ -68430,11 +68485,11 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "copy-anything": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz", - "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", "requires": { - "is-what": "^3.12.0" + "is-what": "^3.14.1" } }, "core-js": { @@ -70249,18 +70304,10 @@ "jake": "^10.8.5" } }, - "ejson-shell-parser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ejson-shell-parser/-/ejson-shell-parser-2.0.1.tgz", - "integrity": "sha512-ZTDIeoRBWSrGgHMYlBn4PymQdtNCsnFUK/cSVwZREPNC3Mr+E3arO08DapVjBVDGTE08kkpqRll1Y+lwe5ZvCQ==", - "requires": { - "acorn": "^8.1.0" - } - }, "electron": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-29.4.3.tgz", - "integrity": "sha512-Fr/D7Iru7zGFK5DtNf3Ck/DBxLHtP/o/32pRXsSoGTVqyHKu2genIiSUiOhbxdu+gQZw4Do+BDDR6inkyr4CGQ==", + "version": "29.4.5", + "resolved": "https://registry.npmjs.org/electron/-/electron-29.4.5.tgz", + "integrity": "sha512-DlEuzGbWBYl1Qr0qUYgNZdoixJg4YGHy2HC6fkRjSXSlb01UrQ5ORi8hNLzelzyYx8rNQyyE3zDUuk9EnZwYuA==", "requires": { "@electron/get": "^2.0.0", "@types/node": "^20.9.0", @@ -72972,40 +73019,6 @@ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" }, - "fs-plus": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-3.1.1.tgz", - "integrity": "sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==", - "requires": { - "async": "^1.5.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2", - "underscore-plus": "1.x" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, "fs-temp": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", @@ -74140,7 +74153,7 @@ "hadron-app-registry": { "version": "file:packages/hadron-app-registry", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -74192,13 +74205,12 @@ "@mongodb-js/devtools-github-repo": "^1.4.1", "@mongodb-js/dl-center": "^1.0.1", "@mongodb-js/electron-wix-msi": "^3.0.0", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/signing-utils": "^0.3.1", "@npmcli/arborist": "^6.2.0", "@octokit/rest": "^18.6.2", "asar": "^3.0.3", "async": "^3.2.2", - "bluebird": "^3.7.2", "chai": "^4.2.0", "chalk": "^4.1.2", "cli-table": "^0.3.1", @@ -74206,7 +74218,7 @@ "del": "^2.0.2", "depcheck": "^1.4.1", "download": "^8.0.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-installer-debian": "^3.2.0", "electron-installer-dmg": "^4.0.0", "electron-installer-redhat": "^2.0.0", @@ -74223,7 +74235,6 @@ "js-yaml": "^4.1.0", "json-diff": "^0.9.0", "jszip": "^3.5.0", - "less-cache": "^1.1.0", "lodash": "^4.17.21", "mocha": "^10.2.0", "moment": "^2.29.4", @@ -74774,7 +74785,7 @@ "hadron-document": { "version": "file:packages/hadron-document", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -74895,7 +74906,7 @@ "hadron-ipc": { "version": "file:packages/hadron-ipc", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -74906,7 +74917,7 @@ "chai": "^4.3.6", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "is-electron-renderer": "^2.0.1", "mocha": "^10.2.0", @@ -78246,7 +78257,7 @@ "image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "optional": true }, "make-dir": { @@ -78279,17 +78290,6 @@ } } }, - "less-cache": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/less-cache/-/less-cache-1.1.1.tgz", - "integrity": "sha512-cl7K2sUMu9m6lNHUd3XV3/C2IF76GOrsck2C9cf81Ymu6wbHrQI6NSJUejfcnR8MttdLpK6XdUYDNe+GDJdqJg==", - "requires": { - "fs-plus": "^3.1.1", - "less": "^3.12.2", - "underscore-plus": "^1.7.0", - "walkdir": "^0.4.1" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -79969,7 +79969,7 @@ "mongodb-collection-model": { "version": "file:packages/collection-model", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "ampersand-collection": "^2.0.2", "ampersand-model": "^8.0.1", @@ -79977,7 +79977,7 @@ "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2", "xvfb-maybe": "^0.2.1" } @@ -79987,48 +79987,48 @@ "requires": { "@electron/rebuild": "^3.6.0", "@electron/remote": "^2.1.2", - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-aggregations": "^9.35.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connection-import-export": "^0.29.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-databases-collections": "^1.32.0", - "@mongodb-js/compass-explain-plan": "^6.33.0", - "@mongodb-js/compass-export-to-language": "^9.9.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-find-in-page": "^4.26.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-import-export": "^7.32.0", - "@mongodb-js/compass-indexes": "^5.32.0", - "@mongodb-js/compass-intercom": "^0.7.1", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-saved-aggregations-queries": "^1.33.0", - "@mongodb-js/compass-schema": "^6.34.0", - "@mongodb-js/compass-schema-validation": "^6.33.0", - "@mongodb-js/compass-serverstats": "^16.32.0", - "@mongodb-js/compass-settings": "^0.34.0", - "@mongodb-js/compass-shell": "^3.32.0", - "@mongodb-js/compass-sidebar": "^5.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-welcome": "^0.31.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-aggregations": "^9.38.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connection-import-export": "^0.32.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-databases-collections": "^1.35.0", + "@mongodb-js/compass-explain-plan": "^6.36.0", + "@mongodb-js/compass-export-to-language": "^9.12.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-find-in-page": "^4.29.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-import-export": "^7.35.0", + "@mongodb-js/compass-indexes": "^5.35.0", + "@mongodb-js/compass-intercom": "^0.9.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-saved-aggregations-queries": "^1.36.0", + "@mongodb-js/compass-schema": "^6.37.0", + "@mongodb-js/compass-schema-validation": "^6.36.0", + "@mongodb-js/compass-serverstats": "^16.35.0", + "@mongodb-js/compass-settings": "^0.37.0", + "@mongodb-js/compass-shell": "^3.35.0", + "@mongodb-js/compass-sidebar": "^5.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-welcome": "^0.34.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/get-os-info": "^0.3.24", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-downloader": "^0.3.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/sbom-tools": "^0.7.0", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/webpack-config-compass": "^1.3.11", - "@mongosh/node-runtime-worker-thread": "^2.2.10", + "@mongodb-js/webpack-config-compass": "^1.3.13", + "@mongosh/node-runtime-worker-thread": "^2.2.12", "@segment/analytics-node": "^1.1.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -80037,19 +80037,19 @@ "chalk": "^4.1.2", "clean-stack": "^2.0.0", "clipboard": "^2.0.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-devtools-installer": "^3.2.0", "electron-dl": "^3.5.0", "electron-mocha": "^12.2.0", "electron-squirrel-startup": "^1.0.1", "ensure-error": "^3.0.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-build": "^25.5.3", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-build": "^25.5.5", + "hadron-ipc": "^3.2.18", "kerberos": "^2.1.0", "keytar": "^7.9.0", "local-links": "^1.4.0", @@ -80061,8 +80061,8 @@ "mongodb-client-encryption": "^6.0.0", "mongodb-cloud-info": "^2.1.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-log-writer": "^1.4.2", "mongodb-ns": "^2.4.2", "node-fetch": "^2.7.0", @@ -80073,10 +80073,10 @@ "semver": "^7.6.2", "sinon": "^8.1.1", "source-code-pro": "^2.38.0", - "system-ca": "^1.0.3", + "system-ca": "^2.0.0", "ts-node": "^10.9.1", "web-vitals": "^2.1.2", - "win-export-certificate-and-key": "^1.1.2", + "win-export-certificate-and-key": "^2.0.1", "winreg-ts": "^1.0.4" }, "dependencies": { @@ -80135,16 +80135,16 @@ "mongodb-data-service": { "version": "file:packages/data-service", "requires": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/compass-utils": "^0.6.7", "@mongodb-js/devtools-connect": "^3.0.1", "@mongodb-js/devtools-docker-test-envs": "^1.3.2", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/oidc-plugin": "^1.0.0", "@mongodb-js/prettier-config-compass": "^1.0.2", - "@mongodb-js/ssh-tunnel": "^2.2.1", + "@mongodb-js/ssh-tunnel": "^2.3.1", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/lodash": "^4.14.188", "@types/whatwg-url": "^8.2.1", @@ -80195,15 +80195,15 @@ "mongodb-database-model": { "version": "file:packages/database-model", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "ampersand-collection": "^2.0.2", "ampersand-model": "^8.0.1", "depcheck": "^1.4.1", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1" + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1" } }, "mongodb-download-url": { @@ -80235,16 +80235,16 @@ "mongodb-instance-model": { "version": "file:packages/instance-model", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "ampersand-model": "^8.0.1", "chai": "^4.3.4", "depcheck": "^1.4.1", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1", - "mongodb-database-model": "^2.21.1" + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-database-model": "^2.22.1" } }, "mongodb-js-cli": { @@ -80512,12 +80512,12 @@ "integrity": "sha512-gYJjEYG4v4a1WSXgUf81OBoBRlj+Z1SlnQVO392fC/4a1CN7CLWDITajZWPFTPh/yRozYk6sHHtZwZmQhodBEA==" }, "mongodb-query-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/mongodb-query-parser/-/mongodb-query-parser-4.1.2.tgz", - "integrity": "sha512-MfXJlYQcCgHKXo/OUo4x5eeJTN0XbZh9BD78xSsJ2pRnBo5/3Sx6H9Lw3NtdlTN/fJwypvJH24Qm2S2RmeRlFw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mongodb-query-parser/-/mongodb-query-parser-4.2.0.tgz", + "integrity": "sha512-VsrB2rJzKh3kEMApAz5EipA19G2LLZlnV9X1Ov9ERtnUkozm01sHP9YOGX//T1j/dZx96kbt5Aw2co5R5f6Bkw==", "requires": { + "@mongodb-js/shell-bson-parser": "^1.1.0", "debug": "^4.3.4", - "ejson-shell-parser": "^2.0.0", "javascript-stringify": "^2.1.0", "lodash": "^4.17.21" } @@ -80525,7 +80525,7 @@ "mongodb-query-util": { "version": "file:packages/mongodb-query-util", "requires": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -80568,11 +80568,11 @@ } }, "mongodb-redact": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/mongodb-redact/-/mongodb-redact-0.2.3.tgz", - "integrity": "sha512-a6ZPWlC9yf6F/n6ylKyyTO2PXZeD6nPKWwBmAIlOtOH4v82DIfsgO4Bpml10/YSwFxF1+VY8NHohmxofzpB4Yw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mongodb-redact/-/mongodb-redact-1.1.1.tgz", + "integrity": "sha512-j39aojyFmiEBb8KLgNC+oAb1ZTjLYjzFgyEzeNkW4bDFFlqBo0nqC6SXsU1q0+8yb4TQ6OzQD+KHd8yx7AnsGA==", "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.21" } }, "mongodb-runner": { @@ -80779,9 +80779,9 @@ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "native-request": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz", - "integrity": "sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz", + "integrity": "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw==", "optional": true }, "natural-compare": { @@ -84048,7 +84048,7 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "optional": true }, "ps-list": { @@ -85533,9 +85533,9 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=" }, "semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==" + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" }, "semver-compare": { "version": "1.0.0", @@ -86902,12 +86902,12 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "system-ca": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/system-ca/-/system-ca-1.0.3.tgz", - "integrity": "sha512-FHwdyDHM/J6SjHNVEp532J5rWsO0oPB/szZGsP/8I2s78mPLQhE0WwKTGi/RJulqTICekINsczg5q44n/1b+lQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/system-ca/-/system-ca-2.0.0.tgz", + "integrity": "sha512-eEWsCZHEyXdRPPMO680gLUhb9x8RK7YlXvv+I0zCvmGg9zf9OCchJxDf5NHqGPwAzLDEFpLXL5qv9KEU62N4Nw==", "requires": { "macos-export-certificate-and-key": "^1.1.1", - "win-export-certificate-and-key": "^1.1.1" + "win-export-certificate-and-key": "^2.0.0" } }, "tabbable": { @@ -87869,21 +87869,6 @@ "through": "^2.3.8" } }, - "underscore-plus": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.7.0.tgz", - "integrity": "sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==", - "requires": { - "underscore": "^1.9.1" - }, - "dependencies": { - "underscore": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", - "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==" - } - } - }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -88281,11 +88266,6 @@ "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-1.0.0.tgz", "integrity": "sha512-hwj/qMDUEjCU5h0xr90KGCf0tg0/LgJbmOWgrWKYlcJZM7XvquvUJZ0G/HMGr7F7OQMOUuPHWP9JpriinkAlkg==" }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" - }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -88882,14 +88862,13 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, "win-export-certificate-and-key": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/win-export-certificate-and-key/-/win-export-certificate-and-key-1.1.2.tgz", - "integrity": "sha512-3Su7Xdt9UR8pZicWQDcGSWNL6We/NzAGxe7AeQ1Z/zAeGHWlTKAh3HemGvIvxLRPsk4NW9D/QL3cL6SIvFcTvQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/win-export-certificate-and-key/-/win-export-certificate-and-key-2.0.1.tgz", + "integrity": "sha512-GsPUuIn95CepWgfiaqyIBWlj1uzr0LMfWIHBESSa+f84Zll9SjIX7Jj0+xNs/FlhH5zEkPO6k+SRQX1dfv3zPg==", "optional": true, "requires": { "bindings": "^1.5.0", - "node-addon-api": "^3.1.0", - "node-forge": "^1.2.1" + "node-addon-api": "^3.1.0" }, "dependencies": { "node-addon-api": { @@ -88897,12 +88876,6 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "optional": true - }, - "node-forge": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz", - "integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==", - "optional": true } } }, diff --git a/package.json b/package.json index 2ac4552056a..a4d33fab268 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "release": "npm run release --workspace mongodb-compass --", "reformat": "lerna run reformat --stream --no-bail", "package-compass": "npm run package-compass --workspace=mongodb-compass --", + "package-compass-nocompile": "npm run package-compass-nocompile --workspace=mongodb-compass --", "prestart": "npm run compile --workspace=@mongodb-js/webpack-config-compass", "prestart-web": "npm run prestart", "start": "npm run start --workspace=mongodb-compass", @@ -72,14 +73,14 @@ "@testing-library/dom": "^8.20.1", "babel-loader": "^7.1.5", "husky": "^8.0.3", - "js-yaml":"^4.1.0", + "js-yaml": "^4.1.0", "lerna": "^7.1.5", "lodash": "^4.17.21", "node-gyp": "^8.4.1" }, "engines": { - "node": ">=16.15.1", - "npm": ">=8.19.4" + "node": ">=18.19.1", + "npm": ">=10.2.4" }, "bugs": { "url": "https://docs.mongodb.com/compass/current/#contact", diff --git a/packages/atlas-service/package.json b/packages/atlas-service/package.json index fd5d85810f3..0a036083446 100644 --- a/packages/atlas-service/package.json +++ b/packages/atlas-service/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.22.0", + "version": "0.25.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -55,7 +55,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -73,23 +73,23 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", "@mongodb-js/devtools-connect": "^3.0.1", "@mongodb-js/oidc-plugin": "^1.0.0", - "hadron-app-registry": "^9.1.12", - "compass-preferences-model": "^2.23.1", - "electron": "^29.4.3", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "compass-preferences-model": "^2.25.0", + "electron": "^29.4.5", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "node-fetch": "^2.7.0", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", "redux-thunk": "^2.4.2", - "system-ca": "^1.0.2" + "system-ca": "^2.0.0" } } diff --git a/packages/bson-transpilers/package.json b/packages/bson-transpilers/package.json index 556401069bc..dfadc556570 100644 --- a/packages/bson-transpilers/package.json +++ b/packages/bson-transpilers/package.json @@ -1,6 +1,6 @@ { "name": "bson-transpilers", - "version": "3.0.4", + "version": "3.0.5", "apiVersion": "0.0.1", "description": "Source to source compilers using ANTLR", "contributors": [ @@ -32,7 +32,7 @@ }, "license": "SSPL", "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "chai": "^4.3.4", "depcheck": "^1.4.1", "eslint": "^7.25.0", diff --git a/packages/collection-model/package.json b/packages/collection-model/package.json index 2d4e6dd5046..c6b22c7b278 100644 --- a/packages/collection-model/package.json +++ b/packages/collection-model/package.json @@ -2,7 +2,7 @@ "name": "mongodb-collection-model", "description": "MongoDB collection model", "author": "Lucas Hrabovsky ", - "version": "5.21.1", + "version": "5.22.1", "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" @@ -31,11 +31,11 @@ "dependencies": { "ampersand-collection": "^2.0.2", "ampersand-model": "^8.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", diff --git a/packages/compass-aggregations/package.json b/packages/compass-aggregations/package.json index 27820edb35c..1b7c0d9b28e 100644 --- a/packages/compass-aggregations/package.json +++ b/packages/compass-aggregations/package.json @@ -2,7 +2,7 @@ "name": "@mongodb-js/compass-aggregations", "description": "Compass Aggregation Pipeline Builder", "private": true, - "version": "9.35.0", + "version": "9.38.0", "main": "dist/index.js", "compass:main": "src/index.ts", "types": "dist/index.d.ts", @@ -32,7 +32,7 @@ }, "license": "SSPL", "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -61,36 +61,36 @@ "@dnd-kit/core": "^6.0.7", "@dnd-kit/sortable": "^7.0.2", "@dnd-kit/utilities": "^3.2.1", - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/explain-plan-helper": "^1.1.13", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/explain-plan-helper": "^1.1.14", "@mongodb-js/mongodb-constants": "^0.10.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", + "@mongodb-js/shell-bson-parser": "^1.1.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "mongodb-schema": "^12.2.0", "prop-types": "^15.7.2", "re-resizable": "^6.9.0", diff --git a/packages/compass-aggregations/src/components/aggregation-side-panel/index.tsx b/packages/compass-aggregations/src/components/aggregation-side-panel/index.tsx index 48841e0e72d..ff3cb0d553c 100644 --- a/packages/compass-aggregations/src/components/aggregation-side-panel/index.tsx +++ b/packages/compass-aggregations/src/components/aggregation-side-panel/index.tsx @@ -18,6 +18,7 @@ import { FeedbackLink } from './feedback-link'; import { addWizard } from '../../modules/pipeline-builder/stage-editor'; import { UseCaseCard } from './stage-wizard-use-cases'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const containerStyles = css({ height: '100%', @@ -79,6 +80,7 @@ export const AggregationSidePanel = ({ onSelectUseCase, }: AggregationSidePanelProps) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const [searchText, setSearchText] = useState(''); const darkMode = useDarkMode(); @@ -104,12 +106,16 @@ export const AggregationSidePanel = ({ return; } onSelectUseCase(id, useCase.stageOperator); - track('Aggregation Use Case Added', { - drag_and_drop: false, - stage_name: useCase.stageOperator, - }); + track( + 'Aggregation Use Case Added', + { + drag_and_drop: false, + stage_name: useCase.stageOperator, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); }, - [onSelectUseCase, track] + [onSelectUseCase, track, connectionInfoAccess] ); return ( diff --git a/packages/compass-aggregations/src/components/create-view-modal/create-view-modal.tsx b/packages/compass-aggregations/src/components/create-view-modal/create-view-modal.tsx index 64d064cb7ce..9d66684f366 100644 --- a/packages/compass-aggregations/src/components/create-view-modal/create-view-modal.tsx +++ b/packages/compass-aggregations/src/components/create-view-modal/create-view-modal.tsx @@ -13,6 +13,11 @@ import { createView, changeViewName, close } from '../../modules/create-view'; import type { CreateViewRootState } from '../../stores/create-view'; import { withTelemetry } from '@mongodb-js/compass-telemetry/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import { + type ConnectionRepository, + withConnectionRepository, + type ConnectionInfo, +} from '@mongodb-js/compass-connections/provider'; const progressContainerStyles = css({ display: 'flex', @@ -29,9 +34,11 @@ type CreateViewModalProps = { isDuplicating?: boolean; source?: string; pipeline?: unknown[]; + connectionId: ConnectionInfo['id']; isRunning?: boolean; error: Error | null; track: TrackFunction; + connectionRepository: ConnectionRepository; }; class CreateViewModal extends PureComponent { @@ -46,7 +53,11 @@ class CreateViewModal extends PureComponent { componentDidUpdate(prevProps: CreateViewModalProps) { if (prevProps.isVisible !== this.props.isVisible && this.props.isVisible) { - this.props.track('Screen', { name: 'create_view_modal' }); + const connectionInfo = + this.props.connectionRepository.getConnectionInfoById( + this.props.connectionId + ); + this.props.track('Screen', { name: 'create_view_modal' }, connectionInfo); } } @@ -107,6 +118,7 @@ const mapStateToProps = (state: CreateViewRootState) => ({ error: state.error, source: state.source, pipeline: state.pipeline, + connectionId: state.connectionId, }); /** @@ -114,11 +126,13 @@ const mapStateToProps = (state: CreateViewRootState) => ({ * (dispatch) */ const MappedCreateViewModal = withTelemetry( - connect(mapStateToProps, { - createView, - changeViewName, - closeModal: close, - })(CreateViewModal) + withConnectionRepository( + connect(mapStateToProps, { + createView, + changeViewName, + closeModal: close, + })(CreateViewModal) + ) ); export default MappedCreateViewModal; diff --git a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-editor.tsx b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-editor.tsx index aa1a8fa9499..c5ee866344c 100644 --- a/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-editor.tsx +++ b/packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-editor.tsx @@ -21,6 +21,7 @@ import { changeEditorValue } from '../../../modules/pipeline-builder/text-editor import type { PipelineParserError } from '../../../modules/pipeline-builder/pipeline-parser/utils'; import { useAutocompleteFields } from '@mongodb-js/compass-field-store'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const containerStyles = css({ position: 'relative', @@ -80,6 +81,7 @@ export const PipelineEditor: React.FunctionComponent = ({ }) => { const fields = useAutocompleteFields(namespace); const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const editorInitialValueRef = useRef(pipelineText); const editorCurrentValueRef = useRef(pipelineText); editorCurrentValueRef.current = pipelineText; @@ -100,13 +102,17 @@ export const PipelineEditor: React.FunctionComponent = ({ !!editorCurrentValueRef.current && editorCurrentValueRef.current !== editorInitialValueRef.current ) { - track('Aggregation Edited', { - num_stages, - editor_view_type: 'text', - }); + track( + 'Aggregation Edited', + { + num_stages, + editor_view_type: 'text', + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); editorInitialValueRef.current = editorCurrentValueRef.current; } - }, [num_stages, track]); + }, [num_stages, track, connectionInfoAccess]); const annotations: Annotation[] = useMemo(() => { return syntaxErrors diff --git a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.spec.tsx b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.spec.tsx index e43f2c1b550..592ec9e72c2 100644 --- a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.spec.tsx +++ b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.spec.tsx @@ -171,6 +171,7 @@ describe('PipelineAI Component', function () { { event: 'PipelineAI Feedback', properties: { + connection_id: 'TEST', feedback: 'positive', request_id: 'pineapple', text: 'this is the pipeline I was looking for', diff --git a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.tsx b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.tsx index 2adf8ac084a..b93451a7034 100644 --- a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.tsx +++ b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-ai.tsx @@ -15,10 +15,12 @@ import type { RootState } from '../../modules'; import { useLogger } from '@mongodb-js/compass-logging/provider'; import { getPipelineStageOperatorsFromBuilderState } from '../../modules/pipeline-builder/builder-helpers'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const useOnSubmitFeedback = (lastAIPipelineRequestId: string | null) => { const logger = useLogger('AI-PIPELINE-UI'); const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); return useCallback( (feedback: 'positive' | 'negative', text: string) => { const { log, mongoLogId } = logger; @@ -33,11 +35,15 @@ const useOnSubmitFeedback = (lastAIPipelineRequestId: string | null) => { } ); - track('PipelineAI Feedback', () => ({ - feedback, - request_id: lastAIPipelineRequestId, - text, - })); + track( + 'PipelineAI Feedback', + () => ({ + feedback, + request_id: lastAIPipelineRequestId, + text, + }), + connectionInfoAccess.getCurrentConnectionInfo() + ); openToast('pipeline-ai-feedback-submitted', { variant: 'success', @@ -45,7 +51,7 @@ const useOnSubmitFeedback = (lastAIPipelineRequestId: string | null) => { timeout: 10_000, }); }, - [logger, track, lastAIPipelineRequestId] + [logger, track, lastAIPipelineRequestId, connectionInfoAccess] ); }; diff --git a/packages/compass-aggregations/src/components/stage-editor/stage-editor.tsx b/packages/compass-aggregations/src/components/stage-editor/stage-editor.tsx index afdab0506f6..6ec3bb581ea 100644 --- a/packages/compass-aggregations/src/components/stage-editor/stage-editor.tsx +++ b/packages/compass-aggregations/src/components/stage-editor/stage-editor.tsx @@ -25,6 +25,7 @@ import type { RootState } from '../../modules'; import type { PipelineParserError } from '../../modules/pipeline-builder/pipeline-parser/utils'; import { useAutocompleteFields } from '@mongodb-js/compass-field-store'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const editorContainerStyles = css({ display: 'flex', @@ -97,6 +98,7 @@ export const StageEditor = ({ editorRef, }: StageEditorProps) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const darkMode = useDarkMode(); const editorInitialValueRef = useRef(stageValue); const editorCurrentValueRef = useRef(stageValue); @@ -136,16 +138,27 @@ export const StageEditor = ({ !!editorCurrentValueRef.current && editorCurrentValueRef.current !== editorInitialValueRef.current ) { - track('Aggregation Edited', { - num_stages: num_stages, - stage_index: index + 1, - stage_action: 'stage_content_changed', - stage_name: stageOperator, - editor_view_type: editor_view_type, - }); + track( + 'Aggregation Edited', + { + num_stages: num_stages, + stage_index: index + 1, + stage_action: 'stage_content_changed', + stage_name: stageOperator, + editor_view_type: editor_view_type, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); editorInitialValueRef.current = editorCurrentValueRef.current; } - }, [track, num_stages, index, stageOperator, editor_view_type]); + }, [ + track, + num_stages, + index, + stageOperator, + editor_view_type, + connectionInfoAccess, + ]); return (
{} }, }) ) ); diff --git a/packages/compass-aggregations/src/modules/aggregation.ts b/packages/compass-aggregations/src/modules/aggregation.ts index 992f39cf316..f17053f1e1d 100644 --- a/packages/compass-aggregations/src/modules/aggregation.ts +++ b/packages/compass-aggregations/src/modules/aggregation.ts @@ -289,7 +289,7 @@ export const runAggregation = (): PipelineBuilderThunkAction> => { return async ( dispatch, getState, - { pipelineBuilder, instance, dataService, track } + { pipelineBuilder, instance, dataService, track, connectionInfoAccess } ) => { const pipeline = getPipelineFromBuilderState(getState(), pipelineBuilder); @@ -309,10 +309,14 @@ export const runAggregation = (): PipelineBuilderThunkAction> => { type: ActionTypes.RunAggregation, pipeline, }); - track('Aggregation Executed', () => ({ - num_stages: pipeline.length, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - })); + track( + 'Aggregation Executed', + () => ({ + num_stages: pipeline.length, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }), + connectionInfoAccess.getCurrentConnectionInfo() + ); return dispatch(fetchAggregationData()); }; }; @@ -363,8 +367,12 @@ export const cancelAggregation = (): PipelineBuilderThunkAction< void, Actions > => { - return (dispatch, getState, { track }) => { - track('Aggregation Canceled'); + return (dispatch, getState, { track, connectionInfoAccess }) => { + track( + 'Aggregation Canceled', + {}, + connectionInfoAccess.getCurrentConnectionInfo() + ); const { aggregation: { abortController }, } = getState(); @@ -387,7 +395,13 @@ const fetchAggregationData = ( return async ( dispatch, getState, - { preferences, logger: { log, mongoLogId }, track, globalAppRegistry } + { + preferences, + logger: { log, mongoLogId }, + track, + connectionInfoAccess, + connectionScopedAppRegistry, + } ) => { const { namespace, @@ -438,7 +452,7 @@ const fetchAggregationData = ( }); if (isMergeOrOut) { - globalAppRegistry.emit( + connectionScopedAppRegistry.emit( 'agg-pipeline-out-executed', getDestinationNamespaceFromStage( namespace, @@ -470,7 +484,11 @@ const fetchAggregationData = ( page, }); if ((e as MongoServerError).codeName === 'MaxTimeMSExpired') { - track('Aggregation Timed Out', { max_time_ms: maxTimeMS ?? null }); + track( + 'Aggregation Timed Out', + { max_time_ms: maxTimeMS ?? null }, + connectionInfoAccess.getCurrentConnectionInfo() + ); } log.warn( mongoLogId(1001000106), diff --git a/packages/compass-aggregations/src/modules/create-view/index.ts b/packages/compass-aggregations/src/modules/create-view/index.ts index e8b00714ac0..0b6b3e5c736 100644 --- a/packages/compass-aggregations/src/modules/create-view/index.ts +++ b/packages/compass-aggregations/src/modules/create-view/index.ts @@ -202,7 +202,13 @@ export const createView = (): CreateViewThunkAction> => { return async ( dispatch, getState, - { globalAppRegistry, connectionsManager, track, workspaces } + { + globalAppRegistry, + connectionsManager, + connectionRepository, + track, + workspaces, + } ) => { const { name: viewName, @@ -227,7 +233,11 @@ export const createView = (): CreateViewThunkAction> => { options ); const ns = `${database}.${viewName}`; - track('Aggregation Saved As View', { num_stages: viewPipeline.length }); + track( + 'Aggregation Saved As View', + { num_stages: viewPipeline.length }, + connectionRepository.getConnectionInfoById(connectionId) + ); globalAppRegistry.emit('view-created', ns, { connectionId, }); diff --git a/packages/compass-aggregations/src/modules/focus-mode.ts b/packages/compass-aggregations/src/modules/focus-mode.ts index 00411503051..8b5f575ddda 100644 --- a/packages/compass-aggregations/src/modules/focus-mode.ts +++ b/packages/compass-aggregations/src/modules/focus-mode.ts @@ -76,12 +76,16 @@ export default function reducer( export const enableFocusMode = ( stageIndex: number ): PipelineBuilderThunkAction => { - return (dispatch, getState, { track }) => { - track('Focus Mode Opened', { - num_stages: pipelineFromStore( - getState().pipelineBuilder.stageEditor.stages - ).length, - }); + return (dispatch, getState, { track, connectionInfoAccess }) => { + track( + 'Focus Mode Opened', + { + num_stages: pipelineFromStore( + getState().pipelineBuilder.stageEditor.stages + ).length, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch({ type: ActionTypes.FocusModeEnabled, stageIndex, @@ -93,15 +97,19 @@ export const disableFocusMode = (): PipelineBuilderThunkAction< void, FocusModeDisabledAction > => { - return (dispatch, getState, { track }) => { + return (dispatch, getState, { track, connectionInfoAccess }) => { const state = getState(); - track('Focus Mode Closed', { - num_stages: pipelineFromStore(state.pipelineBuilder.stageEditor.stages) - .length, - duration: Number( - (Date.now() - (state.focusMode.openedAt ?? 0)).toFixed(1) - ), - }); + track( + 'Focus Mode Closed', + { + num_stages: pipelineFromStore(state.pipelineBuilder.stageEditor.stages) + .length, + duration: Number( + (Date.now() - (state.focusMode.openedAt ?? 0)).toFixed(1) + ), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch({ type: ActionTypes.FocusModeDisabled }); }; }; diff --git a/packages/compass-aggregations/src/modules/index.ts b/packages/compass-aggregations/src/modules/index.ts index 1c78656edb5..e6b9409b75f 100644 --- a/packages/compass-aggregations/src/modules/index.ts +++ b/packages/compass-aggregations/src/modules/index.ts @@ -109,7 +109,9 @@ export type PipelineBuilderExtraArgs = { instance: MongoDBInstance; dataService: DataService; connectionInfoAccess: ConnectionInfoAccess; - connectionScopedAppRegistry: ConnectionScopedAppRegistry<'open-export'>; + connectionScopedAppRegistry: ConnectionScopedAppRegistry< + 'open-export' | 'view-edited' | 'agg-pipeline-out-executed' + >; }; export type PipelineBuilderThunkDispatch = diff --git a/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-ai.ts b/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-ai.ts index 5aed1b59f45..f120b3aa488 100644 --- a/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-ai.ts +++ b/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-ai.ts @@ -14,6 +14,7 @@ import type { AtlasServiceError } from '@mongodb-js/atlas-service/renderer'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import { mongoLogId } from '@mongodb-js/compass-logging/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; const emptyPipelineError = 'No pipeline was returned. Please try again with a different prompt.'; @@ -160,6 +161,7 @@ type FailedResponseTrackMessage = { errorName: string; errorCode?: string; requestId: string; + connectionInfo: ConnectionInfo; track: TrackFunction; } & Pick; @@ -171,6 +173,7 @@ function trackAndLogFailed({ errorCode, log, requestId, + connectionInfo, track, }: FailedResponseTrackMessage) { log.warn( @@ -185,13 +188,17 @@ function trackAndLogFailed({ requestId, } ); - track('AI Response Failed', { - editor_view_type, - error_code: errorCode || '', - status_code: statusCode, - error_name: errorName, - request_id: requestId, - }); + track( + 'AI Response Failed', + { + editor_view_type, + error_code: errorCode || '', + status_code: statusCode, + error_name: errorName, + request_id: requestId, + }, + connectionInfo + ); } export const runAIPipelineGeneration = ( @@ -209,6 +216,7 @@ export const runAIPipelineGeneration = ( preferences, logger: { log, mongoLogId }, track, + connectionInfoAccess, } ) => { const { @@ -220,6 +228,8 @@ export const runAIPipelineGeneration = ( dataService: { dataService }, } = getState(); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + const provideSampleDocuments = preferences.getPreferences().enableGenAISampleDocumentPassing; @@ -232,12 +242,16 @@ export const runAIPipelineGeneration = ( const abortController = new AbortController(); const { id: requestId, signal } = getAbortSignal(); - track('AI Prompt Submitted', () => ({ - editor_view_type, - user_input_length: userInput.length, - request_id: requestId, - has_sample_documents: provideSampleDocuments, - })); + track( + 'AI Prompt Submitted', + () => ({ + editor_view_type, + user_input_length: userInput.length, + request_id: requestId, + has_sample_documents: provideSampleDocuments, + }), + connectionInfo + ); dispatch({ type: AIPipelineActionTypes.AIPipelineStarted, @@ -293,6 +307,7 @@ export const runAIPipelineGeneration = ( track, log, requestId, + connectionInfo, }); // We're going to reset input state with this error, show the error in the // toast instead @@ -341,6 +356,7 @@ export const runAIPipelineGeneration = ( track, log, requestId, + connectionInfo, }); dispatch({ type: AIPipelineActionTypes.AIPipelineFailed, @@ -363,12 +379,16 @@ export const runAIPipelineGeneration = ( } ); - track('AI Response Generated', () => ({ - editor_view_type, - syntax_errors: !!(pipelineBuilder.syntaxError?.length > 0), - query_shape: pipelineBuilder.stages.map((stage) => stage.operator), - request_id: requestId, - })); + track( + 'AI Response Generated', + () => ({ + editor_view_type, + syntax_errors: !!(pipelineBuilder.syntaxError?.length > 0), + query_shape: pipelineBuilder.stages.map((stage) => stage.operator), + request_id: requestId, + }), + connectionInfo + ); dispatch({ type: AIPipelineActionTypes.LoadGeneratedPipeline, diff --git a/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-mode.ts b/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-mode.ts index 7c368cdc784..c7d8f125ee6 100644 --- a/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-mode.ts +++ b/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-mode.ts @@ -65,7 +65,11 @@ const reducer: Reducer = (state = INITIAL_STATE, action) => { export const changePipelineMode = ( newMode: PipelineMode ): PipelineBuilderThunkAction => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { if (newMode === getState().pipelineBuilder.pipelineMode) { return; } @@ -91,10 +95,14 @@ export const changePipelineMode = ( pipelineBuilder ).length; - track('Editor Type Changed', { - num_stages, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - }); + track( + 'Editor Type Changed', + { + num_stages, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch(updatePipelinePreview()); }; diff --git a/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-parser/utils.ts b/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-parser/utils.ts index 647a4ad58d4..71cbf6031c7 100644 --- a/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-parser/utils.ts +++ b/packages/compass-aggregations/src/modules/pipeline-builder/pipeline-parser/utils.ts @@ -1,6 +1,6 @@ import babelGenerate from '@babel/generator'; import type { Node } from '@babel/types'; -import _parseShellBSON, { ParseMode } from 'ejson-shell-parser'; +import _parseShellBSON, { ParseMode } from '@mongodb-js/shell-bson-parser'; import { prettify } from '@mongodb-js/compass-editor'; import type { FormatOptions } from '@mongodb-js/compass-editor'; diff --git a/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.ts b/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.ts index e421b578672..f3e5b9285b2 100644 --- a/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.ts +++ b/packages/compass-aggregations/src/modules/pipeline-builder/stage-editor.ts @@ -389,7 +389,7 @@ export const runStage = ( return async ( dispatch, getState, - { pipelineBuilder, preferences, globalAppRegistry } + { pipelineBuilder, preferences, connectionScopedAppRegistry } ) => { const { dataService: { dataService }, @@ -442,7 +442,7 @@ export const runStage = ( id: idx, previewDocs: result.map((doc) => new HadronDocument(doc)), }); - globalAppRegistry.emit( + connectionScopedAppRegistry.emit( 'agg-pipeline-out-executed', getDestinationNamespaceFromStage( namespace, @@ -534,7 +534,11 @@ export const changeStageOperator = ( string | undefined, ChangeStageOperatorAction > => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { const { env, comments, @@ -569,13 +573,17 @@ export const changeStageOperator = ( stage.changeOperator(newVal); - track('Aggregation Edited', { - num_stages: pipelineFromStore(stages).length, - stage_action: 'stage_renamed', - stage_name: stage.operator, - stage_index: idxInPipeline + 1, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - }); + track( + 'Aggregation Edited', + { + num_stages: pipelineFromStore(stages).length, + stage_action: 'stage_renamed', + stage_name: stage.operator, + stage_index: idxInPipeline + 1, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch({ type: StageEditorActionTypes.StageOperatorChange, id, stage }); @@ -643,7 +651,11 @@ export const changeStageCollapsed = ( export const addStage = ( after?: number ): PipelineBuilderThunkAction => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { const { pipelineBuilder: { stageEditor: { stages }, @@ -657,12 +669,16 @@ export const addStage = ( }); const stage = pipelineBuilder.addStage(addAfterIdxInPipeline); - track('Aggregation Edited', { - num_stages: pipelineFromStore(stages).length, - stage_action: 'stage_added', - stage_index: stage.id + 1, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - }); + track( + 'Aggregation Edited', + { + num_stages: pipelineFromStore(stages).length, + stage_action: 'stage_added', + stage_index: stage.id + 1, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch({ type: StageEditorActionTypes.StageAdded, after: addAfter, @@ -674,7 +690,11 @@ export const addStage = ( export const removeStage = ( at: number ): PipelineBuilderThunkAction => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { const { pipelineBuilder: { stageEditor: { stages }, @@ -689,13 +709,17 @@ export const removeStage = ( pipelineBuilder.cancelPreviewForStage(idxInPipeline); const stage = pipelineBuilder.removeStage(idxInPipeline); - track('Aggregation Edited', { - num_stages: pipelineFromStore(stages).length, - stage_action: 'stage_deleted', - stage_name: stage.operator, - stage_index: idxInPipeline + 1, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - }); + track( + 'Aggregation Edited', + { + num_stages: pipelineFromStore(stages).length, + stage_action: 'stage_deleted', + stage_name: stage.operator, + stage_index: idxInPipeline + 1, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch({ type: StageEditorActionTypes.StageRemoved, at }); dispatch(loadPreviewForStagesFrom(at)); void dispatch(fetchExplainForPipeline()); @@ -706,7 +730,11 @@ export const moveStage = ( from: number, to: number ): PipelineBuilderThunkAction => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { if (from === to) { return; } @@ -742,13 +770,17 @@ export const moveStage = ( if (pipelineWasNotModified) { dispatch({ type: StageEditorActionTypes.StageMoved, from, to }); } else { - track('Aggregation Edited', { - num_stages: pipelineFromStore(stages).length, - stage_action: 'stage_reordered', - stage_name: stageAtFromIdx.stageOperator, - stage_index: stageAtFromIdx.idxInPipeline + 1, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - }); + track( + 'Aggregation Edited', + { + num_stages: pipelineFromStore(stages).length, + stage_action: 'stage_reordered', + stage_name: stageAtFromIdx.stageOperator, + stage_index: stageAtFromIdx.idxInPipeline + 1, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); pipelineBuilder.moveStage(stageAtFromIdx.idxInPipeline, toIdxInPipeline); dispatch({ type: StageEditorActionTypes.StageMoved, from, to }); @@ -872,7 +904,11 @@ export const convertWizardToStage = ( void, WizardChangeAction | WizardToStageAction > => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { const { pipelineBuilder: { stageEditor: { stages }, @@ -903,16 +939,25 @@ export const convertWizardToStage = ( stage.changeValue(formatWizardValue(itemAtIdx.value as string)); - track('Aggregation Edited', { - num_stages: pipelineFromStore(stages).length + 1, - stage_action: 'stage_added', - stage_name: stage.operator, - stage_index: afterStageIndex + 1, - editor_view_type: 'stage', - }); - track('Aggregation Use Case Saved', { - stage_name: stage.operator, - }); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + track( + 'Aggregation Edited', + { + num_stages: pipelineFromStore(stages).length + 1, + stage_action: 'stage_added', + stage_name: stage.operator, + stage_index: afterStageIndex + 1, + editor_view_type: 'stage', + }, + connectionInfo + ); + track( + 'Aggregation Use Case Saved', + { + stage_name: stage.operator, + }, + connectionInfo + ); dispatch({ type: StageEditorActionTypes.WizardToStageClicked, diff --git a/packages/compass-aggregations/src/modules/pipeline-builder/text-editor-output-stage.ts b/packages/compass-aggregations/src/modules/pipeline-builder/text-editor-output-stage.ts index 9ad7a2d3204..b02323818a4 100644 --- a/packages/compass-aggregations/src/modules/pipeline-builder/text-editor-output-stage.ts +++ b/packages/compass-aggregations/src/modules/pipeline-builder/text-editor-output-stage.ts @@ -131,7 +131,7 @@ export const runPipelineWithOutputStage = (): PipelineBuilderThunkAction< return async ( dispatch, getState, - { pipelineBuilder, preferences, globalAppRegistry } + { pipelineBuilder, preferences, connectionScopedAppRegistry } ) => { const { autoPreview, @@ -173,7 +173,7 @@ export const runPipelineWithOutputStage = (): PipelineBuilderThunkAction< dispatch({ type: OutputStageActionTypes.FetchSucceded, }); - globalAppRegistry.emit( + connectionScopedAppRegistry.emit( 'agg-pipeline-out-executed', getDestinationNamespaceFromStage( namespace, diff --git a/packages/compass-aggregations/src/modules/saved-pipeline.ts b/packages/compass-aggregations/src/modules/saved-pipeline.ts index 2d1856108e6..0fccaa96060 100644 --- a/packages/compass-aggregations/src/modules/saved-pipeline.ts +++ b/packages/compass-aggregations/src/modules/saved-pipeline.ts @@ -164,7 +164,11 @@ export const openStoredPipeline = ( */ export const saveCurrentPipeline = (): PipelineBuilderThunkAction => - async (dispatch, getState, { pipelineBuilder, pipelineStorage, track }) => { + async ( + dispatch, + getState, + { pipelineBuilder, pipelineStorage, track, connectionInfoAccess } + ) => { if (getState().id === '') { dispatch(createId()); } @@ -205,21 +209,26 @@ export const saveCurrentPipeline = } })(); - track('Aggregation Saved', { - id: savedPipeline.id, - num_stages: stagesLength, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - }); + track( + 'Aggregation Saved', + { + id: savedPipeline.id, + num_stages: stagesLength, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch(updatePipelineList()); }; export const confirmOpenPipeline = (pipelineData: SavedPipeline): PipelineBuilderThunkAction => - async (dispatch, getState, { track }) => { + async (dispatch, getState, { track, connectionInfoAccess }) => { const isModified = getState().isModified; + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); if (isModified) { - track('Screen', { name: 'restore_pipeline_modal' }); + track('Screen', { name: 'restore_pipeline_modal' }, connectionInfo); const confirmed = await showConfirmation({ title: 'Are you sure you want to open this pipeline?', description: @@ -230,18 +239,27 @@ export const confirmOpenPipeline = return; } } - track('Aggregation Opened', { - id: pipelineData.id, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - screen: 'aggregations', - }); + track( + 'Aggregation Opened', + { + id: pipelineData.id, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + screen: 'aggregations', + }, + connectionInfo + ); void dispatch(openStoredPipeline(pipelineData)); }; export const confirmDeletePipeline = (pipelineId: string): PipelineBuilderThunkAction => - async (dispatch, getState, { pipelineStorage, track }) => { - track('Screen', { name: 'delete_pipeline_modal' }); + async ( + dispatch, + getState, + { pipelineStorage, track, connectionInfoAccess } + ) => { + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + track('Screen', { name: 'delete_pipeline_modal' }, connectionInfo); const confirmed = await showConfirmation({ title: 'Are you sure you want to delete this pipeline?', description: @@ -252,11 +270,15 @@ export const confirmDeletePipeline = if (!confirmed) { return; } - track('Aggregation Deleted', { - id: pipelineId, - editor_view_type: mapPipelineModeToEditorViewType(getState()), - screen: 'aggregations', - }); + track( + 'Aggregation Deleted', + { + id: pipelineId, + editor_view_type: mapPipelineModeToEditorViewType(getState()), + screen: 'aggregations', + }, + connectionInfo + ); await pipelineStorage?.delete(pipelineId); dispatch(updatePipelineList()); }; diff --git a/packages/compass-aggregations/src/modules/side-panel.ts b/packages/compass-aggregations/src/modules/side-panel.ts index d5e39ae37d9..4df84ed2ef4 100644 --- a/packages/compass-aggregations/src/modules/side-panel.ts +++ b/packages/compass-aggregations/src/modules/side-panel.ts @@ -37,7 +37,11 @@ export const toggleSidePanel = (): PipelineBuilderThunkAction< void, SidePanelToggledAction > => { - return (dispatch, getState, { pipelineBuilder, track }) => { + return ( + dispatch, + getState, + { pipelineBuilder, track, connectionInfoAccess } + ) => { const { sidePanel: { isPanelOpen }, } = getState(); @@ -46,10 +50,14 @@ export const toggleSidePanel = (): PipelineBuilderThunkAction< // When user is opening the panel if (willPanelBeOpen) { - track('Aggregation Side Panel Opened', { - num_stages: getPipelineFromBuilderState(getState(), pipelineBuilder) - .length, - }); + track( + 'Aggregation Side Panel Opened', + { + num_stages: getPipelineFromBuilderState(getState(), pipelineBuilder) + .length, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); } // Persist the state of the stage wizard side panel for other tabs or for diff --git a/packages/compass-aggregations/src/modules/update-view.spec.ts b/packages/compass-aggregations/src/modules/update-view.spec.ts index 8d20aea1abe..d95310067c2 100644 --- a/packages/compass-aggregations/src/modules/update-view.spec.ts +++ b/packages/compass-aggregations/src/modules/update-view.spec.ts @@ -4,11 +4,26 @@ import { ERROR_UPDATING_VIEW, updateView } from './update-view'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; import AppRegistry from 'hadron-app-registry'; -import { TEST_CONNECTION_INFO } from '@mongodb-js/compass-connections/provider'; +import { + type ConnectionInfoAccess, + ConnectionScopedAppRegistryImpl, + TEST_CONNECTION_INFO, +} from '@mongodb-js/compass-connections/provider'; describe('update-view module', function () { + const globalAppRegistry = new AppRegistry(); + const connectionInfoAccess: ConnectionInfoAccess = { + getCurrentConnectionInfo() { + return TEST_CONNECTION_INFO; + }, + }; + const connectionScopedAppRegistry = new ConnectionScopedAppRegistryImpl( + globalAppRegistry.emit.bind(globalAppRegistry), + connectionInfoAccess + ); const thunkArg = { - globalAppRegistry: new AppRegistry(), + globalAppRegistry, + connectionScopedAppRegistry, localAppRegistry: new AppRegistry(), pipelineBuilder: { getPipelineFromStages() { diff --git a/packages/compass-aggregations/src/modules/update-view.ts b/packages/compass-aggregations/src/modules/update-view.ts index 3a5688829dc..4d1ee29191c 100644 --- a/packages/compass-aggregations/src/modules/update-view.ts +++ b/packages/compass-aggregations/src/modules/update-view.ts @@ -87,7 +87,7 @@ export const updateView = (): PipelineBuilderThunkAction> => { workspaces, logger: { debug }, track, - globalAppRegistry, + connectionScopedAppRegistry, connectionInfoAccess, } ) => { @@ -101,8 +101,7 @@ export const updateView = (): PipelineBuilderThunkAction> => { return; } - const { id: connectionId } = - connectionInfoAccess.getCurrentConnectionInfo(); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); const viewPipeline = getPipelineFromBuilderState( getState(), @@ -115,13 +114,17 @@ export const updateView = (): PipelineBuilderThunkAction> => { try { await ds!.updateCollection(viewNamespace, options); - track('View Updated', { - num_stages: viewPipeline.length, - editor_view_type: mapPipelineModeToEditorViewType(state), - }); + track( + 'View Updated', + { + num_stages: viewPipeline.length, + editor_view_type: mapPipelineModeToEditorViewType(state), + }, + connectionInfo + ); debug('selecting namespace', viewNamespace); - globalAppRegistry.emit('view-edited', viewNamespace); - workspaces.openCollectionWorkspace(connectionId, viewNamespace); + connectionScopedAppRegistry.emit('view-edited', viewNamespace); + workspaces.openCollectionWorkspace(connectionInfo.id, viewNamespace); } catch (e: any) { debug('Unexpected error updating view', e); dispatch(updateViewErrorOccured(e)); diff --git a/packages/compass-aggregations/src/stores/create-view.spec.ts b/packages/compass-aggregations/src/stores/create-view.spec.ts index f544673c9c7..51957e95750 100644 --- a/packages/compass-aggregations/src/stores/create-view.spec.ts +++ b/packages/compass-aggregations/src/stores/create-view.spec.ts @@ -4,6 +4,7 @@ import { expect } from 'chai'; import { ConnectionsManager, type DataService, + type ConnectionRepository, } from '@mongodb-js/compass-connections/provider'; import { changeViewName, createView } from '../modules/create-view'; import Sinon from 'sinon'; @@ -34,6 +35,9 @@ describe('CreateViewStore [Store]', function () { const workspaces = { openCollectionWorkspace: openCollectionWorkspaceStub, } as unknown as WorkspacesService; + const connectionRepository = { + getConnectionInfoById: () => {}, + } as unknown as ConnectionRepository; beforeEach(function () { globalAppRegistry = new AppRegistry(); @@ -46,6 +50,7 @@ describe('CreateViewStore [Store]', function () { { globalAppRegistry, connectionsManager, + connectionRepository, logger, track, workspaces, diff --git a/packages/compass-aggregations/src/stores/create-view.ts b/packages/compass-aggregations/src/stores/create-view.ts index 76cbc42c8fe..aff00f1979d 100644 --- a/packages/compass-aggregations/src/stores/create-view.ts +++ b/packages/compass-aggregations/src/stores/create-view.ts @@ -7,13 +7,17 @@ import reducer, { open } from '../modules/create-view'; import type AppRegistry from 'hadron-app-registry'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; -import type { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionRepositoryAccess, + ConnectionsManager, +} from '@mongodb-js/compass-connections/provider'; import type { ActivateHelpers } from 'hadron-app-registry'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; type CreateViewServices = { globalAppRegistry: AppRegistry; connectionsManager: ConnectionsManager; + connectionRepository: ConnectionRepositoryAccess; logger: Logger; track: TrackFunction; workspaces: WorkspacesService; @@ -50,6 +54,7 @@ export function activateCreateViewPlugin( { globalAppRegistry, connectionsManager, + connectionRepository, logger, track, workspaces, @@ -59,6 +64,7 @@ export function activateCreateViewPlugin( const store = configureStore({ globalAppRegistry, connectionsManager, + connectionRepository, logger, track, workspaces, diff --git a/packages/compass-app-stores/package.json b/packages/compass-app-stores/package.json index a5f582bb38b..b53c63e78c3 100644 --- a/packages/compass-app-stores/package.json +++ b/packages/compass-app-stores/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "7.19.0", + "version": "7.22.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -53,7 +53,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -74,14 +74,14 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/connection-info": "^0.4.1", - "hadron-app-registry": "^9.1.12", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/connection-info": "^0.5.1", + "hadron-app-registry": "^9.2.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2" }, diff --git a/packages/compass-app-stores/src/stores/instance-store.spec.ts b/packages/compass-app-stores/src/stores/instance-store.spec.ts index 02121e2ebbb..fa30fbf9942 100644 --- a/packages/compass-app-stores/src/stores/instance-store.spec.ts +++ b/packages/compass-app-stores/src/stores/instance-store.spec.ts @@ -121,6 +121,9 @@ describe('InstanceStore [Store]', function () { let connectedInstance: MongoDBInstance; let initialInstanceRefreshedPromise: Promise; beforeEach(function () { + sinon + .stub(connectionsManager, 'getDataServiceForConnection') + .returns(dataService); connectionsManager.emit( ConnectionsManagerEvents.ConnectionAttemptSuccessful, connectedConnectionInfoId, @@ -330,35 +333,35 @@ describe('InstanceStore [Store]', function () { }); }); - const createdEvents = ['agg-pipeline-out-executed']; - - for (const evt of createdEvents) { - context(`on '${evt}' event`, function () { - it('should add collection to the databases collections', function () { - globalAppRegistry.emit(evt, 'foo.qux'); - expect( - connectedInstance.databases.get('foo')?.collections - ).to.have.lengthOf(3); - expect( - connectedInstance.databases - .get('foo') - ?.collections.get('foo.qux', '_id') - ).to.exist; + context(`on 'agg-pipeline-out-executed' event`, function () { + it('should add collection to the databases collections', function () { + globalAppRegistry.emit('agg-pipeline-out-executed', 'foo.qux', { + connectionId: connectedConnectionInfoId, }); + expect( + connectedInstance.databases.get('foo')?.collections + ).to.have.lengthOf(3); + expect( + connectedInstance.databases + .get('foo') + ?.collections.get('foo.qux', '_id') + ).to.exist; + }); - it("should add new database and add collection to its collections if database doesn't exist yet", function () { - globalAppRegistry.emit(evt, 'bar.qux'); - expect(connectedInstance.databases).to.have.lengthOf(2); - expect(connectedInstance.databases.get('bar')).to.exist; - expect( - connectedInstance.databases.get('bar')?.collections - ).to.have.lengthOf(1); - expect( - connectedInstance.databases.get('bar')?.collections.get('bar.qux') - ).to.exist; + it("should add new database and add collection to its collections if database doesn't exist yet", function () { + globalAppRegistry.emit('agg-pipeline-out-executed', 'bar.qux', { + connectionId: connectedConnectionInfoId, }); + expect(connectedInstance.databases).to.have.lengthOf(2); + expect(connectedInstance.databases.get('bar')).to.exist; + expect( + connectedInstance.databases.get('bar')?.collections + ).to.have.lengthOf(1); + expect( + connectedInstance.databases.get('bar')?.collections.get('bar.qux') + ).to.exist; }); - } + }); context(`on 'collection-created' event`, function () { it('should not respond when the connectionId does not matches the connectionId for the instance', function () { @@ -469,4 +472,68 @@ describe('InstanceStore [Store]', function () { }); }); }); + + context('when disconnected', function () { + it('should remove the instance from InstancesManager and should not perform any actions on the stale instance', async function () { + // first connect + connectionsManager.emit( + ConnectionsManagerEvents.ConnectionAttemptSuccessful, + connectedConnectionInfoId, + dataService + ); + + // setup a spy on old instance + const oldInstance = instancesManager.getMongoDBInstanceForConnection( + connectedConnectionInfoId + ); + const oldFetchDatabasesSpy = sinon.spy(oldInstance, 'fetchDatabases'); + + // now disconnect + connectionsManager.emit( + ConnectionsManagerEvents.ConnectionDisconnected, + connectedConnectionInfoId + ); + + // there is no instance in store InstancesManager now + expect(() => + instancesManager.getMongoDBInstanceForConnection( + connectedConnectionInfoId + ) + ).to.throw; + + // lets connect again and ensure that old instance does not receive events anymore + const newDataService = createDataService(); + sinon + .stub(connectionsManager, 'getDataServiceForConnection') + .returns(dataService); + connectionsManager.emit( + ConnectionsManagerEvents.ConnectionAttemptSuccessful, + connectedConnectionInfoId, + newDataService + ); + + // setup a spy on new instance + const newInstance = instancesManager.getMongoDBInstanceForConnection( + connectedConnectionInfoId + ); + + let resolveFetchDatabasePromise: (() => void) | undefined; + const fetchDatabasePromise = new Promise((resolve) => { + resolveFetchDatabasePromise = resolve; + }); + const newFetchDatabasesSpy = sinon + .stub(newInstance, 'fetchDatabases') + .callsFake(() => { + resolveFetchDatabasePromise?.(); + return Promise.resolve(); + }); + + globalAppRegistry.emit('refresh-databases', { + connectionId: connectedConnectionInfoId, + }); + await fetchDatabasePromise; + expect(oldFetchDatabasesSpy).to.not.be.called; + expect(newFetchDatabasesSpy).to.be.called; + }); + }); }); diff --git a/packages/compass-app-stores/src/stores/instance-store.ts b/packages/compass-app-stores/src/stores/instance-store.ts index e5d85693d39..b5a801801c5 100644 --- a/packages/compass-app-stores/src/stores/instance-store.ts +++ b/packages/compass-app-stores/src/stores/instance-store.ts @@ -53,144 +53,236 @@ export function createInstancesStore( { on, cleanup, addCleanup }: ActivateHelpers ) { const instancesManager = new MongoDBInstancesManager(); - on( - connectionsManager, - ConnectionsManagerEvents.ConnectionDisconnected, - function (connectionInfoId: string) { - instancesManager.removeMongoDBInstanceForConnection(connectionInfoId); - } - ); - on( - connectionsManager, - ConnectionsManagerEvents.ConnectionAttemptSuccessful, - function (instanceConnectionId: string, dataService: DataService) { - async function refreshInstance( - refreshOptions: Omit< - Parameters[0], - 'dataService' - > = {} - ) { - const isFirstRun = instance.status === 'initial'; - - try { - await instance.refresh({ dataService, ...refreshOptions }); - } catch (err: any) { - log.warn( - mongoLogId(1_001_000_295), - 'Instance Store', - 'Failed to refresh instance', - { - message: (err as Error).message, - connectionId: dataService.id, - isFirstRun, - } - ); - // The `instance.refresh` method is catching all expected errors: we treat - // a lot of metadata as optional so failing to fetch it shouldn't throw. - // In most cases if this failed on subsequent runs, user is probably - // already in a state that will show them a more specified error (like - // seeing some server error trying to refresh collection list in cases - // that something happened with the server after connection). However if - // we are fetching instance info for the first time (as indicated by the - // initial instance status) and we ended up here, there might be no other - // place for the user to see the error. This is a very rare case, but we - // don't want to leave the user without any indication that something went - // wrong and so we show an toast with the error message - if (isFirstRun) { - const { name, message } = err as Error; - openToast('instance-refresh-failed', { - title: 'Failed to retrieve server info', - description: `${name}: ${message}`, - variant: 'important', - }); - } - } + const fetchAllCollections = async ({ + connectionId, + }: { connectionId?: string } = {}) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided'); } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + // It is possible to get here before the databases finished loading. We have + // to wait for the databases, otherwise it will load all the collections for + // 0 databases. + await instance.fetchDatabases({ dataService }); + await Promise.all( + instance.databases.map((db) => { + return db.fetchCollections({ dataService }); + }) + ); + } catch (error) { + log.warn( + mongoLogId(1_001_000_324), + 'Instance Store', + 'Failed to respond to fetch all collections', + { + message: (error as Error).message, + connectionId: connectionId, + } + ); + } + }; - // Event emitted when the Databases grid needs to be refreshed. We - // additionally refresh the list of collections as well since there is the - // side navigation which could be in expanded mode - async function refreshDatabases() { - try { - await instance.fetchDatabases({ dataService, force: true }); - await Promise.allSettled( - instance.databases.map((db) => - db.fetchCollections({ dataService, force: true }) - ) - ); - } catch (err: any) { - log.warn( - mongoLogId(1_001_000_296), - 'Instance Store', - 'Failed to refresh databases', - { - message: (err as Error).message, - connectionId: dataService.id, - } - ); + const refreshInstance = async ( + refreshOptions: Omit< + Parameters[0], + 'dataService' + > = {}, + { connectionId }: { connectionId?: string } = {} + ) => { + let isFirstRun: boolean | undefined; + + try { + if (!connectionId) { + throw new Error('No connectionId provided'); + } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + isFirstRun = instance.status === 'initial'; + await instance.refresh({ dataService, ...refreshOptions }); + } catch (err: any) { + log.warn( + mongoLogId(1_001_000_295), + 'Instance Store', + 'Failed to refresh instance', + { + message: (err as Error).message, + connectionId: connectionId, + isFirstRun, } + ); + // The `instance.refresh` method is catching all expected errors: we treat + // a lot of metadata as optional so failing to fetch it shouldn't throw. + // In most cases if this failed on subsequent runs, user is probably + // already in a state that will show them a more specified error (like + // seeing some server error trying to refresh collection list in cases + // that something happened with the server after connection). However if + // we are fetching instance info for the first time (as indicated by the + // initial instance status) and we ended up here, there might be no other + // place for the user to see the error. This is a very rare case, but we + // don't want to leave the user without any indication that something went + // wrong and so we show an toast with the error message + if (isFirstRun) { + const { name, message } = err as Error; + openToast('instance-refresh-failed', { + title: 'Failed to retrieve server info', + description: `${name}: ${message}`, + variant: 'important', + }); } + } + }; - async function fetchAllCollections() { - // It is possible to get here before the databases finished loading. We have - // to wait for the databases, otherwise it will load all the collections for - // 0 databases. - await instance.fetchDatabases({ dataService }); - await Promise.all( - instance.databases.map((db) => { - return db.fetchCollections({ dataService }); - }) - ); + // Event emitted when the Databases grid needs to be refreshed. We + // additionally refresh the list of collections as well since there is the + // side navigation which could be in expanded mode + const refreshDatabases = async ({ + connectionId, + }: { connectionId?: string } = {}) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided in the event parameters'); } - - async function refreshNamespaceStats( - { ns }: { ns: string }, - { connectionId }: { connectionId?: string } = {} - ) { - if (connectionId !== instanceConnectionId) { - return; + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + await instance.fetchDatabases({ dataService, force: true }); + await Promise.allSettled( + instance.databases.map((db) => + db.fetchCollections({ dataService, force: true }) + ) + ); + } catch (err: any) { + log.warn( + mongoLogId(1_001_000_296), + 'Instance Store', + 'Failed to refresh databases', + { + message: (err as Error).message, + connectionId: connectionId, } + ); + } + }; - const { database } = toNS(ns); - const db = instance.databases.get(database); - const coll = db?.collections.get(ns); - // We don't care if this fails - await Promise.allSettled([ - db?.fetch({ dataService, force: true }), - coll?.fetch({ dataService, force: true }), - ]); + const refreshNamespaceStats = async ( + { ns }: { ns: string }, + { connectionId }: { connectionId?: string } = {} + ) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided in the event parameters'); } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + const { database } = toNS(ns); + const db = instance.databases.get(database); + const coll = db?.collections.get(ns); + // We don't care if this fails + await Promise.allSettled([ + db?.fetch({ dataService, force: true }), + coll?.fetch({ dataService, force: true }), + ]); + } catch (error) { + log.warn( + mongoLogId(1_001_000_319), + 'Instance Store', + 'Failed to refresh databases', + { + message: (error as Error).message, + connectionId: connectionId, + } + ); + } + }; - // A shared method that will add new namespace model to the instance model if - // it doesn't exist yet and will call refresh methods on the database and - // collection models - async function maybeAddAndRefreshCollectionModel(namespace: string) { - const { database } = toNS(namespace); - const db = - instance.databases.get(database) ?? - // We might be adding collection to a new db namespace - instance.databases.add({ _id: database }); - // We might be refreshing an existing namespace (in case of out stages usage - // for example) - let newCollection = false; - let coll = db.collections.get(namespace, '_id'); - if (!coll) { - newCollection = true; - coll = db.collections.add({ _id: namespace }); + // A shared method that will add new namespace model to the instance model if + // it doesn't exist yet and will call refresh methods on the database and + // collection models + const maybeAddAndRefreshCollectionModel = async ( + namespace: string, + { connectionId }: { connectionId?: string } = {} + ) => { + try { + if (!connectionId) { + throw new Error('connectionId not provided'); + } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + const { database } = toNS(namespace); + const db = + instance.databases.get(database) ?? + // We might be adding collection to a new db namespace + instance.databases.add({ _id: database }); + // We might be refreshing an existing namespace (in case of out stages usage + // for example) + let newCollection = false; + let coll = db.collections.get(namespace, '_id'); + if (!coll) { + newCollection = true; + coll = db.collections.add({ _id: namespace }); + } + // We don't care if this fails + await Promise.allSettled([ + db.fetch({ dataService, force: true }), + coll.fetch({ + dataService, + force: true, + // We only need to fetch info in case of new collection being created + fetchInfo: newCollection, + }), + ]); + } catch (error) { + log.warn( + mongoLogId(1_001_000_320), + 'Instance Store', + 'Failed to refresh collection model', + { + message: (error as Error).message, + connectionId: connectionId, } - // We don't care if this fails - await Promise.allSettled([ - db.fetch({ dataService, force: true }), - coll.fetch({ - dataService, - force: true, - // We only need to fetch info in case of new collection being created - fetchInfo: newCollection, - }), - ]); + ); + } + }; + + on( + connectionsManager, + ConnectionsManagerEvents.ConnectionDisconnected, + function (connectionInfoId: string) { + try { + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionInfoId); + instance.removeAllListeners(); + } catch (error) { + log.warn( + mongoLogId(1_001_000_322), + 'Instance Store', + 'Failed to remove instance listeners upon disconnect', + { + message: (error as Error).message, + connectionId: connectionInfoId, + } + ); } + instancesManager.removeMongoDBInstanceForConnection(connectionInfoId); + } + ); + on( + connectionsManager, + ConnectionsManagerEvents.ConnectionAttemptSuccessful, + function (instanceConnectionId: string, dataService: DataService) { const connectionString = dataService.getConnectionString(); const firstHost = connectionString.hosts[0] || ''; const [hostname, port] = firstHost.split(':'); @@ -212,163 +304,264 @@ export function createInstancesStore( instance.removeAllListeners(); }); - void refreshInstance({ - fetchDatabases: true, - fetchDbStats: true, - }); - - function onTopologyDescriptionChanged({ - newDescription, - }: { - newDescription: ReturnType; - }) { - instance.set({ - topologyDescription: getTopologyDescription(newDescription), - }); - } + void refreshInstance( + { + fetchDatabases: true, + fetchDbStats: true, + }, + { + connectionId: instanceConnectionId, + } + ); on( dataService, 'topologyDescriptionChanged', - onTopologyDescriptionChanged + ({ + newDescription, + }: { + newDescription: ReturnType; + }) => { + instance.set({ + topologyDescription: getTopologyDescription(newDescription), + }); + } ); + } + ); - on( - globalAppRegistry, - 'sidebar-expand-database', - (connectionId: string, databaseId: string) => { - if (connectionId !== instanceConnectionId) { - return; - } - void instance.databases - .get(databaseId) - ?.fetchCollections({ dataService }); + on( + globalAppRegistry, + 'sidebar-expand-database', + (databaseId: string, { connectionId }: { connectionId?: string } = {}) => { + try { + if (!connectionId) { + throw new Error('connectionId is not provided'); } - ); + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + void instance.databases + .get(databaseId) + ?.fetchCollections({ dataService }); + } catch (error) { + log.warn( + mongoLogId(1_001_000_323), + 'Instance Store', + 'Failed to respond to sidebar-expand-database', + { + message: (error as Error).message, + connectionId: connectionId, + } + ); + } + } + ); - on( - globalAppRegistry, - 'sidebar-filter-navigation-list', - fetchAllCollections + on( + globalAppRegistry, + 'sidebar-filter-navigation-list', + ({ connectionId }: { connectionId?: string } = {}) => { + const connectedConnectionIds = Array.from( + instancesManager.listMongoDBInstances().keys() ); + // connectionId will be provided by the sidebar when in single connection + // mode. We don't derive that from the list of connected connections + // because there is a possibility for us to be fetching all collections on + // wrong connection that way + const connectionIds = connectionId + ? [connectionId] + : connectedConnectionIds; + for (const id of connectionIds) { + void fetchAllCollections({ connectionId: id }); + } + } + ); - on(globalAppRegistry, 'refresh-data', refreshInstance); + on( + globalAppRegistry, + 'refresh-data', + ( + refreshOptions?: Omit< + Parameters[0], + 'dataService' + > + ) => { + for (const [connectionId] of instancesManager.listMongoDBInstances()) { + void refreshInstance(refreshOptions, { connectionId }); + } + } + ); - on( - globalAppRegistry, - 'database-dropped', - (dbName: string, { connectionId }: { connectionId?: string } = {}) => { - if (connectionId !== instanceConnectionId) { - return; - } + on( + globalAppRegistry, + 'database-dropped', + (dbName: string, { connectionId }: { connectionId?: string } = {}) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided in event parameters'); + } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); - const db = instance.databases.remove(dbName); - if (db) { - MongoDBInstance.removeAllListeners(db); + const db = instance.databases.remove(dbName); + if (db) { + MongoDBInstance.removeAllListeners(db); + } + } catch (error) { + log.warn( + mongoLogId(1_001_000_325), + 'Instance Store', + 'Failed to respond to database-dropped', + { + message: (error as Error).message, + connectionId: connectionId, } + ); + } + } + ); + + on( + globalAppRegistry, + 'collection-dropped', + (namespace: string, { connectionId }: { connectionId?: string } = {}) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided in event parameters'); } - ); - on( - globalAppRegistry, - 'collection-dropped', - ( - namespace: string, - { connectionId }: { connectionId?: string } = {} - ) => { - if (connectionId !== instanceConnectionId) { - return; - } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); + const { database } = toNS(namespace); + const db = instance.databases.get(database); + const coll = db?.collections.get(namespace, '_id'); - const { database } = toNS(namespace); - const db = instance.databases.get(database); - const coll = db?.collections.get(namespace, '_id'); + if (!db || !coll) { + return; + } - if (!db || !coll) { - return; + const isLastCollection = db.collections.length === 1; + + if (isLastCollection) { + instance.databases.remove(db); + MongoDBInstance.removeAllListeners(db); + } else { + db.collections.remove(coll); + MongoDBInstance.removeAllListeners(coll); + // Update db stats to account for db stats affected by collection stats + void db?.fetch({ dataService, force: true }).catch(() => { + // noop, we ignore stats fetching failures + }); + } + } catch (error) { + log.warn( + mongoLogId(1_001_000_317), + 'Instance Store', + 'Failed to respond to collection-dropped', + { + message: (error as Error).message, + connectionId: connectionId, } + ); + } + } + ); - const isLastCollection = db.collections.length === 1; - - if (isLastCollection) { - instance.databases.remove(db); - MongoDBInstance.removeAllListeners(db); - } else { - db.collections.remove(coll); - MongoDBInstance.removeAllListeners(coll); - // Update db stats to account for db stats affected by collection stats - void db?.fetch({ dataService, force: true }).catch(() => { - // noop, we ignore stats fetching failures - }); - } - } - ); + on(globalAppRegistry, 'refresh-databases', refreshDatabases); - on(globalAppRegistry, 'refresh-databases', refreshDatabases); + on( + globalAppRegistry, + 'collection-renamed', + ( + { from, to }: { from: string; to: string }, + { connectionId }: { connectionId?: string } = {} + ) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided in the event parameters'); + } + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); - on( - globalAppRegistry, - 'collection-renamed', - ( - { from, to }: { from: string; to: string }, - { connectionId }: { connectionId?: string } = {} - ) => { - if (connectionId !== instanceConnectionId) { - return; + const { database, collection } = toNS(from); + instance.databases + .get(database) + ?.collections.get(collection, 'name') + ?.set({ _id: to }); + } catch (err: any) { + log.warn( + mongoLogId(1_001_000_318), + 'Instance Store', + 'Failed to respond to collection-renamed', + { + message: (err as Error).message, + connectionId: connectionId, } + ); + } + } + ); - const { database, collection } = toNS(from); - instance.databases - .get(database) - ?.collections.get(collection, 'name') - ?.set({ _id: to }); - } - ); + on(globalAppRegistry, 'document-deleted', refreshNamespaceStats); + on(globalAppRegistry, 'document-inserted', refreshNamespaceStats); + on(globalAppRegistry, 'import-finished', refreshNamespaceStats); - on(globalAppRegistry, 'document-deleted', refreshNamespaceStats); - on(globalAppRegistry, 'document-inserted', refreshNamespaceStats); - on(globalAppRegistry, 'import-finished', refreshNamespaceStats); + on( + globalAppRegistry, + 'collection-created', + maybeAddAndRefreshCollectionModel + ); - on( - globalAppRegistry, - 'collection-created', - (ns: string, { connectionId }: { connectionId?: string } = {}) => { - if (connectionId === instanceConnectionId) { - void maybeAddAndRefreshCollectionModel(ns); - } - } - ); + on(globalAppRegistry, 'view-created', maybeAddAndRefreshCollectionModel); - on( - globalAppRegistry, - 'view-created', - (ns: string, { connectionId }: { connectionId?: string } = {}) => { - if (connectionId === instanceConnectionId) { - void maybeAddAndRefreshCollectionModel(ns); - } - } - ); + on( + globalAppRegistry, + 'agg-pipeline-out-executed', + // null means the out / merge stage destination wasn't a namespace in the + // same cluster + ( + namespace: string | null, + { connectionId }: { connectionId?: string } = {} + ) => { + if (!namespace) { + return; + } + void maybeAddAndRefreshCollectionModel(namespace, { connectionId }); + } + ); - on( - globalAppRegistry, - 'agg-pipeline-out-executed', - // null means the out / merge stage destination wasn't a namespace in the - // same cluster - (namespace: string | null) => { - if (!namespace) { - return; - } - void maybeAddAndRefreshCollectionModel(namespace); + on( + globalAppRegistry, + 'view-edited', + (namespace: string, { connectionId }: { connectionId?: string } = {}) => { + try { + if (!connectionId) { + throw new Error('No connectionId provided in the event parameters'); } - ); - - on(globalAppRegistry, 'view-edited', (namespace: string) => { + const instance = + instancesManager.getMongoDBInstanceForConnection(connectionId); + const dataService = + connectionsManager.getDataServiceForConnection(connectionId); const { database } = toNS(namespace); void instance.databases .get(database) ?.collections.get(namespace, '_id') ?.fetch({ dataService, force: true }); - }); + } catch (error) { + log.warn( + mongoLogId(1_001_000_321), + 'Instance Store', + 'Failed to respond to view-edited', + { + message: (error as Error).message, + connectionId: connectionId, + } + ); + } } ); diff --git a/packages/compass-collection/package.json b/packages/compass-collection/package.json index 48b11478ade..2ad81bbadd7 100644 --- a/packages/compass-collection/package.json +++ b/packages/compass-collection/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "4.32.0", + "version": "4.35.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,16 +48,17 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", - "mongodb-collection-model": "^5.21.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/mongodb-constants": "^0.10.2", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "mongodb-collection-model": "^5.22.1", "mongodb-ns": "^2.4.2", "numeral": "^2.0.6", "react": "^17.0.2", @@ -66,7 +67,7 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-collection/src/components/collection-header-actions/collection-header-actions.tsx b/packages/compass-collection/src/components/collection-header-actions/collection-header-actions.tsx index 167daf17b6e..bfc13543ff0 100644 --- a/packages/compass-collection/src/components/collection-header-actions/collection-header-actions.tsx +++ b/packages/compass-collection/src/components/collection-header-actions/collection-header-actions.tsx @@ -8,7 +8,9 @@ import { import { useConnectionInfo } from '@mongodb-js/compass-connections/provider'; import { useOpenWorkspace } from '@mongodb-js/compass-workspaces/provider'; import React from 'react'; -import { usePreference } from 'compass-preferences-model/provider'; +import { usePreferences } from 'compass-preferences-model/provider'; +import toNS from 'mongodb-ns'; +import { wrapField } from '@mongodb-js/mongodb-constants'; const collectionHeaderActionsStyles = css({ display: 'flex', @@ -17,6 +19,20 @@ const collectionHeaderActionsStyles = css({ gap: spacing[2], }); +function buildChartsUrl( + groupId: string, + clusterName: string, + namespace: string +) { + const { database, collection } = toNS(namespace); + const url = new URL(`/charts/${groupId}`, window.location.origin); + url.searchParams.set('sourceType', 'cluster'); + url.searchParams.set('instanceName', clusterName); + url.searchParams.set('database', database); + url.searchParams.set('collection', collection); + return url.toString(); +} + type CollectionHeaderActionsProps = { namespace: string; isReadonly: boolean; @@ -34,15 +50,58 @@ const CollectionHeaderActions: React.FunctionComponent< sourceName, sourcePipeline, }: CollectionHeaderActionsProps) => { - const { id: connectionId } = useConnectionInfo(); - const { openCollectionWorkspace, openEditViewWorkspace } = useOpenWorkspace(); - const preferencesReadOnly = usePreference('readOnly'); + const { id: connectionId, atlasMetadata } = useConnectionInfo(); + const { openCollectionWorkspace, openEditViewWorkspace, openShellWorkspace } = + useOpenWorkspace(); + const { + readOnly: preferencesReadOnly, + enableShell, + enableNewMultipleConnectionSystem, + } = usePreferences([ + 'readOnly', + 'enableShell', + 'enableNewMultipleConnectionSystem', + ]); + + const { database, collection } = toNS(namespace); + + const showOpenShellButton = enableShell && enableNewMultipleConnectionSystem; return (
+ {showOpenShellButton && ( + + )} + {atlasMetadata && ( + + )} {isReadonly && sourceName && !editViewName && !preferencesReadOnly && (
)}
-
- {children} + {typeof children === 'function' ? ( + children(scrollDetectionTrigger) + ) : ( + <> +
+ {children} + + )}
diff --git a/packages/compass-components/src/components/workspace-tabs/tab.tsx b/packages/compass-components/src/components/workspace-tabs/tab.tsx index 961fdbc57aa..3a498be3ff4 100644 --- a/packages/compass-components/src/components/workspace-tabs/tab.tsx +++ b/packages/compass-components/src/components/workspace-tabs/tab.tsx @@ -184,6 +184,8 @@ const selectedCloseButtonStyles = css({ type IconGlyph = Extract; type TabProps = { + connectionName?: string; + type: string; title: string; isSelected: boolean; isDragging: boolean; @@ -196,6 +198,8 @@ type TabProps = { }; function Tab({ + connectionName, + type, title, isSelected, isDragging, @@ -254,6 +258,8 @@ function Tab({ tabIndex={isSelected ? 0 : -1} aria-controls={tabContentId} data-testid="workspace-tab-button" + data-connectionName={connectionName} + data-type={type} title={subtitle ? subtitle : title} {...tabProps} > diff --git a/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx b/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx index 8d94e63901c..d1b2e9beb87 100644 --- a/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx +++ b/packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx @@ -170,6 +170,7 @@ type WorkspaceTabsProps = { export type TabProps = { id: string; + type: string; title: string; subtitle?: string; connectionId?: string; diff --git a/packages/compass-components/src/index.ts b/packages/compass-components/src/index.ts index 171fd1fd92c..7887f26c50e 100644 --- a/packages/compass-components/src/index.ts +++ b/packages/compass-components/src/index.ts @@ -199,3 +199,4 @@ export { useRequiredURLSearchParams, } from './components/links/link'; export { ChevronCollapse } from './components/chevron-collapse-icon'; +export { formatDate } from './utils/format-date'; diff --git a/packages/compass-connection-import-export/package.json b/packages/compass-connection-import-export/package.json index d37b84d6a91..40a31e3839a 100644 --- a/packages/compass-connection-import-export/package.json +++ b/packages/compass-connection-import-export/package.json @@ -14,7 +14,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.29.0", + "version": "0.32.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,15 +51,15 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/connection-storage": "^0.14.1", - "compass-preferences-model": "^2.23.1", - "hadron-ipc": "^3.2.16", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/connection-storage": "^0.16.0", + "compass-preferences-model": "^2.25.0", + "hadron-ipc": "^3.2.18", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-connections-navigation/package.json b/packages/compass-connections-navigation/package.json index abdf692ca68..98e88c094ca 100644 --- a/packages/compass-connections-navigation/package.json +++ b/packages/compass-connections-navigation/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.32.0", + "version": "1.35.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -47,19 +47,19 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "compass-preferences-model": "^2.23.1", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "compass-preferences-model": "^2.25.0", "mongodb-build-info": "^1.7.2", "react": "^17.0.2", "react-virtualized-auto-sizer": "^1.0.6", "react-window": "^1.8.6" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-connections-navigation/src/base-navigation-item.tsx b/packages/compass-connections-navigation/src/base-navigation-item.tsx index eaf751082ce..1e287cefbee 100644 --- a/packages/compass-connections-navigation/src/base-navigation-item.tsx +++ b/packages/compass-connections-navigation/src/base-navigation-item.tsx @@ -13,7 +13,8 @@ import { type NavigationItemActions } from './item-actions'; type NavigationBaseItemProps = { name: string; isActive: boolean; - canExpand: boolean; + isExpandVisible: boolean; + isExpandDisabled: boolean; isExpanded: boolean; isFocused: boolean; icon: React.ReactNode; @@ -91,7 +92,8 @@ export const NavigationBaseItem: React.FC = ({ style, icon, dataAttributes, - canExpand, + isExpandVisible, + isExpandDisabled, isExpanded, isFocused, onExpand, @@ -106,9 +108,10 @@ export const NavigationBaseItem: React.FC = ({ {...dataAttributes} >
- {canExpand && ( + {isExpandVisible && ( { + if (isExpandDisabled) return; evt.stopPropagation(); onExpand(!isExpanded); }} diff --git a/packages/compass-connections-navigation/src/connections-navigation-tree.spec.tsx b/packages/compass-connections-navigation/src/connections-navigation-tree.spec.tsx index a1660418191..706aac11d3e 100644 --- a/packages/compass-connections-navigation/src/connections-navigation-tree.spec.tsx +++ b/packages/compass-connections-navigation/src/connections-navigation-tree.spec.tsx @@ -286,6 +286,7 @@ describe('ConnectionsNavigationTree', function () { connections: mockedConnections, onItemAction: itemActionSpy, }); + expect(screen.getByLabelText('Lock Icon')).to.be.visible; expect(screen.getAllByLabelText('In-Use Encryption')).to.have.lengthOf(1); userEvent.click(screen.getByLabelText('In-Use Encryption')); @@ -307,6 +308,7 @@ describe('ConnectionsNavigationTree', function () { connections[2], ]; await renderConnectionsNavigationTree({ connections: mockedConnections }); + expect(screen.getByLabelText('Unlock Icon')).to.be.visible; expect(screen.getAllByLabelText('In-Use Encryption')).to.have.lengthOf(1); }); @@ -570,7 +572,10 @@ describe('ConnectionsNavigationTree', function () { userEvent.click(otherActions); expect(screen.getByText('Open MongoDB shell')).to.be.visible; - if (name !== 'when connection is datalake') { + if ( + name !== 'when connection is datalake' && + name !== 'when connection is not writable' + ) { expect( screen.getByTestId( 'sidebar-navigation-item-actions-open-shell-action' diff --git a/packages/compass-connections-navigation/src/navigation-item.tsx b/packages/compass-connections-navigation/src/navigation-item.tsx index 8a69dec605c..033d88b1fef 100644 --- a/packages/compass-connections-navigation/src/navigation-item.tsx +++ b/packages/compass-connections-navigation/src/navigation-item.tsx @@ -238,7 +238,7 @@ export function NavigationItem({ action: 'open-csfle-modal', label: 'In-Use Encryption', tooltip: 'Configure In-Use Encryption', - icon: 'Key', + icon: item.csfleMode === 'enabled' ? 'Lock' : 'Unlock', actionButtonClassName: cx(csfleBtnStyles, { [csfleBtnStylesDarkMode]: isDarkMode, }), @@ -261,7 +261,11 @@ export function NavigationItem({ name={item.name} style={style} dataAttributes={itemDataProps} - canExpand={item.isExpandable} + isExpandVisible={item.isExpandable} + isExpandDisabled={ + item.type === 'connection' && + item.connectionStatus === 'disconnected' + } onExpand={(isExpanded: boolean) => { onItemExpand(item, isExpanded); }} diff --git a/packages/compass-connections-navigation/src/tree-data.ts b/packages/compass-connections-navigation/src/tree-data.ts index 574b397f7d6..9d6b033bd83 100644 --- a/packages/compass-connections-navigation/src/tree-data.ts +++ b/packages/compass-connections-navigation/src/tree-data.ts @@ -170,7 +170,7 @@ const connectedConnectionToItems = ({ const colorCode = connectionInfo.favorite?.color; const hasWriteActionsDisabled = preferencesReadOnly || isDataLake || !isWritable; - const isShellEnabled = !preferencesReadOnly && isWritable; + const isShellEnabled = !preferencesReadOnly; const connectionTI: ConnectedConnectionTreeItem = { id: connectionInfo.id, level: 1, diff --git a/packages/compass-connections/package.json b/packages/compass-connections/package.json index aabc854bfa3..0e1048c080f 100644 --- a/packages/compass-connections/package.json +++ b/packages/compass-connections/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.33.0", + "version": "1.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,24 +51,24 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb-build-info": "^1.7.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-connections/src/components/connections-provider.tsx b/packages/compass-connections/src/components/connections-provider.tsx index 83b3f9a4cb4..ffd3392d297 100644 --- a/packages/compass-connections/src/components/connections-provider.tsx +++ b/packages/compass-connections/src/components/connections-provider.tsx @@ -1,7 +1,8 @@ import React, { useContext, useEffect, useRef } from 'react'; -import { useConnectionsManagerContext } from '../provider'; +import { type ConnectionInfo, useConnectionsManagerContext } from '../provider'; import { useConnections as useConnectionsStore } from '../stores/connections-store'; import { useConnectionRepository as useConnectionsRepositoryState } from '../hooks/use-connection-repository'; +import { createServiceLocator } from 'hadron-app-registry'; const ConnectionsStoreContext = React.createContext = F extends (...args: [infer A, ...any]) => any + ? A + : F extends { new (...args: [infer A, ...any]): any } + ? A + : never; + +function withConnectionRepository< + T extends ((...args: any[]) => any) | { new (...args: any[]): any } +>( + ReactComponent: T +): React.FunctionComponent, 'connectionRepository'>> { + const WithConnectionRepository = ( + props: Omit, 'connectionRepository'> & React.Attributes + ) => { + const connectionRepository = useConnectionRepository(); + return React.createElement(ReactComponent, { + ...props, + connectionRepository, + }); + }; + return WithConnectionRepository; +} + +export { withConnectionRepository }; + +export type ConnectionRepositoryAccess = Pick< + ConnectionRepository, + 'getConnectionInfoById' +>; + +export const useConnectionRepositoryAccess = (): ConnectionRepositoryAccess => { + const repository = useConnectionRepository(); + const repositoryRef = useRef(repository); + repositoryRef.current = repository; + return { + getConnectionInfoById(id: ConnectionInfo['id']) { + return repositoryRef.current.getConnectionInfoById(id); + }, + }; +}; +export const connectionRepositoryAccessLocator = createServiceLocator( + useConnectionRepositoryAccess, + 'connectionRepositoryAccessLocator' +); + export type ConnectionRepository = ReturnType; export { areConnectionsEqual } from '../hooks/use-connection-repository'; diff --git a/packages/compass-connections/src/components/connections.spec.tsx b/packages/compass-connections/src/components/legacy-connections.spec.tsx similarity index 99% rename from packages/compass-connections/src/components/connections.spec.tsx rename to packages/compass-connections/src/components/legacy-connections.spec.tsx index e55399ba9c3..10c4dd72c81 100644 --- a/packages/compass-connections/src/components/connections.spec.tsx +++ b/packages/compass-connections/src/components/legacy-connections.spec.tsx @@ -10,7 +10,7 @@ import { expect } from 'chai'; import type { ConnectionOptions, connect } from 'mongodb-data-service'; import { UUID } from 'bson'; import sinon from 'sinon'; -import Connections from './connections'; +import Connections from './legacy-connections'; import { ToastArea } from '@mongodb-js/compass-components'; import type { PreferencesAccess } from 'compass-preferences-model'; import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; diff --git a/packages/compass-connections/src/components/connections.tsx b/packages/compass-connections/src/components/legacy-connections.tsx similarity index 98% rename from packages/compass-connections/src/components/connections.tsx rename to packages/compass-connections/src/components/legacy-connections.tsx index 97c62c1a9b0..a13313dd91a 100644 --- a/packages/compass-connections/src/components/connections.tsx +++ b/packages/compass-connections/src/components/legacy-connections.tsx @@ -92,7 +92,7 @@ function Connections({ cancelConnectionAttempt, connect, createNewConnection, - duplicateConnection, + legacyDuplicateConnection: duplicateConnection, setActiveConnectionById, removeAllRecentsConnections, removeConnection, @@ -150,7 +150,7 @@ function Connections({ ); const onConnectClick = (connectionInfo: ConnectionInfo) => { - void connect({ ...cloneDeep(connectionInfo) }).catch(() => { + void connect({ ...cloneDeep(connectionInfo) }, true).catch(() => { // noop, we're logging in the connect method }); }; diff --git a/packages/compass-connections/src/connection-info-provider.tsx b/packages/compass-connections/src/connection-info-provider.tsx index 0fa714dc9c2..52fff988fa0 100644 --- a/packages/compass-connections/src/connection-info-provider.tsx +++ b/packages/compass-connections/src/connection-info-provider.tsx @@ -73,3 +73,28 @@ export const connectionInfoAccessLocator = createServiceLocator( useConnectionInfoAccess, 'connectionInfoAccessLocator' ); + +type FirstArgument = F extends (...args: [infer A, ...any]) => any + ? A + : F extends { new (...args: [infer A, ...any]): any } + ? A + : never; + +function withConnectionInfoAccess< + T extends ((...args: any[]) => any) | { new (...args: any[]): any } +>( + ReactComponent: T +): React.FunctionComponent, 'connectionInfoAccess'>> { + const WithConnectionInfoAccess = ( + props: Omit, 'connectionInfoAccess'> & React.Attributes + ) => { + const connectionInfoAccess = useConnectionInfoAccess(); + return React.createElement(ReactComponent, { + ...props, + connectionInfoAccess, + }); + }; + return WithConnectionInfoAccess; +} + +export { withConnectionInfoAccess }; diff --git a/packages/compass-connections/src/index.ts b/packages/compass-connections/src/index.ts index 64af9460de8..e0c553797a5 100644 --- a/packages/compass-connections/src/index.ts +++ b/packages/compass-connections/src/index.ts @@ -1,4 +1,4 @@ -import SingleConnectionForm from './components/connections'; +import SingleConnectionForm from './components/legacy-connections'; import { ConnectionsProvider } from './components/connections-provider'; export { LegacyConnectionsModal } from './components/legacy-connections-modal'; export { SingleConnectionForm }; diff --git a/packages/compass-connections/src/provider.ts b/packages/compass-connections/src/provider.ts index 890d4a3d4ee..1dcbf347b62 100644 --- a/packages/compass-connections/src/provider.ts +++ b/packages/compass-connections/src/provider.ts @@ -89,7 +89,10 @@ export { export { type ConnectionRepository, useConnectionRepository, + withConnectionRepository, areConnectionsEqual, + connectionRepositoryAccessLocator, + type ConnectionRepositoryAccess, } from './components/connections-provider'; export * from './connection-info-provider'; diff --git a/packages/compass-connections/src/stores/connections-store.spec.tsx b/packages/compass-connections/src/stores/connections-store.spec.tsx index eab7a74ffb1..5741ce1056a 100644 --- a/packages/compass-connections/src/stores/connections-store.spec.tsx +++ b/packages/compass-connections/src/stores/connections-store.spec.tsx @@ -275,7 +275,6 @@ describe('use-connections hook', function () { describe('#connect', function () { it(`calls onConnected`, async function () { const onConnected = sinon.spy(); - const saveSpy = sinon.spy(mockConnectionStorage, 'save'); const { result } = renderHookWithContext(() => useConnections({ onConnected, @@ -294,7 +293,6 @@ describe('use-connections hook', function () { await waitFor(() => { expect(onConnected).to.have.been.called; }); - expect(saveSpy).to.have.been.calledOnce; }); }); @@ -574,13 +572,8 @@ describe('use-connections hook', function () { }); }); - describe('#duplicateConnection', function () { - let hookResult: RenderResult>; - - it('should duplicate a connection', async function () { - const loadAllSpy = sinon.spy(mockConnectionStorage, 'loadAll'); - const saveSpy = sinon.spy(mockConnectionStorage, 'save'); - + describe('createDuplicateConnection', function () { + it('should create a connection duplicate and set it as the new active connection', async function () { const { result } = renderHookWithContext(() => useConnections({ onConnected: noop, @@ -592,19 +585,58 @@ describe('use-connections hook', function () { expect(result.current.favoriteConnections.length).to.equal(2); }); - result.current.setActiveConnectionById('turtle'); - result.current.duplicateConnection(result.current.favoriteConnections[0]); + const original = result.current.favoriteConnections[0]; + result.current.createDuplicateConnection(original); + + const duplicate = result.current.state.activeConnectionInfo; + + expect(duplicate).to.haveOwnProperty('id'); + expect(duplicate.id).not.to.equal(original.id); + expect(result.current.state.activeConnectionId).to.equal(duplicate.id); + delete original.id; + delete duplicate.id; + expect(duplicate).to.deep.equal({ + ...original, + favorite: { + ...original.favorite, + name: `${original.favorite.name} (1)`, + }, + }); + }); + it('should increment (number) appendix', async function () { + mockConnectionStorage = new InMemoryConnectionStorage([ + mockConnections[0], + { + ...mockConnections[0], + favorite: { + ...mockConnections[0].favorite, + name: `${mockConnections[0].favorite.name} (1)`, + }, + }, + ]); + const { result } = renderHookWithContext(() => + useConnections({ + onConnected: noop, + onConnectionFailed: noop, + onConnectionAttemptStarted: noop, + }) + ); await waitFor(() => { - expect(loadAllSpy).to.have.been.called; - expect(saveSpy.callCount).to.equal(1); + expect(result.current.favoriteConnections.length).to.equal(2); }); - hookResult = result; - }); + const original = result.current.favoriteConnections[0]; // copying the original + result.current.createDuplicateConnection(original); + const duplicate = result.current.state.activeConnectionInfo; + expect(duplicate.favorite.name).to.equal(`${original.favorite.name} (2)`); - it('should set the duplicated connection as current active', function () { - expect(hookResult.current.state.activeConnectionId).to.not.equal(null); + const copy = result.current.favoriteConnections[1]; // copying the copy + result.current.createDuplicateConnection(copy); + const duplicate2 = result.current.state.activeConnectionInfo; + expect(duplicate2.favorite.name).to.equal( + `${original.favorite.name} (2)` + ); }); }); diff --git a/packages/compass-connections/src/stores/connections-store.tsx b/packages/compass-connections/src/stores/connections-store.tsx index 70eba793d9e..56158ab2f51 100644 --- a/packages/compass-connections/src/stores/connections-store.tsx +++ b/packages/compass-connections/src/stores/connections-store.tsx @@ -178,13 +178,17 @@ export function useConnections({ cancelConnectionAttempt: ( connectionId: ConnectionInfo['id'] ) => Promise; - connect: (connectionInfo: ConnectionInfo) => Promise; + connect: ( + connectionInfo: ConnectionInfo, + legacyShouldSaveConnectionInfo?: boolean + ) => Promise; closeConnection: (connectionId: ConnectionInfo['id']) => Promise; createNewConnection: () => void; + createDuplicateConnection: (connectionInfo: ConnectionInfo) => void; saveConnection: (connectionInfo: ConnectionInfo) => Promise; setActiveConnectionById: (newConnectionId: string) => void; removeAllRecentsConnections: () => Promise; - duplicateConnection: (connectionInfo: ConnectionInfo) => void; + legacyDuplicateConnection: (connectionInfo: ConnectionInfo) => void; removeConnection: (connectionInfo: ConnectionInfo) => void; } { // TODO(COMPASS-7397): services should not be used directly in render method, @@ -292,12 +296,12 @@ export function useConnections({ async ( connectionInfo: ConnectionInfo, dataService: DataService, - shouldSaveConnectionInfo: boolean + legacyShouldSaveConnectionInfo?: boolean // TODO: cleanup COMPASS-7906 ) => { try { dispatch({ type: 'set-active-connection', connectionInfo }); onConnected?.(connectionInfo, dataService); - if (!shouldSaveConnectionInfo) return; + if (!legacyShouldSaveConnectionInfo) return; let mergeConnectionInfo = {}; if (persistOIDCTokens) { @@ -358,7 +362,7 @@ export function useConnections({ _connectionInfo: | ConnectionInfo | (() => Promise), - shouldSaveConnectionInfo = true + legacyShouldSaveConnectionInfo?: boolean ) => { const isAutoconnectAttempt = typeof _connectionInfo === 'function'; let connectionInfo: ConnectionInfo; @@ -425,7 +429,7 @@ export function useConnections({ void onConnectSuccess( connectionInfo, newConnectionDataService, - shouldSaveConnectionInfo + legacyShouldSaveConnectionInfo ); debug( @@ -519,14 +523,24 @@ export function useConnections({ removeConnection(connectionInfo) { void removeConnection(connectionInfo); }, - duplicateConnection(connectionInfo: ConnectionInfo) { + legacyDuplicateConnection(connectionInfo: ConnectionInfo) { + const findConnectionByFavoriteName = (name: string) => + [...favoriteConnections, ...recentConnections].find( + (connection: ConnectionInfo) => connection.favorite?.name === name + ); const duplicate: ConnectionInfo = { ...cloneDeep(connectionInfo), id: new UUID().toString(), }; if (duplicate.favorite?.name) { - duplicate.favorite.name += ' (copy)'; + const copyFormat = duplicate.favorite?.name.match(/(.*)\s\(([0-9])+\)/); // title (2) -> [title (2), title, 2] + const name = copyFormat ? copyFormat[1] : duplicate.favorite?.name; + let copyNumber = copyFormat ? parseInt(copyFormat[2]) : 1; + while (findConnectionByFavoriteName(`${name} (${copyNumber})`)) { + copyNumber++; + } + duplicate.favorite.name = `${name} (${copyNumber})`; } void saveConnectionInfo(duplicate).then( @@ -541,6 +555,32 @@ export function useConnections({ } ); }, + createDuplicateConnection(connectionInfo: ConnectionInfo) { + const findConnectionByFavoriteName = (name: string) => + [...favoriteConnections, ...recentConnections].find( + (connection: ConnectionInfo) => connection.favorite?.name === name + ); + + const duplicate: ConnectionInfo = { + ...cloneDeep(connectionInfo), + id: new UUID().toString(), + }; + + if (duplicate.favorite?.name) { + const copyFormat = duplicate.favorite?.name.match(/(.*)\s\(([0-9])+\)/); // title (2) -> [title (2), title, 2] + const name = copyFormat ? copyFormat[1] : duplicate.favorite?.name; + let copyNumber = copyFormat ? parseInt(copyFormat[2]) : 1; + while (findConnectionByFavoriteName(`${name} (${copyNumber})`)) { + copyNumber++; + } + duplicate.favorite.name = `${name} (${copyNumber})`; + } + + dispatch({ + type: 'new-connection', + connectionInfo: duplicate, + }); + }, async removeAllRecentsConnections() { await Promise.all( recentConnections.map((info) => deleteConnection(info)) diff --git a/packages/compass-crud/package.json b/packages/compass-crud/package.json index 22dcbe83fc9..e120ead802e 100644 --- a/packages/compass-crud/package.json +++ b/packages/compass-crud/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "13.33.0", + "version": "13.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,8 +48,8 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -59,44 +59,44 @@ "chai": "^4.1.2", "chai-as-promised": "^7.1.1", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "nyc": "^15.1.0", "react-dom": "^17.0.2", "sinon": "^8.1.1", "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/explain-plan-helper": "^1.1.13", - "@mongodb-js/my-queries-storage": "^0.10.0", - "@mongodb-js/reflux-state-mixin": "^1.0.2", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/explain-plan-helper": "^1.1.14", + "@mongodb-js/my-queries-storage": "^0.13.0", + "@mongodb-js/reflux-state-mixin": "^1.0.3", + "@mongodb-js/shell-bson-parser": "^1.1.0", "ag-grid-community": "^20.2.0", "ag-grid-react": "^20.2.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "hadron-type-checker": "^7.2.2", "jsondiffpatch": "^0.5.0", "lodash": "^4.17.21", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "prop-types": "^15.7.2", "react": "^17.0.2", "reflux": "^0.4.1", diff --git a/packages/compass-crud/src/components/crud-toolbar.tsx b/packages/compass-crud/src/components/crud-toolbar.tsx index 755122f89d7..eb428ebce6f 100644 --- a/packages/compass-crud/src/components/crud-toolbar.tsx +++ b/packages/compass-crud/src/components/crud-toolbar.tsx @@ -19,6 +19,7 @@ import { usePreference } from 'compass-preferences-model/provider'; import UpdateMenu from './update-data-menu'; import DeleteMenu from './delete-data-menu'; import { QueryBar } from '@mongodb-js/compass-query-bar'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const crudQueryBarStyles = css({ width: '100%', @@ -139,6 +140,7 @@ const CrudToolbar: React.FunctionComponent = ({ querySkip, }) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const isImportExportEnabled = usePreference('enableImportExport'); const displayedDocumentCount = useMemo( @@ -147,9 +149,13 @@ const CrudToolbar: React.FunctionComponent = ({ ); const onClickRefreshDocuments = useCallback(() => { - track('Query Results Refreshed'); + track( + 'Query Results Refreshed', + {}, + connectionInfoAccess.getCurrentConnectionInfo() + ); refreshDocuments(); - }, [refreshDocuments, track]); + }, [refreshDocuments, track, connectionInfoAccess]); const prevButtonDisabled = useMemo(() => page === 0, [page]); const nextButtonDisabled = useMemo( diff --git a/packages/compass-crud/src/index.ts b/packages/compass-crud/src/index.ts index a69493b2fc4..e20f4778359 100644 --- a/packages/compass-crud/src/index.ts +++ b/packages/compass-crud/src/index.ts @@ -27,7 +27,7 @@ import { } from '@mongodb-js/my-queries-storage/provider'; import { fieldStoreServiceLocator } from '@mongodb-js/compass-field-store'; import { queryBarServiceLocator } from '@mongodb-js/compass-query-bar'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; export const CompassDocumentsHadronPlugin = registerHadronPlugin( { @@ -43,7 +43,7 @@ export const CompassDocumentsHadronPlugin = registerHadronPlugin( instance: mongoDBInstanceLocator, preferences: preferencesLocator, logger: createLoggerLocator('COMPASS-CRUD-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, favoriteQueryStorageAccess: favoriteQueryStorageAccessLocator, recentQueryStorageAccess: recentQueryStorageAccessLocator, fieldStoreService: fieldStoreServiceLocator, diff --git a/packages/compass-crud/src/stores/crud-store.ts b/packages/compass-crud/src/stores/crud-store.ts index 8fe25894d2e..493b5edcb8f 100644 --- a/packages/compass-crud/src/stores/crud-store.ts +++ b/packages/compass-crud/src/stores/crud-store.ts @@ -7,7 +7,7 @@ import StateMixin from '@mongodb-js/reflux-state-mixin'; import type { Element } from 'hadron-document'; import { Document } from 'hadron-document'; import HadronDocument from 'hadron-document'; -import _parseShellBSON, { ParseMode } from 'ejson-shell-parser'; +import _parseShellBSON, { ParseMode } from '@mongodb-js/shell-bson-parser'; import type { PreferencesAccess } from 'compass-preferences-model/provider'; import { capMaxTimeMSAtPreferenceLimit } from 'compass-preferences-model/provider'; import type { Stage } from '@mongodb-js/explain-plan-helper'; @@ -335,6 +335,7 @@ class CrudStoreImpl fieldStoreService: FieldStoreService; logger: Logger; track: TrackFunction; + connectionInfoAccess: ConnectionInfoAccess; instance: MongoDBInstance; connectionScopedAppRegistry: ConnectionScopedAppRegistry; queryBar: QueryBarService; @@ -349,6 +350,7 @@ class CrudStoreImpl | 'preferences' | 'logger' | 'track' + | 'connectionInfoAccess' | 'fieldStoreService' | 'connectionScopedAppRegistry' | 'queryBar' @@ -366,6 +368,7 @@ class CrudStoreImpl this.preferences = services.preferences; this.logger = services.logger; this.track = services.track; + this.connectionInfoAccess = services.connectionInfoAccess; this.instance = services.instance; this.fieldStoreService = services.fieldStoreService; this.connectionScopedAppRegistry = services.connectionScopedAppRegistry; @@ -478,7 +481,11 @@ class CrudStoreImpl * @returns {Boolean} If the copy succeeded. */ copyToClipboard(doc: Document) { - this.track('Document Copied', { mode: this.modeForTelemetry() }); + this.track( + 'Document Copied', + { mode: this.modeForTelemetry() }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); const documentEJSON = doc.toEJSON(); // eslint-disable-next-line no-undef void navigator.clipboard.writeText(documentEJSON); @@ -490,7 +497,11 @@ class CrudStoreImpl * @param {Document} doc - The hadron document. */ async removeDocument(doc: Document) { - this.track('Document Deleted', { mode: this.modeForTelemetry() }); + this.track( + 'Document Deleted', + { mode: this.modeForTelemetry() }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); const id = doc.getId(); if (id !== undefined) { doc.emit('remove-start'); @@ -558,7 +569,11 @@ class CrudStoreImpl * @param {Document} doc - The hadron document. */ async updateDocument(doc: Document) { - this.track('Document Updated', { mode: this.modeForTelemetry() }); + this.track( + 'Document Updated', + { mode: this.modeForTelemetry() }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); try { doc.emit('update-start'); // We add the shard keys here, if there are any, because that is @@ -624,7 +639,11 @@ class CrudStoreImpl * @param {Document} doc - The hadron document. */ async replaceDocument(doc: Document) { - this.track('Document Updated', { mode: this.modeForTelemetry() }); + this.track( + 'Document Updated', + { mode: this.modeForTelemetry() }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); try { doc.emit('update-start'); @@ -863,7 +882,11 @@ class CrudStoreImpl const hadronDoc = new HadronDocument(doc); if (clone) { - this.track('Document Cloned', { mode: this.modeForTelemetry() }); + this.track( + 'Document Cloned', + { mode: this.modeForTelemetry() }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); // We need to remove the _id or we will get an duplicate key error on // insert, and we currently do not allow editing of the _id field. for (const element of hadronDoc.elements) { @@ -922,9 +945,13 @@ class CrudStoreImpl } async openBulkUpdateModal(updateText?: string) { - this.track('Bulk Update Opened', { - isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, - }); + this.track( + 'Bulk Update Opened', + { + isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, + }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); await this.updateBulkUpdatePreview(updateText ?? INITIAL_BULK_UPDATE_TEXT); this.setState({ @@ -1068,9 +1095,13 @@ class CrudStoreImpl } async runBulkUpdate() { - this.track('Bulk Update Executed', { - isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, - }); + this.track( + 'Bulk Update Executed', + { + isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, + }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); this.closeBulkUpdateModal(); @@ -1247,10 +1278,14 @@ class CrudStoreImpl const docs = HadronDocument.FromEJSONArray( this.state.insert.jsonDoc ?? '' ).map((doc) => doc.generateObject()); - this.track('Document Inserted', { - mode: this.state.insert.jsonView ? 'json' : 'field-by-field', - multiple: docs.length > 1, - }); + this.track( + 'Document Inserted', + { + mode: this.state.insert.jsonView ? 'json' : 'field-by-field', + multiple: docs.length > 1, + }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); try { await this.dataService.insertMany(this.state.ns, docs); @@ -1297,10 +1332,14 @@ class CrudStoreImpl * view to insert. */ async insertDocument() { - this.track('Document Inserted', { - mode: this.state.insert.jsonView ? 'json' : 'field-by-field', - multiple: false, - }); + this.track( + 'Document Inserted', + { + mode: this.state.insert.jsonView ? 'json' : 'field-by-field', + multiple: false, + }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); let doc: BSONObject; @@ -1452,21 +1491,25 @@ class CrudStoreImpl if (onApply) { const { isTimeSeries, isReadonly } = this.state; - this.track('Query Executed', { - has_projection: - !!query.project && Object.keys(query.project).length > 0, - has_skip: (query.skip ?? 0) > 0, - has_sort: !!query.sort && Object.keys(query.sort).length > 0, - has_limit: (query.limit ?? 0) > 0, - has_collation: !!query.collation, - changed_maxtimems: query.maxTimeMS !== DEFAULT_INITIAL_MAX_TIME_MS, - collection_type: isTimeSeries - ? 'time-series' - : isReadonly - ? 'readonly' - : 'collection', - used_regex: objectContainsRegularExpression(query.filter ?? {}), - }); + this.track( + 'Query Executed', + { + has_projection: + !!query.project && Object.keys(query.project).length > 0, + has_skip: (query.skip ?? 0) > 0, + has_sort: !!query.sort && Object.keys(query.sort).length > 0, + has_limit: (query.limit ?? 0) > 0, + has_collation: !!query.collation, + changed_maxtimems: query.maxTimeMS !== DEFAULT_INITIAL_MAX_TIME_MS, + collection_type: isTimeSeries + ? 'time-series' + : isReadonly + ? 'readonly' + : 'collection', + used_regex: objectContainsRegularExpression(query.filter ?? {}), + }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); } // pass the signal so that the queries can close their own cursors and @@ -1702,7 +1745,11 @@ class CrudStoreImpl } openBulkDeleteDialog() { - this.track('Bulk Delete Opened'); + this.track( + 'Bulk Delete Opened', + {}, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); const PREVIEW_DOCS = 5; @@ -1767,7 +1814,11 @@ class CrudStoreImpl } async runBulkDelete() { - this.track('Bulk Delete Executed'); + this.track( + 'Bulk Delete Executed', + {}, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); const { affected } = this.state.bulkDelete; this.closeBulkDeleteDialog(); @@ -1807,9 +1858,13 @@ class CrudStoreImpl } async saveUpdateQuery(name: string): Promise { - this.track('Bulk Update Favorited', { - isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, - }); + this.track( + 'Bulk Update Favorited', + { + isUpdatePreviewSupported: this.state.isUpdatePreviewSupported, + }, + this.connectionInfoAccess.getCurrentConnectionInfo() + ); const { filter } = this.queryBar.getLastAppliedQuery('crud'); let update; @@ -1884,6 +1939,7 @@ export function activateDocumentsPlugin( preferences, logger, track, + connectionInfoAccess, favoriteQueryStorage: favoriteQueryStorageAccess?.getStorage(), recentQueryStorage: recentQueryStorageAccess?.getStorage(), fieldStoreService, diff --git a/packages/compass-e2e-tests/helpers/commands/close-shell.ts b/packages/compass-e2e-tests/helpers/commands/close-shell.ts new file mode 100644 index 00000000000..96e66d4df0a --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/close-shell.ts @@ -0,0 +1,23 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; +import type { CompassBrowser } from '../compass-browser'; +import retryWithBackoff from '../retry-with-backoff'; +import * as Selectors from '../selectors'; + +export async function closeShell( + browser: CompassBrowser, + connectionName: string +): Promise { + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.closeWorkspaceTab({ + connectionName, + type: 'Shell', + }); + } else { + await retryWithBackoff(async function () { + const shellContentElement = await browser.$(Selectors.ShellContent); + if (await shellContentElement.isDisplayed()) { + await browser.clickVisible(Selectors.ShellExpandButton); + } + }); + } +} diff --git a/packages/compass-e2e-tests/helpers/commands/close-workspace-tabs.ts b/packages/compass-e2e-tests/helpers/commands/close-workspace-tabs.ts deleted file mode 100644 index abf855745f7..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/close-workspace-tabs.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { CompassBrowser } from '../compass-browser'; -import * as Selectors from '../selectors'; - -export async function closeWorkspaceTabs( - browser: CompassBrowser, - autoConfirmTabClose = true -): Promise { - const countTabs = async () => { - return (await browser.$$(Selectors.workspaceTab(null))).length; - }; - - while ((await countTabs()) > 0) { - const currentActiveTab = await browser.$( - Selectors.workspaceTab(null, true) - ); - await currentActiveTab.click(); - await browser.waitUntil(async () => { - await currentActiveTab.$(Selectors.CloseWorkspaceTab).click(); - if (autoConfirmTabClose) { - // Tabs in "dirty" state can't be closed without confirmation - if (await browser.$(Selectors.ConfirmTabCloseModal).isExisting()) { - await browser.clickVisible( - browser.$(Selectors.ConfirmTabCloseModal).$('button=Close tab') - ); - } - } - return (await currentActiveTab.isExisting()) === false; - }); - } -} diff --git a/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts b/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts index 7399dca5ee5..25b1ce6c7ba 100644 --- a/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts +++ b/packages/compass-e2e-tests/helpers/commands/collection-workspaces.ts @@ -1,9 +1,11 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; async function navigateToCollection( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account + connectionName: string, dbName: string, collectionName: string, @@ -12,7 +14,10 @@ async function navigateToCollection( // state of Schema, and Validation tabs without re-connecting. closeExistingTabs = true ): Promise { + const connectionId = await browser.getConnectionIdByName(connectionName); + const collectionSelector = Selectors.sidebarCollection( + connectionId, dbName, collectionName ); @@ -23,19 +28,27 @@ async function navigateToCollection( // search for the collection and wait for the collection to be there and visible await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, collectionName); + await browser.setValueVisible( + Selectors.SidebarFilterInput, + `^(${dbName}|${collectionName})$` + ); const collectionElement = await browser.$(collectionSelector); await collectionElement.waitForDisplayed(); // click it and wait for the collection header to become visible await browser.clickVisible(collectionSelector); - await waitUntilActiveCollectionTab(browser, dbName, collectionName); + await waitUntilActiveCollectionTab( + browser, + connectionName, + dbName, + collectionName + ); } export async function navigateToCollectionTab( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account + connectionName: string, dbName: string, collectionName: string, tabName: @@ -48,6 +61,7 @@ export async function navigateToCollectionTab( ): Promise { await navigateToCollection( browser, + connectionName, dbName, collectionName, closeExistingTabs @@ -57,7 +71,6 @@ export async function navigateToCollectionTab( export async function navigateWithinCurrentCollectionTabs( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account tabName: | 'Documents' | 'Aggregations' @@ -77,9 +90,9 @@ export async function navigateWithinCurrentCollectionTabs( await waitUntilActiveCollectionSubTab(browser, tabName); } -export async function waitUntilActiveCollectionTab( +async function waitUntilActiveCollectionTab( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account + connectionName: string, dbName: string, collectionName: string, tabName: @@ -90,9 +103,17 @@ export async function waitUntilActiveCollectionTab( | 'Validation' | null = null ) { - await browser - .$(Selectors.collectionWorkspaceTab(`${dbName}.${collectionName}`, true)) - .waitForDisplayed(); + const options: WorkspaceTabSelectorOptions = { + namespace: `${dbName}.${collectionName}`, + active: true, + }; + // Only add the connectionName for multiple connections because for some + // reason this sometimes flakes in single connections even though the tab is + // definitely there in the screenshot. + if (TEST_MULTIPLE_CONNECTIONS) { + options.connectionName = connectionName; + } + await browser.$(Selectors.workspaceTab(options)).waitForDisplayed(); if (tabName) { await waitUntilActiveCollectionSubTab(browser, tabName); } @@ -100,7 +121,6 @@ export async function waitUntilActiveCollectionTab( export async function waitUntilActiveCollectionSubTab( browser: CompassBrowser, - // TODO(COMPASS-8002): take connectionName into account tabName: | 'Documents' | 'Aggregations' @@ -113,7 +133,7 @@ export async function waitUntilActiveCollectionSubTab( export async function getActiveTabNamespace(browser: CompassBrowser) { const activeWorkspaceNamespace = await browser - .$(Selectors.workspaceTab(null, true)) + .$(Selectors.workspaceTab({ active: true })) .getAttribute('data-namespace'); return activeWorkspaceNamespace || null; } diff --git a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts index fc2ba18b529..7f862622192 100644 --- a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts +++ b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-form.ts @@ -1,6 +1,5 @@ import type { CompassBrowser } from '../compass-browser'; import type { ConnectFormState } from '../connect-form-state'; -import * as Selectors from '../selectors'; export async function connectWithConnectionForm( browser: CompassBrowser, @@ -8,9 +7,13 @@ export async function connectWithConnectionForm( connectionStatus: 'success' | 'failure' | 'either' = 'success', timeout?: number ): Promise { - const sidebar = await browser.$(Selectors.SidebarTitle); - if (await sidebar.isDisplayed()) { - await browser.disconnect(); + await browser.disconnectAll(); + + // If a connectionName is specified and a connection already exists with this + // name, make sure we don't add a duplicate so that tests can always address + // this new connection. + if (options.connectionName) { + await browser.removeConnection(options.connectionName); } await browser.setConnectFormState(options); diff --git a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts index aba0aa08649..c2adc7117d3 100644 --- a/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts +++ b/packages/compass-e2e-tests/helpers/commands/connect-with-connection-string.ts @@ -12,7 +12,7 @@ export async function connectWithConnectionString( connectionStatus: 'success' | 'failure' | 'either' = 'success', timeout?: number ): Promise { - await browser.disconnect(); + await browser.disconnectAll(); if (TEST_MULTIPLE_CONNECTIONS) { // if the modal is still animating away when we're connecting again, things @@ -24,25 +24,7 @@ export async function connectWithConnectionString( // if a connection with this name already exists, remove it otherwise we'll // add a duplicate and things will get complicated fast const connectionName = connectionNameFromString(connectionString); - - // make sure there's no filter because if the connection is not displayed then we can't remove it - if (await browser.$(Selectors.SidebarFilterInput).isExisting()) { - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, ''); - - // wait for a connection to appear. It must because if there are no - // connections the filter field wouldn't exist in the first place - await browser.$(Selectors.SidebarTreeItems).waitForDisplayed(); - } - - const selector = Selectors.sidebarConnection(connectionName); - if (await browser.$(selector).isExisting()) { - await browser.selectConnectionMenuItem( - connectionName, - Selectors.Multiple.RemoveConnectionItem - ); - await browser.$(selector).waitForExist({ reverse: true }); - } + await browser.removeConnection(connectionName); await browser.clickVisible(Selectors.Multiple.SidebarNewConnectionButton); await browser.$(Selectors.ConnectionModal).waitForDisplayed(); @@ -53,25 +35,4 @@ export async function connectWithConnectionString( connectionString ); await browser.doConnect(connectionStatus, timeout); - - // Ideally this would be part of browser.doConnect() and - // browser.waitForConnectionResult(), but that requires the context of - // connectionName there. Which is easy enough for connectWithConnectionString, - // but not so easy right now for connectWithConnectionForm. - if (TEST_MULTIPLE_CONNECTIONS) { - // There's a potential problem here: The list of connections is virtual, so - // the new connection might not be rendered. By searching for it if possible - // we can guarantee that it will be on screen. The search box won't exist - // for the first connection, but that's OK because once connected it will be - // the only connection so should be rendered. - if (await browser.$(Selectors.SidebarFilterInput).isExisting()) { - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, ''); - } - - // some connection should be expanded (ie. connected) by now - await browser - .$(`${Selectors.SidebarTreeItems} [aria-expanded=true]`) - .waitForExist({ reverse: true }); - } } diff --git a/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts b/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts index baa80b08dfd..a59a2c88cfb 100644 --- a/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts +++ b/packages/compass-e2e-tests/helpers/commands/connection-workspaces.ts @@ -1,6 +1,7 @@ import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; export async function navigateToConnectionTab( browser: CompassBrowser, @@ -30,8 +31,13 @@ export async function waitUntilActiveConnectionTab( connectionName: string, tabName: 'Performance' | 'Databases' ) { - // TODO(COMPASS-8002): we should differentiate by connectionName somehow - await browser - .$(Selectors.connectionWorkspaceTab(tabName, true)) - .waitForDisplayed(); + const options: WorkspaceTabSelectorOptions = { title: tabName, active: true }; + + // Only add the connectionName for multiple connections because for some + // reason this sometimes flakes in single connections even though the tab is + // definitely there in the screenshot. + if (TEST_MULTIPLE_CONNECTIONS) { + options.connectionName = connectionName; + } + await browser.$(Selectors.workspaceTab(options)).waitForDisplayed(); } diff --git a/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts b/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts index 666d5caefd6..48bc4df4efc 100644 --- a/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts +++ b/packages/compass-e2e-tests/helpers/commands/database-workspaces.ts @@ -1,5 +1,7 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; export async function navigateToDatabaseCollectionsTab( browser: CompassBrowser, @@ -16,8 +18,14 @@ export async function waitUntilActiveDatabaseTab( connectionName: string, dbName: string ) { - // TODO(COMPASS-8002): check that the connectionName matches too - await browser - .$(Selectors.databaseWorkspaceTab(dbName, true)) - .waitForDisplayed(); + const options: WorkspaceTabSelectorOptions = { title: dbName, active: true }; + + // Only add the connectionName for multiple connections because for some + // reason this sometimes flakes in single connections even though the tab is + // definitely there in the screenshot. + if (TEST_MULTIPLE_CONNECTIONS) { + options.connectionName = connectionName; + } + + await browser.$(Selectors.workspaceTab(options)).waitForDisplayed(); } diff --git a/packages/compass-e2e-tests/helpers/commands/disconnect.ts b/packages/compass-e2e-tests/helpers/commands/disconnect.ts index 677bd156b8b..881a442d2fe 100644 --- a/packages/compass-e2e-tests/helpers/commands/disconnect.ts +++ b/packages/compass-e2e-tests/helpers/commands/disconnect.ts @@ -7,7 +7,14 @@ import Debug from 'debug'; const debug = Debug('compass-e2e-tests'); -export async function disconnect(browser: CompassBrowser): Promise { +export async function disconnectAll( + browser: CompassBrowser, + { + closeToasts = true, + }: { + closeToasts?: boolean; + } = {} +): Promise { if (TEST_COMPASS_WEB) { const url = new URL(await browser.getUrl()); url.pathname = '/'; @@ -44,7 +51,7 @@ export async function disconnect(browser: CompassBrowser): Promise { // no active connections left. Use a different command if you expect to // disconnect just one connection and still keep others around. await browser - .$(`${Selectors.SidebarTreeItems} [aria-expanded=true]`) + .$(`${Selectors.SidebarTreeItems}[aria-expanded=true]`) .waitForExist({ reverse: true }); // The potential problem here is that the list is virtual, so it is possible @@ -52,14 +59,20 @@ export async function disconnect(browser: CompassBrowser): Promise { // enough. For now just wait an extra second just in case. await browser.pause(1000); - // If we disconnected "too soon" and we get an error like "Failed to - // retrieve server info" or similar, there might be an error or warning - // toast by now. If so, just close it otherwise the next test or connection - // attempt will be confused by it. - if (await browser.$(Selectors.AnyToastDismissButton).isExisting()) { - const toastText = await browser.$('#lg-toast-region').getText(); - debug('Closing toast', toastText); - await browser.clickVisible(Selectors.AnyToastDismissButton); + if (closeToasts) { + // If we disconnected "too soon" and we get an error like "Failed to + // retrieve server info" or similar, there might be an error or warning + // toast by now. If so, just close it otherwise the next test or connection + // attempt will be confused by it. + if (await browser.$(Selectors.LGToastCloseButton).isExisting()) { + try { + const toastText = await browser.$('#lg-toast-region').getText(); + debug('Closing toast', toastText); + await browser.clickVisible(Selectors.LGToastCloseButton); + } catch (error) { + debug('ignoring', error); + } + } } // NOTE: unlike the single connection flow this doesn't make sure the New diff --git a/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts b/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts index e60ee3f3e9e..900d81e9740 100644 --- a/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts +++ b/packages/compass-e2e-tests/helpers/commands/drop-collection-from-sidebar.ts @@ -3,40 +3,25 @@ import * as Selectors from '../selectors'; export async function dropCollectionFromSidebar( browser: CompassBrowser, - dbName: string, + connectionName: string, + databaseName: string, collectionName: string ): Promise { - // search for the collecton in the sidebar filter - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, collectionName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); - await dbElement.waitForDisplayed(); + await browser.selectCollectionMenuItem( + connectionName, + databaseName, + collectionName, + 'drop-collection' + ); + await browser.dropNamespace(collectionName); - // wait for the collection to become displayed + // wait for it to be gone + const connectionId = await browser.getConnectionIdByName(connectionName); const collectionSelector = Selectors.sidebarCollection( - dbName, + connectionId, + databaseName, collectionName ); - await browser.scrollToVirtualItem( - Selectors.SidebarNavigationTree, - collectionSelector, - 'tree' - ); const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); - - // open the drop collection modal from the sidebar - await browser.hover(collectionSelector); - - // NOTE: if the menu was already open for another collection this could get - // confusing. Also this selector is just for the actions button and it is - // assumed that at this point it is the only one. But the drop confirmation - // usually catches that. - await browser.clickVisible(Selectors.SidebarNavigationItemShowActionsButton); - await browser.clickVisible(Selectors.DropCollectionButton); - - await browser.dropNamespace(collectionName); - - // wait for it to be gone await collectionElement.waitForExist({ reverse: true }); } diff --git a/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts b/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts index 6ccb0be9a44..5b23a405abe 100644 --- a/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts +++ b/packages/compass-e2e-tests/helpers/commands/drop-database-from-sidebar.ts @@ -3,15 +3,20 @@ import * as Selectors from '../selectors'; export async function dropDatabaseFromSidebar( browser: CompassBrowser, + connectionName: string, dbName: string ): Promise { + const connectionId = await browser.getConnectionIdByName(connectionName); + // search for the database in the sidebar filter await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - await browser.$(Selectors.sidebarDatabase(dbName)).waitForDisplayed(); + await browser + .$(Selectors.sidebarDatabase(connectionId, dbName)) + .waitForDisplayed(); // open the drop database modal from the sidebar - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); await browser.clickVisible(Selectors.DropDatabaseButton); @@ -19,6 +24,6 @@ export async function dropDatabaseFromSidebar( // wait for it to be gone await browser - .$(Selectors.sidebarDatabase(dbName)) + .$(Selectors.sidebarDatabase(connectionId, dbName)) .waitForExist({ reverse: true }); } diff --git a/packages/compass-e2e-tests/helpers/commands/hide-shell.ts b/packages/compass-e2e-tests/helpers/commands/hide-shell.ts deleted file mode 100644 index 5303b5afe3e..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/hide-shell.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { CompassBrowser } from '../compass-browser'; -import retryWithBackoff from '../retry-with-backoff'; -import * as Selectors from '../selectors'; - -export async function hideShell(browser: CompassBrowser): Promise { - await retryWithBackoff(async function () { - const shellContentElement = await browser.$(Selectors.ShellContent); - if (await shellContentElement.isDisplayed()) { - await browser.clickVisible(Selectors.ShellExpandButton); - } - }); -} diff --git a/packages/compass-e2e-tests/helpers/commands/hide-visible-toasts.ts b/packages/compass-e2e-tests/helpers/commands/hide-visible-toasts.ts index 8f994ecaf2c..9a2a9ad13c9 100644 --- a/packages/compass-e2e-tests/helpers/commands/hide-visible-toasts.ts +++ b/packages/compass-e2e-tests/helpers/commands/hide-visible-toasts.ts @@ -12,12 +12,17 @@ export async function hideAllVisibleToasts( // LG toasts are stacked in scroll container and we need to close them all. const toasts = await toastContainer.$$('div'); for (const toast of toasts) { - await browser.hover(Selectors.LGToastContainer); - const isToastVisible = await toast.isDisplayed(); - if (!isToastVisible) { + try { + await browser.hover(Selectors.LGToastContainer); + const isToastVisible = await toast.isDisplayed(); + if (!isToastVisible) { + continue; + } + await browser.clickVisible(toast.$(Selectors.LGToastCloseButton)); + await toast.waitForExist({ reverse: true }); + } catch (err) { + // if the toast disappears by itself in the meantime, that's fine continue; } - await browser.clickVisible(toast.$(Selectors.LGToastCloseButton)); - await toast.waitForExist({ reverse: true }); } } diff --git a/packages/compass-e2e-tests/helpers/commands/index.ts b/packages/compass-e2e-tests/helpers/commands/index.ts index ecfa9e55207..cac8d754db0 100644 --- a/packages/compass-e2e-tests/helpers/commands/index.ts +++ b/packages/compass-e2e-tests/helpers/commands/index.ts @@ -15,7 +15,7 @@ export * from './collection-workspaces'; export * from './run-find-operation'; export * from './focus-stage-operator'; export * from './select-stage-operator'; -export * from './close-workspace-tabs'; +export * from './workspace-tabs'; export * from './set-validation'; export * from './wait-for-animations'; export * from './wait-for-aria-disabled'; @@ -41,14 +41,13 @@ export * from './get-feature'; export * from './set-feature'; export * from './save-favorite'; export * from './save-connection-string-as-favorite'; -export * from './select-connection'; -export * from './select-connection-menu-item'; +export * from './sidebar-connection'; export * from './select-connections-menu-item'; export * from './open-settings-modal'; export * from './wait-for-connection-result'; export * from './screenshot'; -export * from './show-shell'; -export * from './hide-shell'; +export * from './open-shell'; +export * from './close-shell'; export * from './select-option'; export * from './select-stage-menu-option'; export * from './select-text-pipeline-output-option'; @@ -67,3 +66,4 @@ export * from './drop-index'; export * from './hide-index'; export * from './unhide-index'; export * from './hide-visible-toasts'; +export * from './sidebar-collection'; diff --git a/packages/compass-e2e-tests/helpers/commands/open-shell.ts b/packages/compass-e2e-tests/helpers/commands/open-shell.ts new file mode 100644 index 00000000000..9dd5f14a43d --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/open-shell.ts @@ -0,0 +1,42 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; +import type { CompassBrowser } from '../compass-browser'; +import retryWithBackoff from '../retry-with-backoff'; +import * as Selectors from '../selectors'; + +export async function openShell( + browser: CompassBrowser, + connectionName: string +): Promise { + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.OpenShellItem + ); + + // try and make sure the shell tab is active and ready + await browser.waitUntil(async () => { + const currentActiveTab = await browser.$( + Selectors.workspaceTab({ active: true }) + ); + const activeType = await currentActiveTab.getAttribute('data-type'); + const activeConnectionName = await currentActiveTab.getAttribute( + 'data-connectionName' + ); + return activeType === 'Shell' && activeConnectionName === connectionName; + }); + + await browser.clickVisible(Selectors.ShellInputEditor); + } else { + // Expand the shell + await retryWithBackoff(async function () { + const shellContentElement = await browser.$(Selectors.ShellContent); + if (!(await shellContentElement.isDisplayed())) { + // The toasts may be covering the shell, so we need to close them. + await browser.hideAllVisibleToasts(); + await browser.clickVisible(Selectors.ShellExpandButton); + } + + await browser.clickVisible(Selectors.ShellInputEditor); + }); + } +} diff --git a/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts b/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts index 6caf276b684..9130661f9fc 100644 --- a/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts +++ b/packages/compass-e2e-tests/helpers/commands/save-connection-string-as-favorite.ts @@ -3,8 +3,8 @@ import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; -// TODO(COMPASS-8003,COMPASS-8023): Just remove this command and use -// setConnectionFormState() once we remove the single connection code +// TODO(COMPASS-8023): Just remove this command and use setConnectionFormState() +// once we remove the single connection code export async function saveConnectionStringAsFavorite( browser: CompassBrowser, connectionString: string, diff --git a/packages/compass-e2e-tests/helpers/commands/save-favorite.ts b/packages/compass-e2e-tests/helpers/commands/save-favorite.ts index d463347626d..e2a31a0120e 100644 --- a/packages/compass-e2e-tests/helpers/commands/save-favorite.ts +++ b/packages/compass-e2e-tests/helpers/commands/save-favorite.ts @@ -3,7 +3,7 @@ import type { CompassBrowser } from '../compass-browser'; import * as Selectors from '../selectors'; import { expect } from 'chai'; -// TODO(COMPASS-8003,COMPASS-8023): Just remove this command and use +// TODO(COMPASS-8023): Just remove this command and use // setConnectionFormState() once we remove the single connection code export async function saveFavorite( browser: CompassBrowser, diff --git a/packages/compass-e2e-tests/helpers/commands/select-connection-menu-item.ts b/packages/compass-e2e-tests/helpers/commands/select-connection-menu-item.ts deleted file mode 100644 index b744632cc4f..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/select-connection-menu-item.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; -import type { CompassBrowser } from '../compass-browser'; -import * as Selectors from '../selectors'; - -export async function selectConnectionMenuItem( - browser: CompassBrowser, - connectionName: string, - itemSelector: string -) { - const Sidebar = TEST_MULTIPLE_CONNECTIONS - ? Selectors.Multiple - : Selectors.Single; - - const selector = Selectors.sidebarConnection(connectionName); - - await browser.waitUntil(async () => { - if ( - await browser - .$(Selectors.sidebarConnectionMenuButton(connectionName)) - .isDisplayed() - ) { - return true; - } - - // It takes some time for the favourites to load - await browser.$(selector).waitForDisplayed(); - - // workaround for weirdness in the ItemActionControls menu opener icon - await browser.clickVisible(Sidebar.ConnectionsTitle); - - // Hover over an arbitrary other element to ensure that the second hover will - // actually be a fresh one. This otherwise breaks if this function is called - // twice in a row. - await browser.hover(`*:not(${selector}, ${selector} *)`); - - await browser.hover(selector); - return false; - }); - - await browser.clickVisible( - Selectors.sidebarConnectionMenuButton(connectionName) - ); - await browser.$(Sidebar.ConnectionMenu).waitForDisplayed(); - await browser.clickVisible(itemSelector); -} diff --git a/packages/compass-e2e-tests/helpers/commands/select-connection.ts b/packages/compass-e2e-tests/helpers/commands/select-connection.ts deleted file mode 100644 index 7731c82fadd..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/select-connection.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; -import type { CompassBrowser } from '../compass-browser'; -import * as Selectors from '../selectors'; - -export async function selectConnection( - browser: CompassBrowser, - connectionName: string -): Promise { - if (TEST_MULTIPLE_CONNECTIONS) { - await browser.selectConnectionMenuItem( - connectionName, - Selectors.Multiple.EditConnectionItem - ); - } else { - await browser.pause(1000); - - await browser.clickVisible( - Selectors.sidebarConnectionButton(connectionName), - { - screenshot: `selecting-connection-${connectionName}.png`, - } - ); - } - - await browser.waitUntil(async () => { - const connectionTitleSelector = TEST_MULTIPLE_CONNECTIONS - ? Selectors.ConnectionModalTitle - : Selectors.ConnectionTitle; - - const text = await browser.$(connectionTitleSelector).getText(); - return text === connectionName; - }); -} diff --git a/packages/compass-e2e-tests/helpers/commands/shell-eval.ts b/packages/compass-e2e-tests/helpers/commands/shell-eval.ts index 8acaf3efb4f..5ab994decd4 100644 --- a/packages/compass-e2e-tests/helpers/commands/shell-eval.ts +++ b/packages/compass-e2e-tests/helpers/commands/shell-eval.ts @@ -9,30 +9,44 @@ async function getOutputText(browser: CompassBrowser): Promise { export async function shellEval( browser: CompassBrowser, - str: string, + connectionName: string, + input: string | string[], parse = false ): Promise { - await browser.showShell(); - - const numLines = (await getOutputText(browser)).length; - - const command = parse === true ? `JSON.stringify(${str})` : str; - - await browser.setCodemirrorEditorValue(Selectors.ShellInputEditor, command); - await browser.keys(['Enter']); - - // wait until more output appears - await browser.waitUntil(async () => { - const lines = await getOutputText(browser); - return ( - lines.length > - /** - * input line becomes an output line on enter press, so we are waiting - * for two new lines to appear, not just one - */ - numLines + 1 - ); - }); + // Keep in mind that for multiple connections this will open a new tab and + // focus it. + await browser.openShell(connectionName); + + const strings = Array.isArray(input) ? input : [input]; + + for (const str of strings) { + const numLines = (await getOutputText(browser)).length; + + const command = parse === true ? `JSON.stringify(${str})` : str; + + await browser.setCodemirrorEditorValue(Selectors.ShellInputEditor, command); + await browser.keys(['Enter']); + + // wait until more output appears + await browser.waitUntil(async () => { + const lines = await getOutputText(browser); + if ( + lines.length > + /** + * input line becomes an output line on enter press, so we are waiting + * for two new lines to appear, not just one + */ + numLines + 1 + ) { + // make sure the prompt shows up before entering another line or continueing on + await browser + .$(`${Selectors.ShellInput} [aria-label="Chevron Right Icon"]`) + .waitForDisplayed(); + return true; + } + return false; + }); + } const output = await getOutputText(browser); @@ -52,7 +66,11 @@ export async function shellEval( } } - await browser.hideShell(); + // For multiple connections we're currently making the assumption that closing + // the shell will put the user back on the tab they were on before + // opening the shell tab. This might not stay true as we start testing more + // complicated user flows. + await browser.closeShell(connectionName); return result as string; } diff --git a/packages/compass-e2e-tests/helpers/commands/show-shell.ts b/packages/compass-e2e-tests/helpers/commands/show-shell.ts deleted file mode 100644 index 3179ced6f02..00000000000 --- a/packages/compass-e2e-tests/helpers/commands/show-shell.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { CompassBrowser } from '../compass-browser'; -import retryWithBackoff from '../retry-with-backoff'; -import * as Selectors from '../selectors'; - -export async function showShell(browser: CompassBrowser): Promise { - // Expand the shVdell - await retryWithBackoff(async function () { - const shellContentElement = await browser.$(Selectors.ShellContent); - if (!(await shellContentElement.isDisplayed())) { - // The toasts may be covering the shell, so we need to close them. - await browser.hideAllVisibleToasts(); - await browser.clickVisible(Selectors.ShellExpandButton); - } - - await browser.clickVisible(Selectors.ShellInputEditor); - }); -} diff --git a/packages/compass-e2e-tests/helpers/commands/sidebar-collection.ts b/packages/compass-e2e-tests/helpers/commands/sidebar-collection.ts new file mode 100644 index 00000000000..b3926034ca3 --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/sidebar-collection.ts @@ -0,0 +1,54 @@ +import type { CompassBrowser } from '../compass-browser'; +import * as Selectors from '../selectors'; + +export async function selectCollectionMenuItem( + browser: CompassBrowser, + connectionName: string, + databaseName: string, + collectionName: string, + actionName: string +) { + const connectionId = await browser.getConnectionIdByName(connectionName); + + // search for the view in the sidebar + await browser.clickVisible(Selectors.SidebarFilterInput); + await browser.setValueVisible( + Selectors.SidebarFilterInput, + `^(${databaseName}|${collectionName})$` + ); + + const collectionSelector = Selectors.sidebarCollection( + connectionId, + databaseName, + collectionName + ); + + // scroll to the collection if necessary + await browser.scrollToVirtualItem( + Selectors.SidebarNavigationTree, + collectionSelector, + 'tree' + ); + + const collectionElement = await browser.$(collectionSelector); + await collectionElement.waitForDisplayed(); + + // hover over the collection + await browser.hover(collectionSelector); + + // click the show collections button + // NOTE: This assumes it is currently closed + await browser.clickVisible( + `${collectionSelector} ${Selectors.SidebarNavigationItemShowActionsButton}` + ); + + const actionSelector = `[role="menuitem"][data-action="${actionName}"]`; + + const actionButton = await browser.$(actionSelector); + + // click the action + await browser.clickVisible(actionSelector); + + // make sure the menu closed + await actionButton.waitForDisplayed({ reverse: true }); +} diff --git a/packages/compass-e2e-tests/helpers/commands/sidebar-connection.ts b/packages/compass-e2e-tests/helpers/commands/sidebar-connection.ts new file mode 100644 index 00000000000..0a395f712ff --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/sidebar-connection.ts @@ -0,0 +1,128 @@ +import { TEST_MULTIPLE_CONNECTIONS } from '../compass'; +import type { CompassBrowser } from '../compass-browser'; +import * as Selectors from '../selectors'; + +export async function getConnectionIdByName( + browser: CompassBrowser, + connectionName: string +): Promise { + if (!TEST_MULTIPLE_CONNECTIONS) { + // the connection id isn't somewhere we can consistently access it in the + // single connection world + return undefined; + } + + const connections = await browser.$$( + Selectors.sidebarConnection(connectionName) + ); + + if (connections.length !== 1) { + throw new Error( + `Found ${connections.length} connections named ${connectionName}.` + ); + } + + return await browser + .$(Selectors.sidebarConnection(connectionName)) + .getAttribute('data-connection-id'); +} + +export async function selectConnection( + browser: CompassBrowser, + connectionName: string +): Promise { + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.EditConnectionItem + ); + } else { + await browser.pause(1000); + + await browser.clickVisible( + Selectors.sidebarConnectionButton(connectionName), + { + screenshot: `selecting-connection-${connectionName}.png`, + } + ); + } + + await browser.waitUntil(async () => { + const connectionTitleSelector = TEST_MULTIPLE_CONNECTIONS + ? Selectors.ConnectionModalTitle + : Selectors.ConnectionTitle; + + const text = await browser.$(connectionTitleSelector).getText(); + return text === connectionName; + }); +} + +export async function selectConnectionMenuItem( + browser: CompassBrowser, + connectionName: string, + itemSelector: string +) { + const Sidebar = TEST_MULTIPLE_CONNECTIONS + ? Selectors.Multiple + : Selectors.Single; + + const selector = Selectors.sidebarConnection(connectionName); + + await browser.waitUntil(async () => { + if ( + await browser + .$(Selectors.sidebarConnectionMenuButton(connectionName)) + .isDisplayed() + ) { + return true; + } + + // It takes some time for the favourites to load + await browser.$(selector).waitForDisplayed(); + + // workaround for weirdness in the ItemActionControls menu opener icon + await browser.clickVisible(Sidebar.ConnectionsTitle); + + // Hover over an arbitrary other element to ensure that the second hover will + // actually be a fresh one. This otherwise breaks if this function is called + // twice in a row. + await browser.hover(`*:not(${selector}, ${selector} *)`); + + await browser.hover(selector); + return false; + }); + + await browser.clickVisible( + Selectors.sidebarConnectionMenuButton(connectionName) + ); + await browser.$(Sidebar.ConnectionMenu).waitForDisplayed(); + await browser.clickVisible(itemSelector); +} + +export async function removeConnection( + browser: CompassBrowser, + connectionName: string +): Promise { + if (!TEST_MULTIPLE_CONNECTIONS) { + return; + } + + // make sure there's no filter because if the connection is not displayed then we can't remove it + if (await browser.$(Selectors.SidebarFilterInput).isExisting()) { + await browser.clickVisible(Selectors.SidebarFilterInput); + await browser.setValueVisible(Selectors.SidebarFilterInput, ''); + + // wait for a connection to appear. It must because if there are no + // connections the filter field wouldn't exist in the first place + await browser.$(Selectors.SidebarTreeItems).waitForDisplayed(); + } + + const selector = Selectors.sidebarConnection(connectionName); + if (await browser.$(selector).isExisting()) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.RemoveConnectionItem + ); + await browser.$(selector).waitForExist({ reverse: true }); + } +} diff --git a/packages/compass-e2e-tests/helpers/commands/wait-for-connection-result.ts b/packages/compass-e2e-tests/helpers/commands/wait-for-connection-result.ts index 1b4b104eb6f..cfc1b3c840c 100644 --- a/packages/compass-e2e-tests/helpers/commands/wait-for-connection-result.ts +++ b/packages/compass-e2e-tests/helpers/commands/wait-for-connection-result.ts @@ -21,12 +21,14 @@ export async function waitForConnectionResult( selector = TEST_COMPASS_WEB ? '[data-testid="workspace-tab-button"][title=Databases]' : TEST_MULTIPLE_CONNECTIONS - ? Selectors.SidebarTreeItems + ? `${Selectors.SidebarTreeItems}[aria-expanded=true]` : Selectors.MyQueriesList; } else { // TODO(COMPASS-7600): this doesn't support compass-web yet, but also isn't // encountered yet - selector = Selectors.ConnectionFormErrorMessage; + selector = TEST_MULTIPLE_CONNECTIONS + ? Selectors.ConnectionToastErrorText + : Selectors.ConnectionFormErrorMessage; } const element = await browser.$(selector); await element.waitForDisplayed( @@ -37,8 +39,9 @@ export async function waitForConnectionResult( } if (TEST_MULTIPLE_CONNECTIONS) { + // make sure the placeholders for databases & collections that are loading are all gone await browser - .$(Selectors.ConnectionModal) + .$(Selectors.DatabaseCollectionPlaceholder) .waitForDisplayed({ reverse: true }); } } diff --git a/packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts b/packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts new file mode 100644 index 00000000000..ecb9b0e169e --- /dev/null +++ b/packages/compass-e2e-tests/helpers/commands/workspace-tabs.ts @@ -0,0 +1,101 @@ +import type { CompassBrowser } from '../compass-browser'; +import * as Selectors from '../selectors'; +import type { WorkspaceTabSelectorOptions } from '../selectors'; +import Debug from 'debug'; +const debug = Debug('compass-e2e-tests'); + +export async function navigateToMyQueries(browser: CompassBrowser) { + await browser.clickVisible(Selectors.SidebarMyQueriesTab); + await browser + .$(Selectors.workspaceTab({ title: 'My Queries', active: true })) + .waitForDisplayed(); +} + +async function closeTab( + browser: CompassBrowser, + selectorOptions: WorkspaceTabSelectorOptions, + autoConfirmTabClose: boolean +): Promise { + // wait until the tab goes away and if the confirmation modal opens, maybe confirm + await browser.waitUntil( + async () => { + // keep retrying the click :( + await browser.clickVisible( + browser + .$(Selectors.workspaceTab(selectorOptions)) + .$(Selectors.CloseWorkspaceTab) + ); + + if (autoConfirmTabClose) { + // Tabs in "dirty" state can't be closed without confirmation + if (await browser.$(Selectors.ConfirmTabCloseModal).isExisting()) { + await browser.clickVisible( + browser.$(Selectors.ConfirmTabCloseModal).$('button=Close tab') + ); + await browser + .$(Selectors.ConfirmTabCloseModal) + .waitForDisplayed({ reverse: true }); + } + } + return ( + (await browser + .$(Selectors.workspaceTab(selectorOptions)) + .isExisting()) === false + ); + }, + // Don't wait longer than the wait in closeWorkspaceTabs + { timeout: 10_000 } + ); +} + +export async function closeWorkspaceTabs( + browser: CompassBrowser, + autoConfirmTabClose = true +): Promise { + const countTabs = async () => { + return (await browser.$$(Selectors.workspaceTab())).length; + }; + + await browser.waitUntil(async () => { + const numTabsStart = await countTabs(); + if (numTabsStart > 0) { + const currentActiveTab = await browser.$( + Selectors.workspaceTab({ active: true }) + ); + + // Close this exact active tab rather than "the active one" because if there + // are multiple tabs then another tab will immediately become active and + // trip up the logic that checks that the tab you closed went away. + const id = await currentActiveTab.getAttribute('id'); + debug('closing tab', { numTabsStart, id }); + await closeTab(browser, { id }, autoConfirmTabClose); + + const numTabsEnd = await countTabs(); + debug('after closing tab', { id, numTabsStart, numTabsEnd }); + return numTabsEnd === 0; + } else { + return true; + } + }); +} + +export async function closeWorkspaceTab( + browser: CompassBrowser, + selectorOptions: WorkspaceTabSelectorOptions +): Promise { + const currentTabId = await browser + .$(Selectors.workspaceTab({ active: true })) + .getAttribute('id'); + const targetTabId = await browser + .$(Selectors.workspaceTab(selectorOptions)) + .getAttribute('id'); + + if (currentTabId !== targetTabId) { + // The tab we want to close isn't the active one so the close button isn't + // visible. We can either focus it which would have the side-effect of + // changing the tab focus or we can try and hover over it. + await browser.hover(Selectors.workspaceTab(selectorOptions)); + } + + await closeTab(browser, selectorOptions, true); +} diff --git a/packages/compass-e2e-tests/helpers/compass.ts b/packages/compass-e2e-tests/helpers/compass.ts index a572cfb3caa..ed9c4cd41c1 100644 --- a/packages/compass-e2e-tests/helpers/compass.ts +++ b/packages/compass-e2e-tests/helpers/compass.ts @@ -12,10 +12,7 @@ import { remote } from 'webdriverio'; import { rebuild } from '@electron/rebuild'; import type { RebuildOptions } from '@electron/rebuild'; import type { ConsoleMessageType } from 'puppeteer'; -import { - run as packageCompass, - compileAssets, -} from 'hadron-build/commands/release'; +import { run as packageCompass } from 'hadron-build/commands/release'; import { redactConnectionString } from 'mongodb-connection-string-url'; import { getConnectionTitle } from '@mongodb-js/connection-info'; export * as Selectors from './selectors'; @@ -33,7 +30,6 @@ const debug = Debug('compass-e2e-tests'); const { gunzip } = zlib; const { Z_SYNC_FLUSH } = zlib.constants; -const compileAssetsAsync = promisify(compileAssets); const packageCompassAsync = promisify(packageCompass); export const COMPASS_PATH = path.dirname( @@ -81,6 +77,9 @@ export const MONGODB_TEST_SERVER_PORT = Number( ); export const DEFAULT_CONNECTION_STRING = `mongodb://127.0.0.1:${MONGODB_TEST_SERVER_PORT}/test`; +export const DEFAULT_CONNECTION_NAME = connectionNameFromString( + DEFAULT_CONNECTION_STRING +); export function updateMongoDBServerInfo() { try { @@ -873,9 +872,7 @@ export async function rebuildNativeModules( export async function compileCompassAssets( compassPath = COMPASS_PATH ): Promise { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore some weirdness from util-callbackify - await compileAssetsAsync({ dir: compassPath }); + await promisify(execFile)('npm', ['run', 'compile'], { cwd: compassPath }); } async function getCompassBuildMetadata(): Promise { diff --git a/packages/compass-e2e-tests/helpers/selectors.ts b/packages/compass-e2e-tests/helpers/selectors.ts index e3773864a26..c2533d63d5e 100644 --- a/packages/compass-e2e-tests/helpers/selectors.ts +++ b/packages/compass-e2e-tests/helpers/selectors.ts @@ -1,5 +1,14 @@ import { TEST_MULTIPLE_CONNECTIONS } from './compass'; +export type WorkspaceTabSelectorOptions = { + id?: string; + connectionName?: string; + namespace?: string; + type?: string; + title?: string; + active?: boolean; +}; + // Settings Modal export const SettingsModal = '[data-testid="settings-modal"]'; export const CloseSettingsModalButton = `${SettingsModal} [aria-label="Close modal"]`; @@ -16,6 +25,7 @@ export const SettingsInputElement = (settingName: string): string => { // LG Toasts container (these test ids are used by LG in the toast and are not in the code anywhere). export const LGToastContainer = '[data-testid="lg-toast-scroll-container"]'; export const LGToastCloseButton = '[data-testid="lg-toast-dismiss-button"]'; +export const LGToastTitle = '[data-testid="toast-title"]'; // Welcome Modal export const WelcomeModal = '[data-testid="welcome-modal"]'; @@ -222,6 +232,9 @@ export const ConnectionFormConnectionColor = '[data-testid="personalization-color-input"]'; export const ConnectionFormFavoriteCheckbox = '[data-testid="personalization-favorite-checkbox"]'; +export const ConnectionToastErrorText = '[data-testid="connection-error-text"]'; +export const ConnectionToastErrorReviewButton = + '[data-testid="connection-error-review"]'; // Single Connection sidebar export const Single = { @@ -249,6 +262,8 @@ export const Single = { '[data-testid="favorites-menu-export-saved-connections-action"]', ImportConnectionsModalOpen: '[data-testid="favorites-menu-import-saved-connections-action"]', + + InUseEncryptionMarker: '[data-testid="fle-connection-configuration"]', }; // Multiple Connections sidebar @@ -287,6 +302,8 @@ export const Multiple = { '[data-testid="connections-list-title-actions-export-saved-connections-action"]', ImportConnectionsModalOpen: '[data-testid="connections-list-title-actions-import-saved-connections-action"]', + + InUseEncryptionMarker: '[data-action="open-csfle-modal"]', }; // Rename Collection Modal @@ -315,23 +332,36 @@ export const RenameCollectionButton = '[data-testid="sidebar-navigation-item-actions-rename-collection-action"]'; export const DropDatabaseButton = '[data-action="drop-database"]'; export const CreateCollectionButton = '[data-action="create-collection"]'; -export const DropCollectionButton = '[data-action="drop-collection"]'; +export const DatabaseCollectionPlaceholder = '[data-testid="placeholder"]'; -export const FleConnectionConfigurationBanner = - '[data-testid="fle-connection-configuration"]'; - -export const sidebarDatabase = (dbName: string): string => { +export const sidebarDatabase = ( + // TODO(COMPASS-7906): don't allow undefined connectionId + connectionId: string | undefined, + dbName: string +): string => { + if (connectionId) { + return `${Sidebar} [data-connection-id="${connectionId}"][data-database-name="${dbName}"]`; + } return `${Sidebar} [data-database-name="${dbName}"]`; }; -export const sidebarDatabaseToggle = (dbName: string): string => { - return `${sidebarDatabase(dbName)} button[type=button]`; +export const sidebarDatabaseToggle = ( + // TODO(COMPASS-7906): don't allow undefined connectionId + connectionId: string | undefined, + dbName: string +): string => { + return `${sidebarDatabase(connectionId, dbName)} button[type=button]`; }; export const sidebarCollection = ( + // TODO(COMPASS-7906): don't allow undefined connectionId + connectionId: string | undefined, dbName: string, collectionName: string ): string => { + if (connectionId) { + return `${Sidebar} [data-connection-id="${connectionId}"][data-namespace="${dbName}.${collectionName}"]`; + } return `${Sidebar} [data-namespace="${dbName}.${collectionName}"]`; }; @@ -347,6 +377,13 @@ export const sidebarConnectionButton = (connectionName: string): string => { return `${sidebarConnection(connectionName)} > div > button`; }; +export const sidebarConnectionActionButton = ( + connectionName: string, + selector: string +): string => { + return `${sidebarConnection(connectionName)} ${selector}`; +}; + export const sidebarConnectionMenuButton = (connectionName: string): string => { return `${sidebarConnection(connectionName)} button[title="Show actions"]`; }; @@ -463,14 +500,15 @@ export const ShellSection = '[data-testid="shell-section"]'; export const ShellContent = '[data-testid="shell-content"]'; export const ShellExpandButton = '[data-testid="shell-expand-button"]'; export const ShellInputEditor = '[data-testid="shell-input"] [data-codemirror]'; +export const ShellInput = '[data-testid="shell-input"]'; export const ShellOutput = '[data-testid="shell-output"]'; // Instance screen export const DatabasesTable = '[data-testid="database-grid"]'; export const InstanceCreateDatabaseButton = - '[data-testid="database-grid"] [data-testid="create-controls"] button'; + '[data-testid="create-controls"] button'; export const InstanceRefreshDatabaseButton = - '[data-testid="database-grid"] [data-testid="refresh-controls"] button'; + '[data-testid="refresh-controls"] button'; export const DatabaseCard = '[data-testid="database-grid-item"]'; // assume that there's only one hovered card at a time and that the first and only button is the drop button export const DatabaseCardDrop = @@ -491,9 +529,9 @@ export const databaseCardClickable = (dbName: string): string => { // Database screen export const CollectionsGrid = '[data-testid="collection-grid"]'; export const DatabaseCreateCollectionButton = - '[data-testid="collection-grid"] [data-testid="create-controls"] button'; + '[data-testid="create-controls"] button'; export const DatabaseRefreshCollectionButton = - '[data-testid="collection-grid"] [data-testid="refresh-controls"] button'; + '[data-testid="refresh-controls"] button'; export const CollectionCard = '[data-testid="collection-grid-item"]'; // assume that there's only one hovered card at a time and that the first and only button is the drop button export const CollectionCardDrop = @@ -1178,36 +1216,34 @@ export const sidebarInstanceNavigationItem = ( export const SidebarMyQueriesTab = `${Sidebar} [aria-label="My Queries"]`; export const WorkspaceTab = '[role="tablist"][aria-label="Workspace Tabs"] [role="tab"]'; -export const workspaceTab = ( - title: string | null, - active: boolean | null = null -) => { - const _active = active === null ? '' : `[aria-selected="${String(active)}"]`; - const _title = - title === null - ? '' - : ['My Queries', 'Performance', 'Databases'].includes(title) - ? `[title="${title}"]` - : `[data-namespace="${title}"]`; - return `${WorkspaceTab}${_title}${_active}`; -}; -export const connectionWorkspaceTab = ( - tabName: 'Performance' | 'Databases', - active: boolean | null = null -) => { - return workspaceTab(tabName, active); -}; -export const databaseWorkspaceTab = ( - dbName: string, - active: boolean | null = null -) => { - return workspaceTab(dbName, active); -}; -export const collectionWorkspaceTab = ( - namespace: string, - active: boolean | null = null -) => { - return workspaceTab(namespace, active); +export const workspaceTab = ({ + id, + connectionName, + namespace, + type, + title, + active, +}: WorkspaceTabSelectorOptions = {}) => { + const parts: string[] = [WorkspaceTab]; + if (id !== undefined) { + parts.push(`[id="${id}"]`); + } + if (connectionName !== undefined) { + parts.push(`[data-connectionName="${connectionName}"]`); + } + if (namespace !== undefined) { + parts.push(`[data-namespace="${namespace}"]`); + } + if (type !== undefined) { + parts.push(`[data-type="${type}"]`); + } + if (title !== undefined) { + parts.push(`[title="${title}"]`); + } + if (active !== undefined) { + parts.push(`[aria-selected="${String(active)}"]`); + } + return parts.join(''); }; // Export modal @@ -1319,8 +1355,5 @@ export const AtlasLoginStatus = '[data-testid="atlas-login-status"]'; export const AtlasLoginErrorToast = '#atlas-sign-in-error'; export const AgreeAndContinueButton = 'button=Agree and continue'; -// Any toast -export const AnyToastDismissButton = '[data-testid="lg-toast-dismiss-button"]'; - // Close tab confirmation export const ConfirmTabCloseModal = '[data-testid="confirm-tab-close"]'; diff --git a/packages/compass-e2e-tests/package.json b/packages/compass-e2e-tests/package.json index 2b4edea2a0a..4eb70b795a9 100644 --- a/packages/compass-e2e-tests/package.json +++ b/packages/compass-e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "compass-e2e-tests", - "version": "1.21.7", + "version": "1.23.1", "private": true, "description": "E2E test suite for Compass app that follows smoke tests / feature testing matrix", "scripts": { @@ -30,9 +30,9 @@ }, "devDependencies": { "@electron/rebuild": "^3.6.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/oidc-mock-provider": "^0.9.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -44,15 +44,15 @@ "chai": "^4.3.4", "chai-as-promised": "^7.1.1", "clipboardy": "^2.3.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "cross-spawn": "^7.0.3", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "fast-glob": "^3.2.7", "glob": "^10.2.5", - "hadron-build": "^25.5.3", + "hadron-build": "^25.5.5", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", diff --git a/packages/compass-e2e-tests/tests/atlas-login.test.ts b/packages/compass-e2e-tests/tests/atlas-login.test.ts index c432a664304..c1128bd76b7 100644 --- a/packages/compass-e2e-tests/tests/atlas-login.test.ts +++ b/packages/compass-e2e-tests/tests/atlas-login.test.ts @@ -6,6 +6,7 @@ import { Selectors, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import type { OIDCMockProviderConfig } from '@mongodb-js/oidc-mock-provider'; @@ -273,7 +274,12 @@ describe('Atlas Login', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); it('should not show AI input if sign in flow was not finished', async function () { @@ -300,7 +306,12 @@ describe('Atlas Login', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); }); it('should not show AI input if sign in flow was not finished', async function () { diff --git a/packages/compass-e2e-tests/tests/auto-connect.test.ts b/packages/compass-e2e-tests/tests/auto-connect.test.ts index a25c0bf6696..6cbe7bba03a 100644 --- a/packages/compass-e2e-tests/tests/auto-connect.test.ts +++ b/packages/compass-e2e-tests/tests/auto-connect.test.ts @@ -7,6 +7,7 @@ import { skipForWeb, TEST_MULTIPLE_CONNECTIONS, screenshotPathName, + connectionNameFromString, } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import os from 'os'; @@ -93,6 +94,7 @@ describe('Automatically connecting from the command line', function () { .getText(); expect(sidebarTitle).to.eq(expectedTitle); const result = await compass.browser.shellEval( + connectionNameFromString(connectionStringSuccess), 'db.runCommand({ connectionStatus: 1 })', true ); @@ -216,7 +218,7 @@ describe('Automatically connecting from the command line', function () { location.reload(); }); await browser.waitForConnectionResult('success'); - await browser.disconnect(); + await browser.disconnectAll(); await browser.execute(() => { location.reload(); }); @@ -274,7 +276,7 @@ describe('Automatically connecting from the command line', function () { try { const browser = compass.browser; await browser.waitForConnectionResult('success'); - await browser.disconnect(); + await browser.disconnectAll(); // this is not the ideal check because by default the recent connections // list doesn't exist either diff --git a/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts b/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts index 2425cd084a1..54105136088 100644 --- a/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-aggregations-tab.test.ts @@ -8,6 +8,7 @@ import { outputFilename, serverSatisfies, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -69,49 +70,6 @@ async function getDocuments(browser: CompassBrowser) { }); } -async function chooseCollectionAction( - browser: CompassBrowser, - dbName: string, - collectionName: string, - actionName: string -) { - // search for the view in the sidebar - await browser.clickVisible(Selectors.SidebarFilterInput); - await browser.setValueVisible(Selectors.SidebarFilterInput, collectionName); - - const collectionSelector = Selectors.sidebarCollection( - dbName, - collectionName - ); - - // scroll to the collection if necessary - await browser.scrollToVirtualItem( - Selectors.SidebarNavigationTree, - collectionSelector, - 'tree' - ); - - const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); - - // hover over the collection - await browser.hover(collectionSelector); - - // click the show collections button - // NOTE: This assumes it is currently closed - await browser.clickVisible(Selectors.SidebarNavigationItemShowActionsButton); - - const actionSelector = `[role="menuitem"][data-action="${actionName}"]`; - - const actionButton = await browser.$(actionSelector); - - // click the action - await browser.clickVisible(actionSelector); - - // make sure the menu closed - await actionButton.waitForDisplayed({ reverse: true }); -} - async function waitForTab(browser: CompassBrowser, namespace: string) { await browser.waitUntil( async function () { @@ -176,7 +134,12 @@ describe('Collection aggregations tab', function () { }, STAGE_WIZARD_GUIDE_CUE_STORAGE_KEY); // Some tests navigate away from the numbers collection aggregations tab - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); // Get us back to the empty stage every time. Also test the Create New // Pipeline flow while at it. await browser.clickVisible(Selectors.CreateNewPipelineButton); @@ -468,8 +431,8 @@ describe('Collection aggregations tab', function () { await waitForTab(browser, 'test.my-view-from-pipeline'); // choose Duplicate view - await chooseCollectionAction( - browser, + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, 'test', 'my-view-from-pipeline', 'duplicate-view' @@ -496,8 +459,8 @@ describe('Collection aggregations tab', function () { await waitForTab(browser, 'test.duplicated-view'); // now select modify view of the non-duplicate - await chooseCollectionAction( - browser, + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, 'test', 'my-view-from-pipeline', 'modify-view' @@ -509,6 +472,7 @@ describe('Collection aggregations tab', function () { // make sure we're on the aggregations tab, in edit mode const modifyBanner = await browser.$(Selectors.ModifySourceBanner); await modifyBanner.waitForDisplayed(); + expect(await modifyBanner.getText()).to.equal( 'MODIFYING PIPELINE BACKING "TEST.MY-VIEW-FROM-PIPELINE"' ); @@ -1627,6 +1591,7 @@ describe('Collection aggregations tab', function () { describe('expanding and collapsing of documents', function () { beforeEach(async function () { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'nestedDocs', 'Aggregations' diff --git a/packages/compass-e2e-tests/tests/collection-ai-query.test.ts b/packages/compass-e2e-tests/tests/collection-ai-query.test.ts index 3c4a88dd346..cfd3bc70036 100644 --- a/packages/compass-e2e-tests/tests/collection-ai-query.test.ts +++ b/packages/compass-e2e-tests/tests/collection-ai-query.test.ts @@ -9,6 +9,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -56,7 +57,12 @@ describe('Collection ai query', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts b/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts index 9dce411f661..1579a9f7230 100644 --- a/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts +++ b/packages/compass-e2e-tests/tests/collection-bulk-delete.test.ts @@ -2,7 +2,12 @@ import { expect } from 'chai'; import type { CompassBrowser } from '../helpers/compass-browser'; import { startTelemetryServer } from '../helpers/telemetry'; import type { Telemetry } from '../helpers/telemetry'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -26,7 +31,12 @@ describe('Bulk Delete', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); afterEach(async function () { @@ -45,6 +55,10 @@ describe('Bulk Delete', function () { // Check the telemetry const openedEvent = await telemetryEntry('Bulk Delete Opened'); + + expect(openedEvent.connection_id).to.exist; + delete openedEvent.connection_id; // connection_id varies + expect(openedEvent).to.deep.equal({}); // Make sure the query is shown in the modal. @@ -75,6 +89,12 @@ describe('Bulk Delete', function () { // Check the telemetry const executedEvent = await telemetryEntry('Bulk Delete Executed'); + + // this id is always different, because the connection is not a saved one + // so we just check it exists for simplicity + expect(executedEvent.connection_id).to.exist; + delete executedEvent.connection_id; + expect(executedEvent).to.deep.equal({}); // The success toast is displayed @@ -153,6 +173,10 @@ describe('Bulk Delete', function () { // Check the telemetry const openedEvent = await telemetryEntry('Delete Export Opened'); + + expect(openedEvent.connection_id).to.exist; + delete openedEvent.connection_id; // connection_id varies + expect(openedEvent).to.deep.equal({}); const text = await browser.exportToLanguage('Python', { diff --git a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts index e10211383cd..583c98b7fd9 100644 --- a/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts +++ b/packages/compass-e2e-tests/tests/collection-bulk-update.test.ts @@ -7,6 +7,7 @@ import { cleanup, screenshotIfFailed, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -31,7 +32,12 @@ describe('Bulk Update', () => { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); afterEach(async function () { @@ -50,6 +56,10 @@ describe('Bulk Update', () => { // Check the telemetry const openedEvent = await telemetryEntry('Bulk Update Opened'); + + expect(openedEvent.connection_id).to.exist; + delete openedEvent.connection_id; // connection_id varies + expect(openedEvent).to.deep.equal({ isUpdatePreviewSupported: true, }); @@ -112,6 +122,10 @@ describe('Bulk Update', () => { // Check the telemetry const executedEvent = await telemetryEntry('Bulk Update Executed'); + + expect(executedEvent.connection_id).to.exist; + delete executedEvent.connection_id; // connection_id varies + expect(executedEvent).to.deep.equal({ isUpdatePreviewSupported: true, }); @@ -156,6 +170,10 @@ describe('Bulk Update', () => { // Check the telemetry const favoritedEvent = await telemetryEntry('Bulk Update Favorited'); + + expect(favoritedEvent.connection_id).to.exist; + delete favoritedEvent.connection_id; // connection_id varies + expect(favoritedEvent).to.deep.equal({ isUpdatePreviewSupported: true, }); diff --git a/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts b/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts index e16385a5eb7..f025bf37eb2 100644 --- a/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-documents-tab.test.ts @@ -9,6 +9,7 @@ import { screenshotIfFailed, TEST_COMPASS_WEB, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -122,7 +123,12 @@ describe('Collection documents tab', function () { await createNumbersCollection(); await createNestedDocumentsCollection('nestedDocs', 10); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); if (!TEST_COMPASS_WEB) { // setFeature/getFeature is not supported in compass-web yet @@ -155,6 +161,10 @@ describe('Collection documents tab', function () { // Check the telemetry const queryExecutedEvent = await telemetryEntry('Query Executed'); + + expect(queryExecutedEvent.connection_id).to.exist; + delete queryExecutedEvent.connection_id; // connection_id varies + expect(queryExecutedEvent).to.deep.equal({ changed_maxtimems: false, collection_type: 'collection', @@ -190,6 +200,10 @@ describe('Collection documents tab', function () { // Check the telemetry const queryExecutedEvent = await telemetryEntry('Query Executed'); + + expect(queryExecutedEvent.connection_id).to.exist; + delete queryExecutedEvent.connection_id; // connection_id varies + expect(queryExecutedEvent).to.deep.equal({ changed_maxtimems: false, collection_type: 'collection', @@ -622,7 +636,12 @@ FindIterable result = collection.find(filter);`); describe('expanding and collapsing of documents', function () { beforeEach(async function () { - await browser.navigateToCollectionTab('test', 'nestedDocs', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'nestedDocs', + 'Documents' + ); }); it('expands and collapses all fields in a document', async function () { diff --git a/packages/compass-e2e-tests/tests/collection-export.test.ts b/packages/compass-e2e-tests/tests/collection-export.test.ts index 2587bea41c1..f557dde6383 100644 --- a/packages/compass-e2e-tests/tests/collection-export.test.ts +++ b/packages/compass-e2e-tests/tests/collection-export.test.ts @@ -10,7 +10,7 @@ import { outputFilename, skipForWeb, TEST_COMPASS_WEB, - TEST_MULTIPLE_CONNECTIONS, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -68,7 +68,12 @@ describe('Collection export', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); it('supports collection to CSV with a query filter with a subset of fields', async function () { @@ -136,6 +141,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, has_projection: false, @@ -205,6 +212,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, has_projection: false, @@ -272,6 +281,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, has_projection: true, @@ -324,6 +335,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: true, file_type: 'csv', @@ -396,6 +409,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'json', @@ -463,6 +478,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'json', @@ -515,6 +532,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: true, file_type: 'json', @@ -569,6 +588,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: true, file_type: 'json', @@ -658,6 +679,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'csv', @@ -743,6 +766,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'json', @@ -761,13 +786,6 @@ describe('Collection export', function () { }); it('aborts an in progress CSV export when disconnected', async function () { - // TODO(COMPASS-8008): this is not working in multiple connections and the - // code below checking for the sidebar title to go away is wrong in that - // world anyway - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } - const telemetryEntry = await browser.listenForTelemetryEvents(telemetry); // Set a query that we'll use. @@ -810,10 +828,7 @@ describe('Collection export', function () { const exportAbortButton = await browser.$(Selectors.ExportToastAbort); await exportAbortButton.waitForDisplayed(); - await browser.disconnect(); - await browser - .$(Selectors.SidebarTitle) - .waitForDisplayed({ reverse: true }); + await browser.disconnectAll({ closeToasts: false }); // Wait for the aborted toast to appear. const toastElement = await browser.$(Selectors.ExportToast); @@ -846,6 +861,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'csv', @@ -868,6 +885,7 @@ describe('Collection export', function () { await createNumbersStringCollection(); await browser.connectWithConnectionString(); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'numbers-strings', 'Documents' @@ -957,6 +975,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'csv', @@ -1058,6 +1078,8 @@ describe('Collection export', function () { const exportCompletedEvent = await telemetryEntry('Export Completed'); delete exportCompletedEvent.duration; // Duration varies. + expect(exportCompletedEvent.connection_id).to.exist; + delete exportCompletedEvent.connection_id; // connection_id varies expect(exportCompletedEvent).to.deep.equal({ all_docs: false, file_type: 'json', diff --git a/packages/compass-e2e-tests/tests/collection-heading.test.ts b/packages/compass-e2e-tests/tests/collection-heading.test.ts index e719d6bc2d5..0da2ad865be 100644 --- a/packages/compass-e2e-tests/tests/collection-heading.test.ts +++ b/packages/compass-e2e-tests/tests/collection-heading.test.ts @@ -1,6 +1,11 @@ import { expect } from 'chai'; import type { CompassBrowser } from '../helpers/compass-browser'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -17,7 +22,12 @@ describe('Collection heading', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-import.test.ts b/packages/compass-e2e-tests/tests/collection-import.test.ts index 8c2908b8542..2bd217da580 100644 --- a/packages/compass-e2e-tests/tests/collection-import.test.ts +++ b/packages/compass-e2e-tests/tests/collection-import.test.ts @@ -9,7 +9,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, - TEST_MULTIPLE_CONNECTIONS, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import { getFirstListDocument } from '../helpers/read-first-document-content'; import type { Compass } from '../helpers/compass'; @@ -126,7 +126,12 @@ describe('Collection import', function () { }); it('supports single JSON objects', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); async function getDocumentCount() { const countText = await browser @@ -202,7 +207,12 @@ describe('Collection import', function () { }); it('supports single objects in document view mode', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); // browse to the "Insert to Collection" modal await browser.clickVisible(Selectors.AddDataButton); @@ -273,7 +283,12 @@ describe('Collection import', function () { }); it('supports JSON arrays', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); const array = []; for (let i = 0; i < 1000; ++i) { @@ -329,7 +344,12 @@ describe('Collection import', function () { }); it('displays an error for a malformed JSON array', async function () { - await browser.navigateToCollectionTab('test', 'json-array', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-array', + 'Documents' + ); const json = 'this is not valid JSON'; @@ -365,7 +385,12 @@ describe('Collection import', function () { it('supports JSON files', async function () { const jsonPath = path.resolve(__dirname, '..', 'fixtures', 'listings.json'); - await browser.navigateToCollectionTab('test', 'json-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'json-file', + 'Documents' + ); await importJSONFile(browser, jsonPath); @@ -411,6 +436,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'extended-json-file', 'Documents' @@ -461,6 +487,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'extended-json-file', 'Documents' @@ -502,7 +529,12 @@ describe('Collection import', function () { it('supports CSV files', async function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); - await browser.navigateToCollectionTab('test', 'csv-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'csv-file', + 'Documents' + ); // open the import modal await browser.clickVisible(Selectors.AddDataButton); @@ -605,6 +637,8 @@ describe('Collection import', function () { const importCompletedEvent = await telemetryEntry('Import Completed'); delete importCompletedEvent.duration; // Duration varies. + expect(importCompletedEvent.connection_id).to.exist; + delete importCompletedEvent.connection_id; // connection_id varies expect(importCompletedEvent).to.deep.equal({ delimiter: ',', newline: '\n', @@ -627,6 +661,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'array-documents', 'Documents' @@ -840,7 +875,12 @@ describe('Collection import', function () { 'source-with-bom.csv' ); - await browser.navigateToCollectionTab('test', 'bom-csv-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'bom-csv-file', + 'Documents' + ); // open the import modal await browser.clickVisible(Selectors.AddDataButton); @@ -927,7 +967,12 @@ describe('Collection import', function () { it('displays an error if an incompatible type is chosen for a column', async function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); - await browser.navigateToCollectionTab('test', 'csv-file', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'csv-file', + 'Documents' + ); // open the import modal await browser.clickVisible(Selectors.AddDataButton); @@ -982,6 +1027,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'broken-delimiter', 'Documents' @@ -1071,6 +1117,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'import-stop-first-error', 'Documents' @@ -1126,6 +1173,7 @@ describe('Collection import', function () { const jsonPath = path.resolve(__dirname, '..', 'fixtures', fileName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'import-with-errors', 'Documents' @@ -1196,6 +1244,7 @@ describe('Collection import', function () { const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'compass-import-abort-e2e-test', 'Documents' @@ -1271,6 +1320,7 @@ describe('Collection import', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'compass-import-abort-e2e-test', 'Documents' @@ -1333,15 +1383,11 @@ describe('Collection import', function () { }); it('aborts when disconnected', async function () { - // TODO(COMPASS-8008): same thing as for aborting an export when disconnected - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } - // 16116 documents. const csvPath = path.resolve(__dirname, '..', 'fixtures', 'listings.csv'); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', 'compass-import-abort-e2e-test', 'Documents' @@ -1365,10 +1411,7 @@ describe('Collection import', function () { // Wait for the in progress toast to appear. await browser.$(Selectors.ImportToastAbort).waitForDisplayed(); - await browser.disconnect(); - await browser - .$(Selectors.SidebarTitle) - .waitForDisplayed({ reverse: true }); + await browser.disconnectAll({ closeToasts: false }); // Wait for the aborted toast to appear. await browser diff --git a/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts b/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts index 7724ec43315..dcfa01bd62f 100644 --- a/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-indexes-tab.test.ts @@ -6,6 +6,7 @@ import { cleanup, screenshotIfFailed, serverSatisfies, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -25,7 +26,12 @@ describe('Collection indexes tab', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Indexes' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/collection-rename.test.ts b/packages/compass-e2e-tests/tests/collection-rename.test.ts index 54f22433bcb..ee4fc9c539f 100644 --- a/packages/compass-e2e-tests/tests/collection-rename.test.ts +++ b/packages/compass-e2e-tests/tests/collection-rename.test.ts @@ -6,12 +6,12 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { CompassBrowser } from '../helpers/compass-browser'; import { createBlankCollection, dropDatabase } from '../helpers/insert-data'; import * as Selectors from '../helpers/selectors'; -import { setFeature } from '../helpers/commands'; const initialName = 'numbers'; const newName = 'renamed'; @@ -57,32 +57,6 @@ class RenameCollectionModal { } } -async function navigateToCollectionInSidebar(browser: CompassBrowser) { - const sidebar = await browser.$(Selectors.SidebarNavigationTree); - await sidebar.waitForDisplayed(); - - // open the database in the sidebar - const dbElement = await browser.$(Selectors.sidebarDatabase(databaseName)); - await dbElement.waitForDisplayed(); - const button = await browser.$(Selectors.sidebarDatabaseToggle(databaseName)); - - await button.waitForDisplayed(); - await button.click(); - - // wait for the collection to become displayed - const collectionSelector = Selectors.sidebarCollection( - databaseName, - initialName - ); - await browser.scrollToVirtualItem( - Selectors.SidebarNavigationTree, - collectionSelector, - 'tree' - ); - const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); -} - async function renameCollectionSuccessFlow( browser: CompassBrowser, newName: string @@ -107,6 +81,7 @@ async function renameCollectionSuccessFlow( describe('Collection Rename Modal', () => { let compass: Compass; let browser: CompassBrowser; + let connectionId: string | undefined; before(async function () { skipForWeb(this, 'feature flags not yet available in compass-web'); @@ -114,7 +89,7 @@ describe('Collection Rename Modal', () => { compass = await init(this.test?.fullTitle()); browser = compass.browser; - await setFeature(browser, 'enableRenameCollectionModal', true); + await browser.setFeature('enableRenameCollectionModal', true); }); beforeEach(async function () { @@ -124,6 +99,7 @@ describe('Collection Rename Modal', () => { await createBlankCollection(databaseName, 'bar'); await browser.connectWithConnectionString(); + connectionId = await browser.getConnectionIdByName(DEFAULT_CONNECTION_NAME); }); after(async function () { @@ -140,50 +116,34 @@ describe('Collection Rename Modal', () => { }); describe('from the sidebar', () => { - it('a collection can be renamed', async () => { - await navigateToCollectionInSidebar(browser); - - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton - ); - await browser.clickVisible(Selectors.RenameCollectionButton); - - // go through - await renameCollectionSuccessFlow(browser, newName); - - // confirm that the new collection name is shown in the sidebar - await browser - .$(Selectors.sidebarCollection(databaseName, newName)) - .waitForDisplayed(); - }); - it('collection rename shows up on collection view', async () => { - await navigateToCollectionInSidebar(browser); // open a collection tab - const collectionSelector = Selectors.sidebarCollection( + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, initialName ); - const collectionElement = await browser.$(collectionSelector); - await collectionElement.waitForDisplayed(); - await collectionElement.click(); const headerSelector = Selectors.CollectionHeader; // wait until the collection tab has loaded await browser.$(headerSelector).waitForDisplayed(); - // open the rename collection flow from the sidebar - await browser.hover(collectionSelector); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); + await renameCollectionSuccessFlow(browser, newName); + // confirm that the new collection name is shown in the sidebar + await browser.setValueVisible(Selectors.SidebarFilterInput, ''); + await browser + .$(Selectors.sidebarCollection(connectionId, databaseName, newName)) + .waitForDisplayed(); + + // confirm that the header in the workspace changes await browser.$(headerSelector).waitForDisplayed(); await browser.waitUntil(async () => { const collectionHeaderContent = await browser @@ -197,16 +157,12 @@ describe('Collection Rename Modal', () => { }); it('collection rename can be retried after an error renaming the collection', async () => { - await navigateToCollectionInSidebar(browser); - - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); // wait for the collection modal to appear const modal = new RenameCollectionModal(browser); @@ -235,34 +191,13 @@ describe('Collection Rename Modal', () => { }); describe('modal dismiss', () => { - it('the modal can be dismissed', async () => { - await navigateToCollectionInSidebar(browser); - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton - ); - await browser.clickVisible(Selectors.RenameCollectionButton); - // wait for the collection modal to appear - const modal = new RenameCollectionModal(browser); - await modal.isVisible(); - - await browser.clickVisible(modal.dismissButton); - await modal.isNotVisible(); - }); - it('clears modal state when dismissed', async () => { - await navigateToCollectionInSidebar(browser); - // open the rename collection modal - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); // wait for the collection modal to appear const modal = new RenameCollectionModal(browser); @@ -274,14 +209,12 @@ describe('Collection Rename Modal', () => { await modal.isNotVisible(); // re-open the modal - // open the drop collection modal from the sidebar - await browser.hover( - Selectors.sidebarCollection(databaseName, initialName) - ); - await browser.clickVisible( - Selectors.SidebarNavigationItemShowActionsButton + await browser.selectCollectionMenuItem( + DEFAULT_CONNECTION_NAME, + databaseName, + initialName, + 'rename-collection' ); - await browser.clickVisible(Selectors.RenameCollectionButton); // assert that the form state has reset expect(await modal.collectionNameInput.getValue()).to.equal(initialName); diff --git a/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts b/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts index 8b0514f0b32..fe9d291edc9 100644 --- a/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-schema-tab.test.ts @@ -5,6 +5,7 @@ import { cleanup, screenshotIfFailed, skipForWeb, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -39,7 +40,12 @@ describe('Collection schema tab', function () { }); it('analyzes a schema', async function () { - await browser.navigateToCollectionTab('test', 'numbers', 'Schema'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Schema' + ); await browser.clickVisible(Selectors.AnalyzeSchemaButton); const element = await browser.$(Selectors.SchemaFieldList); @@ -70,7 +76,12 @@ describe('Collection schema tab', function () { skipForWeb(this, "can't toggle features in compass-web"); await browser.setFeature('enableMaps', enableMaps); - await browser.navigateToCollectionTab('test', 'geospatial', 'Schema'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'geospatial', + 'Schema' + ); await browser.clickVisible(Selectors.AnalyzeSchemaButton); const element = await browser.$(Selectors.SchemaFieldList); diff --git a/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts b/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts index 73ba6ff1f9d..f3ac21a0d1b 100644 --- a/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts +++ b/packages/compass-e2e-tests/tests/collection-validation-tab.test.ts @@ -1,5 +1,10 @@ import type { CompassBrowser } from '../helpers/compass-browser'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -22,7 +27,12 @@ describe('Collection validation tab', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Validation'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Validation' + ); }); after(async function () { diff --git a/packages/compass-e2e-tests/tests/connection-form.test.ts b/packages/compass-e2e-tests/tests/connection-form.test.ts index 3ce11c534e0..1b7838e3fba 100644 --- a/packages/compass-e2e-tests/tests/connection-form.test.ts +++ b/packages/compass-e2e-tests/tests/connection-form.test.ts @@ -65,8 +65,8 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } expect(state).to.deep.equal(expectedState); @@ -99,9 +99,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -138,9 +138,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017,127.0.0.1:27091'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017,127.0.0.1:27091'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -177,9 +177,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -222,9 +222,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -267,9 +267,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } await browser.setValueVisible( @@ -340,9 +340,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -382,9 +382,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -426,9 +426,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -472,9 +472,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -519,9 +519,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(); @@ -566,8 +566,8 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } expect(await browser.getConnectFormState()).to.deep.equal(expectedState); @@ -613,8 +613,8 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } expect(await browser.getConnectFormState()).to.deep.equal(expectedState); @@ -658,9 +658,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(false); @@ -706,14 +706,14 @@ describe('Connection form', function () { Sidebar.DuplicateConnectionItem ); - // duplicating immediately opens the modal so you can edit it + // duplicating opens the modal, in multiple connections you have to save if (TEST_MULTIPLE_CONNECTIONS) { - await browser.clickVisible(Selectors.ConnectionModalCloseButton); + await browser.clickVisible(Selectors.ConnectionModalSaveButton); } // delete the duplicate await browser.selectConnectionMenuItem( - `${favoriteName} (copy)`, + `${favoriteName} (1)`, Sidebar.RemoveConnectionItem ); @@ -785,9 +785,9 @@ describe('Connection form', function () { }; if (TEST_MULTIPLE_CONNECTIONS) { - (expectedState.connectionName = 'localhost:27017'), - (expectedState.connectionColor = 'no-color'), - (expectedState.connectionFavorite = false); + expectedState.connectionName = 'localhost:27017'; + expectedState.connectionColor = 'no-color'; + expectedState.connectionFavorite = false; } const state = await browser.getConnectFormState(true); @@ -799,8 +799,10 @@ describe('Connection form', function () { ); }); - it('supports favorites', async function () { + it('supports saving a favorite (multiple connections)', async function () { if (!TEST_MULTIPLE_CONNECTIONS) { + // this will remain skipped until we remove the test because the test is + // now for the multiple connections case only this.skip(); } @@ -833,9 +835,10 @@ describe('Connection form', function () { }); }); - it('can save & connect', async function () { - // TODO(COMPASS-8003): saving a favorite is now part of the connect form + it('supports saving a favorite (single connection)', async function () { if (TEST_MULTIPLE_CONNECTIONS) { + // this will remain skipped until we remove the test because the test is + // now for the single connection case only this.skip(); } @@ -849,6 +852,8 @@ describe('Connection form', function () { // Save & Connect await browser.clickVisible(Selectors.SaveAndConnectButton); + + // Fill out the favorite info await browser.$(Selectors.FavoriteModal).waitForDisplayed(); await browser.setValueVisible(Selectors.FavoriteNameInput, favoriteName); await browser.clickVisible( @@ -876,6 +881,6 @@ describe('Connection form', function () { favoriteName ); - await browser.disconnect(); + await browser.disconnectAll(); }); }); diff --git a/packages/compass-e2e-tests/tests/connection.test.ts b/packages/compass-e2e-tests/tests/connection.test.ts index 0345c867022..7d2e9758ebd 100644 --- a/packages/compass-e2e-tests/tests/connection.test.ts +++ b/packages/compass-e2e-tests/tests/connection.test.ts @@ -15,6 +15,8 @@ import { TEST_COMPASS_WEB, TEST_MULTIPLE_CONNECTIONS, connectionNameFromString, + DEFAULT_CONNECTION_NAME, + MONGODB_TEST_SERVER_PORT, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import type { ConnectFormState } from '../helpers/connect-form-state'; @@ -22,7 +24,7 @@ import * as Selectors from '../helpers/selectors'; async function disconnect(browser: CompassBrowser) { try { - await browser.disconnect(); + await browser.disconnectAll(); } catch (err) { console.error('Error during disconnect:'); console.error(err); @@ -126,12 +128,16 @@ function generateIamSessionToken(): { async function assertCanReadData( browser: CompassBrowser, - // TODO(COMPASS-8002): take into account connectionName connectionName: string, dbName: string, collectionName: string ): Promise { - await browser.navigateToCollectionTab(dbName, collectionName, 'Documents'); + await browser.navigateToCollectionTab( + connectionName, + dbName, + collectionName, + 'Documents' + ); await browser.waitUntil(async () => { const text = await browser .$(Selectors.DocumentListActionBarMessage) @@ -142,12 +148,16 @@ async function assertCanReadData( async function assertCannotInsertData( browser: CompassBrowser, - // TODO(COMPASS-8002): take into account connectionName connectionName: string, dbName: string, collectionName: string ): Promise { - await browser.navigateToCollectionTab(dbName, collectionName, 'Documents'); + await browser.navigateToCollectionTab( + connectionName, + dbName, + collectionName, + 'Documents' + ); // browse to the "Insert to Collection" modal await browser.clickVisible(Selectors.AddDataButton); @@ -199,7 +209,16 @@ async function assertCannotCreateDb( } // open the create database modal from the sidebar - await browser.clickVisible(Sidebar.CreateDatabaseButton); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Sidebar.CreateDatabaseButton + ) + ); + } else { + await browser.clickVisible(Sidebar.CreateDatabaseButton); + } const createModalElement = await browser.$(Selectors.CreateDatabaseModal); await createModalElement.waitForDisplayed(); @@ -228,17 +247,20 @@ async function assertCannotCreateDb( async function assertCannotCreateCollection( browser: CompassBrowser, - // TODO(COMPASS-8002): take into account connectionName connectionName: string, dbName: string, collectionName: string ): Promise { + const connectionId = await browser.getConnectionIdByName(connectionName); + // open create collection modal from the sidebar await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); await browser.clickVisible(Selectors.CreateCollectionButton); const createModalElement = await browser.$(Selectors.CreateCollectionModal); @@ -287,8 +309,9 @@ describe('Connection string', function () { it('can connect using connection string', async function () { await browser.connectWithConnectionString(); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + DEFAULT_CONNECTION_NAME, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -297,6 +320,31 @@ describe('Connection string', function () { } }); + it('fails for authentication errors', async function () { + skipForWeb(this, 'connect happens on the outside'); + + await browser.connectWithConnectionString( + `mongodb://a:b@127.0.0.1:${MONGODB_TEST_SERVER_PORT}/test`, + 'failure' + ); + if (TEST_MULTIPLE_CONNECTIONS) { + const toastTitle = await browser.$(Selectors.LGToastTitle).getText(); + expect(toastTitle).to.equal('Authentication failed.'); + + const errorMessage = await browser + .$(Selectors.ConnectionToastErrorText) + .getText(); + expect(errorMessage).to.equal( + 'There was a problem connecting to 127.0.0.1:27091' + ); + } else { + const errorMessage = await browser + .$(Selectors.ConnectionFormErrorMessage) + .getText(); + expect(errorMessage).to.equal('Authentication failed.'); + } + }); + it('can connect to an Atlas replicaset without srv', async function () { if (!hasAtlasEnvironmentVariables()) { return this.skip(); @@ -309,8 +357,9 @@ describe('Connection string', function () { const connectionString = await resolveMongodbSrv(withSRV); await browser.connectWithConnectionString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionNameFromString(connectionString), 'db.runCommand({ connectionStatus: 1 })', true ); @@ -339,8 +388,10 @@ describe('Connection string', function () { const connectionString = parsedString.toString(); await browser.connectWithConnectionString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { + await browser.screenshot('direct-connection-shell.png'); const result = await browser.shellEval( + connectionNameFromString(connectionString), 'db.runCommand({ connectionStatus: 1 })', true ); @@ -358,11 +409,13 @@ describe('Connection string', function () { const password = process.env.E2E_TESTS_ATLAS_PASSWORD ?? ''; const host = process.env.E2E_TESTS_SERVERLESS_HOST ?? ''; const connectionString = `mongodb+srv://${username}:${password}@${host}`; + const connectionName = connectionNameFromString(connectionString); await browser.connectWithConnectionString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -380,11 +433,13 @@ describe('Connection string', function () { const password = process.env.E2E_TESTS_ATLAS_PASSWORD ?? ''; const host = process.env.E2E_TESTS_DATA_LAKE_HOST ?? ''; const connectionString = `mongodb://${username}:${password}@${host}/?authSource=admin&tls=true`; + const connectionName = connectionNameFromString(connectionString); await browser.connectWithConnectionString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -402,11 +457,13 @@ describe('Connection string', function () { const password = process.env.E2E_TESTS_ATLAS_PASSWORD ?? ''; const host = process.env.E2E_TESTS_ANALYTICS_NODE_HOST ?? ''; const connectionString = `mongodb+srv://${username}:${password}@${host}`; + const connectionName = connectionNameFromString(connectionString); await browser.connectWithConnectionString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -424,10 +481,12 @@ describe('Connection string', function () { const password = process.env.E2E_TESTS_ATLAS_PASSWORD ?? ''; const host = process.env.E2E_TESTS_FREE_TIER_HOST ?? ''; const connectionString = `mongodb+srv://${username}:${password}@${host}`; + const connectionName = connectionNameFromString(connectionString); await browser.connectWithConnectionString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -441,12 +500,15 @@ describe('Connection string', function () { return this.skip(); } - await browser.connectWithConnectionString( - process.env.E2E_TESTS_ATLAS_READWRITEANY_STRING ?? '' - ); + const connectionString = + process.env.E2E_TESTS_ATLAS_READWRITEANY_STRING ?? ''; + const connectionName = connectionNameFromString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + await browser.connectWithConnectionString(connectionString); + + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -454,10 +516,6 @@ describe('Connection string', function () { expect(result).to.have.property('ok', 1); } - const connectionName = connectionNameFromString( - process.env.E2E_TESTS_ATLAS_READWRITEANY_STRING ?? '' - ); - await assertCanReadData( browser, connectionName, @@ -471,12 +529,16 @@ describe('Connection string', function () { return this.skip(); } - await browser.connectWithConnectionString( - process.env.E2E_TESTS_ATLAS_READANYDATABASE_STRING ?? '' - ); + const connectionString = + process.env.E2E_TESTS_ATLAS_READANYDATABASE_STRING ?? ''; + + await browser.connectWithConnectionString(connectionString); + + const connectionName = connectionNameFromString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -484,10 +546,6 @@ describe('Connection string', function () { expect(result).to.have.property('ok', 1); } - const connectionName = connectionNameFromString( - process.env.E2E_TESTS_ATLAS_READANYDATABASE_STRING ?? '' - ); - await assertCanReadData( browser, connectionName, @@ -519,12 +577,16 @@ describe('Connection string', function () { return this.skip(); } - await browser.connectWithConnectionString( - process.env.E2E_TESTS_ATLAS_CUSTOMROLE_STRING ?? '' - ); + const connectionString = + process.env.E2E_TESTS_ATLAS_CUSTOMROLE_STRING ?? ''; + + await browser.connectWithConnectionString(connectionString); + + const connectionName = connectionNameFromString(connectionString); - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -532,10 +594,6 @@ describe('Connection string', function () { expect(result).to.have.property('ok', 1); } - const connectionName = connectionNameFromString( - process.env.E2E_TESTS_ATLAS_CUSTOMROLE_STRING ?? '' - ); - await assertCanReadData(browser, connectionName, 'test', 'users'); await assertCannotCreateDb( browser, @@ -556,12 +614,16 @@ describe('Connection string', function () { return this.skip(); } - await browser.connectWithConnectionString( - process.env.E2E_TESTS_ATLAS_SPECIFICPERMISSION_STRING ?? '' - ); + const connectionString = + process.env.E2E_TESTS_ATLAS_SPECIFICPERMISSION_STRING ?? ''; - if (!TEST_COMPASS_WEB && !TEST_MULTIPLE_CONNECTIONS) { + await browser.connectWithConnectionString(connectionString); + + const connectionName = connectionNameFromString(connectionString); + + if (!TEST_COMPASS_WEB) { const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -569,10 +631,6 @@ describe('Connection string', function () { expect(result).to.have.property('ok', 1); } - const connectionName = connectionNameFromString( - process.env.E2E_TESTS_ATLAS_CUSTOMROLE_STRING ?? '' - ); - await assertCanReadData(browser, connectionName, 'test', 'users'); await assertCannotInsertData(browser, connectionName, 'test', 'users'); await assertCannotCreateDb( @@ -615,20 +673,19 @@ describe('Connection form', function () { }); it('can connect using connection form', async function () { - const connectionName = this.test?.fullTitle(); + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ hosts: ['127.0.0.1:27091'], connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to an Atlas cluster with username/password authentication (SCRAM-SHA-1)', async function () { @@ -636,7 +693,7 @@ describe('Connection form', function () { return this.skip(); } - const connectionName = this.test?.fullTitle(); + const connectionName = this.test?.fullTitle() ?? ''; const atlasConnectionOptions: ConnectFormState = basicAtlasOptions( process.env.E2E_TESTS_ATLAS_HOST ?? '' @@ -645,14 +702,14 @@ describe('Connection form', function () { ...atlasConnectionOptions, connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + await browser.screenshot('SCDAM-SHA1-shell.png'); + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to an Atlas cluster with X.509 authentication', async function () { @@ -660,7 +717,7 @@ describe('Connection form', function () { return this.skip(); } - const connectionName = this.test?.fullTitle(); + const connectionName = this.test?.fullTitle() ?? ''; let tempdir; try { @@ -679,14 +736,13 @@ describe('Connection form', function () { ...atlasConnectionOptions, connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); } finally { if (tempdir) { await fs.rmdir(tempdir, { recursive: true }); @@ -699,7 +755,7 @@ describe('Connection form', function () { return this.skip(); } - const connectionName = this.test?.fullTitle(); + const connectionName = this.test?.fullTitle() ?? ''; const atlasConnectionOptions: ConnectFormState = { hosts: [process.env.E2E_TESTS_FREE_TIER_HOST ?? ''], @@ -713,14 +769,14 @@ describe('Connection form', function () { ...atlasConnectionOptions, connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + await browser.screenshot('without-session-token-shell.png'); + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to an Atlas cluster with AWS IAM authentication (including session token)', async function () { @@ -745,18 +801,19 @@ describe('Connection form', function () { awsSecretAccessKey: secret, awsSessionToken: token, }; + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ ...atlasConnectionOptions, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + await browser.screenshot('including-session-token-shell.png'); + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to an Atlas with tlsUseSystemCA', async function () { @@ -767,6 +824,7 @@ describe('Connection form', function () { const username = process.env.E2E_TESTS_ATLAS_USERNAME ?? ''; const password = process.env.E2E_TESTS_ATLAS_PASSWORD ?? ''; const host = process.env.E2E_TESTS_ATLAS_HOST ?? ''; + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ scheme: 'MONGODB_SRV', @@ -776,19 +834,20 @@ describe('Connection form', function () { hosts: [host], sslConnection: 'ON', useSystemCA: true, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - // NB: The fact that we can use the shell is a regression test for COMPASS-5802. - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - await new Promise((resolve) => setTimeout(resolve, 10000)); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + await browser.screenshot('tlsUseSystemCA-shell.png'); + + // NB: The fact that we can use the shell is a regression test for COMPASS-5802. + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + await new Promise((resolve) => setTimeout(resolve, 10000)); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to Atlas Serverless', async function () { @@ -799,18 +858,18 @@ describe('Connection form', function () { const atlasConnectionOptions: ConnectFormState = basicAtlasOptions( process.env.E2E_TESTS_SERVERLESS_HOST ?? '' ); + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ ...atlasConnectionOptions, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to Atlas Datalake', async function () { @@ -825,19 +884,19 @@ describe('Connection form', function () { atlasConnectionOptions.defaultDatabase = 'test'; atlasConnectionOptions.sslConnection = 'ON'; atlasConnectionOptions.defaultAuthSource = 'admin'; + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ ...atlasConnectionOptions, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to Atlas Analytics Node', async function () { @@ -848,18 +907,18 @@ describe('Connection form', function () { const atlasConnectionOptions: ConnectFormState = basicAtlasOptions( process.env.E2E_TESTS_ANALYTICS_NODE_HOST ?? '' ); + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ ...atlasConnectionOptions, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); it('can connect to Atlas Free Tier', async function () { @@ -870,18 +929,18 @@ describe('Connection form', function () { const atlasConnectionOptions: ConnectFormState = basicAtlasOptions( process.env.E2E_TESTS_FREE_TIER_HOST ?? '' ); + const connectionName = this.test?.fullTitle() ?? ''; await browser.connectWithConnectionForm({ ...atlasConnectionOptions, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval( - 'db.runCommand({ connectionStatus: 1 })', - true - ); - assertNotError(result); - expect(result).to.have.property('ok', 1); - } + const result = await browser.shellEval( + connectionName, + 'db.runCommand({ connectionStatus: 1 })', + true + ); + assertNotError(result); + expect(result).to.have.property('ok', 1); }); }); @@ -965,22 +1024,20 @@ describe('System CA access', function () { }); it('allows using the system certificate store for connections', async function () { - // TODO(COMPASS-8004): this uses shellEval and that's not working in multiple connections yet - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } - const compass = await init(this.test?.fullTitle()); const browser = compass.browser; + const connectionName = this.test?.fullTitle() ?? ''; + try { await browser.connectWithConnectionForm({ hosts: ['127.0.0.1:27091'], sslConnection: 'DEFAULT', useSystemCA: true, - connectionName: this.test?.fullTitle(), + connectionName, }); const result = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 })', true ); @@ -1045,6 +1102,8 @@ describe('FLE2', function () { return this.skip(); } + const connectionName = this.test?.fullTitle() ?? ''; + await browser.connectWithConnectionForm({ hosts: ['127.0.0.1:27091'], fleKeyVaultNamespace: 'alena.keyvault', @@ -1060,12 +1119,14 @@ describe('FLE2', function () { ] } }`, - connectionName: this.test?.fullTitle(), + connectionName, }); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval('db.getName()', true); - expect(result).to.be.equal('test'); - } + const result = await browser.shellEval( + connectionName, + 'db.getName()', + true + ); + expect(result).to.be.equal('test'); }); }); diff --git a/packages/compass-e2e-tests/tests/database-collections-tab.test.ts b/packages/compass-e2e-tests/tests/database-collections-tab.test.ts index 18c5cf97970..08ad3d2bdba 100644 --- a/packages/compass-e2e-tests/tests/database-collections-tab.test.ts +++ b/packages/compass-e2e-tests/tests/database-collections-tab.test.ts @@ -7,7 +7,7 @@ import { screenshotIfFailed, serverSatisfies, DEFAULT_CONNECTION_STRING, - connectionNameFromString, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -60,7 +60,7 @@ describe('Database collections tab', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); }); @@ -132,7 +132,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -170,10 +170,7 @@ describe('Database collections tab', function () { // the app should still be on the database Collections tab because there are // other collections in this database - await browser.waitUntilActiveDatabaseTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'test' - ); + await browser.waitUntilActiveDatabaseTab(DEFAULT_CONNECTION_NAME, 'test'); }); it('can create a capped collection', async function () { @@ -193,7 +190,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -234,7 +231,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -270,7 +267,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -307,7 +304,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -342,7 +339,7 @@ describe('Database collections tab', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -353,7 +350,12 @@ describe('Database collections tab', function () { '[data-testid="collection-badge-clustered"]' ); - await browser.navigateToCollectionTab('test', collectionName, 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + collectionName, + 'Indexes' + ); const typeElementSelector = `${Selectors.indexComponent(indexName)} ${ Selectors.IndexFieldType @@ -377,10 +379,7 @@ describe('Database collections tab', function () { await mongoClient.close(); } - await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - db - ); + await browser.navigateToDatabaseCollectionsTab(DEFAULT_CONNECTION_NAME, db); await browser.clickVisible(Selectors.DatabaseRefreshCollectionButton); const collSelector = Selectors.collectionCard(db, coll); diff --git a/packages/compass-e2e-tests/tests/force-connection-options.test.ts b/packages/compass-e2e-tests/tests/force-connection-options.test.ts index 8867d492143..ff462782111 100644 --- a/packages/compass-e2e-tests/tests/force-connection-options.test.ts +++ b/packages/compass-e2e-tests/tests/force-connection-options.test.ts @@ -8,6 +8,7 @@ import { TEST_COMPASS_WEB, TEST_MULTIPLE_CONNECTIONS, Selectors, + connectionNameFromString, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import { expect } from 'chai'; @@ -58,15 +59,19 @@ describe('forceConnectionOptions', function () { await browser.clickVisible(Selectors.ConnectionModalCloseButton); } - await browser.connectWithConnectionString( - 'mongodb://127.0.0.1:27091/?appName=userSpecifiedAppName' - ); + const connectionString = + 'mongodb://127.0.0.1:27091/?appName=userSpecifiedAppName'; + const connectionName = connectionNameFromString(connectionString); - if (!TEST_MULTIPLE_CONNECTIONS) { - const result = await browser.shellEval('db.getMongo()._uri', true); - expect(new ConnectionString(result).searchParams.get('appName')).to.equal( - 'testAppName' - ); - } + await browser.connectWithConnectionString(connectionString); + + const result = await browser.shellEval( + connectionName, + 'db.getMongo()._uri', + true + ); + expect(new ConnectionString(result).searchParams.get('appName')).to.equal( + 'testAppName' + ); }); }); diff --git a/packages/compass-e2e-tests/tests/global-preferences.test.ts b/packages/compass-e2e-tests/tests/global-preferences.test.ts index 141c4d0c1c3..9dbf1cf78ea 100644 --- a/packages/compass-e2e-tests/tests/global-preferences.test.ts +++ b/packages/compass-e2e-tests/tests/global-preferences.test.ts @@ -177,6 +177,10 @@ describe('Global preferences', function () { const compass = await init(this.test?.fullTitle()); const browser = compass.browser; try { + // TODO(COMPASS-8071): check that the shell is there before toggling the + // section so we can have some level of confidence that toggling the + // setting did something and that it would be detected by our assertions + // below. await browser.openSettingsModal('Privacy'); await browser.clickVisible(Selectors.GeneralSettingsButton); { @@ -201,6 +205,8 @@ describe('Global preferences', function () { 'This setting cannot be modified as it has been set in the global Compass configuration file.' ); } + // TODO(COMPASS-8071): This just passes for multiple connections because + // the shell section is never there. { const shellSection = await browser.$(Selectors.ShellSection); const isShellSectionExisting = await shellSection.isExisting(); diff --git a/packages/compass-e2e-tests/tests/in-use-encryption.test.ts b/packages/compass-e2e-tests/tests/in-use-encryption.test.ts index 312783f53dd..088dc3fa66e 100644 --- a/packages/compass-e2e-tests/tests/in-use-encryption.test.ts +++ b/packages/compass-e2e-tests/tests/in-use-encryption.test.ts @@ -7,8 +7,7 @@ import { serverSatisfies, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -16,17 +15,25 @@ import { getFirstListDocument } from '../helpers/read-first-document-content'; import { MongoClient } from 'mongodb'; import delay from '../helpers/delay'; +import type { ConnectFormState } from '../helpers/connect-form-state'; const CONNECTION_HOSTS = '127.0.0.1:27091'; const CONNECTION_STRING = `mongodb://${CONNECTION_HOSTS}/`; -async function refresh(browser: CompassBrowser) { +async function refresh(browser: CompassBrowser, connectionName: string) { // We refresh immediately after running commands, so there is an opportunity // for race conditions. Ideally we'd wait for something to become true, then // hit refresh, then wait for a transition to occur that will correlate to the // data actually being refreshed and arriving. - await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.RefreshDatabasesItem + ); + } else { + await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + } } /** @@ -43,18 +50,13 @@ async function refresh(browser: CompassBrowser) { * and never sent in plaintext. */ describe('CSFLE / QE', function () { + // reuse the same connectionName so that connectWithConnectionForm (or + // connectWithConnectionString for that matter) will remove the connection + // every time before connecting + const connectionName = 'fle'; + before(function () { skipForWeb(this, 'not available in compass-web'); - - // TODO(COMPASS-8003): This will have to be refactored for multiple - // connections because saving a favorite is now part of the connect modal - // and there is no favorite modal anymore. Many of these tests also use - // shellEval() which is better to port once we have the shell working - // properly in multiple connections and they also use a refresh - // databases&collections button that doesn't exist yet. - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } }); describe('server version gte 4.2.20 and not a linux platform', function () { @@ -77,10 +79,7 @@ describe('CSFLE / QE', function () { }); beforeEach(async function () { - const sidebar = await browser.$(Selectors.SidebarTitle); - if (await sidebar.isDisplayed()) { - await browser.disconnect(); - } + await browser.disconnectAll(); }); afterEach(async function () { @@ -96,8 +95,7 @@ describe('CSFLE / QE', function () { }); it('does not store KMS settings if the checkbox is not set', async function () { - const favoriteName = 'My FLE Favorite'; - const options = { + const options: ConnectFormState = { hosts: [CONNECTION_HOSTS], fleKeyVaultNamespace: `${databaseName}.keyvault`, fleKey: 'A'.repeat(128), @@ -115,63 +113,94 @@ describe('CSFLE / QE', function () { }`, }; - await browser.setConnectFormState(options); - // Save & Connect - await browser.clickVisible( - TEST_MULTIPLE_CONNECTIONS - ? Selectors.ConnectionModalConnectButton - : Selectors.SaveAndConnectButton - ); - await browser.$(Selectors.FavoriteModal).waitForDisplayed(); - await browser.setValueVisible(Selectors.FavoriteNameInput, favoriteName); - await browser.clickVisible( - `${Selectors.FavoriteColorSelector} [data-testid="color-pick-color2"]` - ); + if (TEST_MULTIPLE_CONNECTIONS) { + // in the multiple connections world the favorite form fields are just + // part of the connection form + options.connectionName = connectionName; + options.connectionColor = 'color1'; + options.connectionFavorite = true; + + await browser.setConnectFormState(options); + + await browser.clickVisible(Selectors.ConnectionModalConnectButton); + } else { + // in the single connections world the favorite form fields are in a + // separate modal + await browser.setConnectFormState(options); + await browser.clickVisible(Selectors.SaveAndConnectButton); + await browser.$(Selectors.FavoriteModal).waitForDisplayed(); + await browser.setValueVisible( + Selectors.FavoriteNameInput, + connectionName + ); + await browser.clickVisible( + `${Selectors.FavoriteColorSelector} [data-testid="color-pick-color2"]` + ); - // The modal's button text should read Save & Connect and not the default Save - expect(await browser.$(Selectors.FavoriteSaveButton).getText()).to.equal( - 'Save & Connect' - ); + // The modal's button text should read Save & Connect and not the default Save + expect( + await browser.$(Selectors.FavoriteSaveButton).getText() + ).to.equal('Save & Connect'); - await browser.$(Selectors.FavoriteSaveButton).waitForEnabled(); - await browser.clickVisible(Selectors.FavoriteSaveButton); - await browser.$(Selectors.FavoriteModal).waitForExist({ reverse: true }); + await browser.$(Selectors.FavoriteSaveButton).waitForEnabled(); + await browser.clickVisible(Selectors.FavoriteSaveButton); + await browser + .$(Selectors.FavoriteModal) + .waitForExist({ reverse: true }); + } // Wait for it to connect - const element = await browser.$(Selectors.MyQueriesList); - await element.waitForDisplayed(); + await browser.waitForConnectionResult('success'); + // extra pause to make very sure that it saved the connection before we disconnect await delay(10000); try { - await browser.disconnect(); + await browser.disconnectAll(); } catch (err) { console.error('Error during disconnect:'); console.error(err); } + // extra pause to make very sure that it loaded the connections await delay(10000); await browser.screenshot('saved-connections-after-disconnect.png'); - await browser.clickVisible( - Selectors.sidebarConnectionButton(favoriteName) - ); + if (TEST_MULTIPLE_CONNECTIONS) { + // in the multiple connections world, if we clicked the connection it + // would connect and that's not what we want in this case. So we select + // edit from the menu. + await browser.selectConnectionMenuItem( + connectionName, + Selectors.Multiple.EditConnectionItem + ); + } else { + // in the single connections world, clicking the favorite connection in + // the sidebar doesn't connect, it just pre-populates the form + await browser.clickVisible( + Selectors.sidebarConnectionButton(connectionName) + ); + } + + // The modal should appear and the title of the modal should be the favorite name await browser.waitUntil(async () => { const connectionTitleSelector = TEST_MULTIPLE_CONNECTIONS ? Selectors.ConnectionModalTitle : Selectors.ConnectionTitle; const text = await browser.$(connectionTitleSelector).getText(); - return text === favoriteName; + return text === connectionName; }); + // The form should have the relevant field values const state = await browser.getConnectFormState(); - expect(state.connectionString).to.be.equal(CONNECTION_STRING); - expect(state.fleKeyVaultNamespace).to.be.equal('fle-test.keyvault'); + expect(state.fleKeyVaultNamespace).to.be.equal( + `${databaseName}.keyvault` + ); expect(state.fleStoreCredentials).to.be.equal(false); expect(state.fleEncryptedFieldsMap).to.include( - 'fle-test.my-another-collection' + `${databaseName}.${collectionName}` ); }); }); @@ -189,6 +218,7 @@ describe('CSFLE / QE', function () { const collectionName = 'my-encrypted-collection'; let compass: Compass; let browser: CompassBrowser; + const connectionName = 'fle'; before(async function () { compass = await init(this.test?.fullTitle()); @@ -197,8 +227,15 @@ describe('CSFLE / QE', function () { hosts: [CONNECTION_HOSTS], fleKeyVaultNamespace: `${databaseName}.keyvault`, fleKey: 'A'.repeat(128), - connectionName: this.test?.fullTitle(), + connectionName, }); + + // create a collection so we can navigate to the database + await browser.shellEval( + connectionName, + `db.getMongo().getDB('${databaseName}').createCollection('default')` + ); + await refresh(browser, connectionName); }); after(async function () { @@ -207,13 +244,6 @@ describe('CSFLE / QE', function () { } }); - beforeEach(async function () { - await browser.shellEval( - `db.getMongo().getDB('${databaseName}').createCollection('default')` - ); - await refresh(browser); - }); - afterEach(async function () { if (compass) { await screenshotIfFailed(compass, this.currentTest); @@ -222,7 +252,7 @@ describe('CSFLE / QE', function () { it('can create a fle2 collection with encryptedFields', async function () { await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); @@ -244,7 +274,7 @@ describe('CSFLE / QE', function () { ); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); @@ -258,6 +288,7 @@ describe('CSFLE / QE', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -330,10 +361,10 @@ describe('CSFLE / QE', function () { ] } }`, - connectionName: this.test?.fullTitle(), + connectionName, }); - await browser.shellEval(`use ${databaseName}`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, 'db.keyvault.insertOne({' + '"_id": UUID("28bbc608-524e-4717-9246-33633361788e"),' + '"keyMaterial": BinData(0, "/yeYyj8IxowIIZGOs5iUcJaUm7KHhoBDAAzNxBz8c5mr2hwBIsBWtDiMU4nhx3fCBrrN3cqXG6jwPgR22gZDIiMZB5+xhplcE9EgNoEEBtRufBE2VjtacpXoqrMgW0+m4Dw76qWUCsF/k1KxYBJabM35KkEoD6+BI1QxU0rwRsR1rE/OLuBPKOEq6pmT5x74i+ursFlTld+5WiOySRDcZg=="),' + @@ -341,9 +372,11 @@ describe('CSFLE / QE', function () { '"updateDate": ISODate("2022-05-27T18:28:33.925Z"),' + '"status": 0,' + '"masterKey": { "provider" : "local" }' + - '})' - ); - await refresh(browser); + '})', + // make sure there is a collection so we can navigate to the database + `db.getMongo().getDB('${databaseName}').createCollection('default')`, + ]); + await refresh(browser, connectionName); plainMongo = await MongoClient.connect(CONNECTION_STRING); }); @@ -364,14 +397,14 @@ describe('CSFLE / QE', function () { it('can create a fle2 collection without encryptedFields', async function () { await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); await browser.clickVisible(Selectors.DatabaseCreateCollectionButton); await browser.addCollection(collectionName); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + connectionName, databaseName ); @@ -395,6 +428,7 @@ describe('CSFLE / QE', function () { ); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -411,10 +445,14 @@ describe('CSFLE / QE', function () { }); it('can insert a document with an encrypted field and a non-encrypted field', async function () { - await browser.shellEval(`db.createCollection('${collectionName}')`); - await refresh(browser); + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -467,15 +505,17 @@ describe('CSFLE / QE', function () { }); it('shows a decrypted field icon', async function () { - await browser.shellEval(`db.createCollection('${collectionName}')`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -513,15 +553,17 @@ describe('CSFLE / QE', function () { const toString = (v: any) => v?.toISOString?.()?.replace(/Z$/, '+00:00') ?? JSON.stringify(v); - await browser.shellEval(`db.createCollection('${coll}')`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${coll}')`, `db[${JSON.stringify( coll - )}].insertOne({ "${field}": ${oldValue}, "name": "Person X" })` - ); - await refresh(browser); + )}].insertOne({ "${field}": ${oldValue}, "name": "Person X" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, coll, 'Documents' @@ -581,15 +623,17 @@ describe('CSFLE / QE', function () { } it('can edit and query the encrypted field in the JSON view', async function () { - await browser.shellEval(`db.createCollection('${collectionName}')`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person X" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -635,13 +679,14 @@ describe('CSFLE / QE', function () { }); it('can not edit the copied encrypted field', async function () { - await browser.shellEval(`db.createCollection('${collectionName}')`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })`, + ]); + await refresh(browser, connectionName); const doc = await plainMongo .db(databaseName) @@ -654,8 +699,9 @@ describe('CSFLE / QE', function () { name: 'La La', }); - await refresh(browser); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -716,13 +762,14 @@ describe('CSFLE / QE', function () { }); it('shows incomplete schema for cloned document banner', async function () { - await browser.shellEval(`db.createCollection('${collectionName}')`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "First" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "First" })`, + ]); + await refresh(browser, connectionName); const doc = await plainMongo .db(databaseName) @@ -735,8 +782,9 @@ describe('CSFLE / QE', function () { name: 'Second', }); - await refresh(browser); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -810,15 +858,17 @@ describe('CSFLE / QE', function () { }); it('can enable and disable in-use encryption from the sidebar', async function () { - await browser.shellEval(`db.createCollection('${collectionName}')`); - await browser.shellEval( + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + `db.createCollection('${collectionName}')`, `db[${JSON.stringify( collectionName - )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })` - ); - await refresh(browser); + )}].insertOne({ "phoneNumber": "30303030", "name": "Person Z" })`, + ]); + await refresh(browser, connectionName); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' @@ -834,17 +884,25 @@ describe('CSFLE / QE', function () { name: '"Person Z"', }); - await browser.clickVisible(Selectors.FleConnectionConfigurationBanner); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Selectors.Multiple.InUseEncryptionMarker + ) + ); + } else { + await browser.clickVisible(Selectors.Single.InUseEncryptionMarker); + } - let modal = await browser.$(Selectors.CSFLEConnectionModal); - await modal.waitForDisplayed(); + await browser.$(Selectors.CSFLEConnectionModal).waitForDisplayed(); await browser.clickVisible(Selectors.SetCSFLEEnabledLabel); - await browser.screenshot('csfle-connection-modal.png'); - await browser.clickVisible(Selectors.CSFLEConnectionModalCloseButton); - await modal.waitForDisplayed({ reverse: true }); + await browser + .$(Selectors.CSFLEConnectionModal) + .waitForDisplayed({ reverse: true }); const encryptedResult = await getFirstListDocument(browser); @@ -856,15 +914,25 @@ describe('CSFLE / QE', function () { name: '"Person Z"', }); - await browser.clickVisible(Selectors.FleConnectionConfigurationBanner); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + connectionName, + Selectors.Multiple.InUseEncryptionMarker + ) + ); + } else { + await browser.clickVisible(Selectors.Single.InUseEncryptionMarker); + } - modal = await browser.$(Selectors.CSFLEConnectionModal); - await modal.waitForDisplayed(); + await browser.$(Selectors.CSFLEConnectionModal).waitForDisplayed(); await browser.clickVisible(Selectors.SetCSFLEEnabledLabel); await browser.clickVisible(Selectors.CSFLEConnectionModalCloseButton); - await modal.waitForDisplayed({ reverse: true }); + await browser + .$(Selectors.CSFLEConnectionModal) + .waitForDisplayed({ reverse: true }); decryptedResult = await getFirstListDocument(browser); @@ -911,91 +979,86 @@ describe('CSFLE / QE', function () { // connect without QE and insert some fixture data that we generated against a 6.x database using the shell await browser.connectWithConnectionForm({ hosts: [CONNECTION_HOSTS], - connectionName: this.test?.fullTitle(), + connectionName, }); - await browser.shellEval(`use ${databaseName}`); - - // insert the dataKey that was used to encrypt the payloads used below - await browser.shellEval( - 'dataKey = new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1");' - ); - await browser.shellEval(`db.getCollection("keyvault").insertOne({ - _id: new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1"), - keyMaterial: Binary.createFromHexString("519e2b15d20f00955a3960aab31e70a8e3fdb661129ef0d8a752291599488f8fda23ca64ddcbced93dbc715d03f45ab53a8e8273f2230c41c0e64d9ef746d6959cbdc1abcf0e9d020856e2da09a91ef129ac60ef13a98abcd5ee0cbfba21f1de153974996ab002bddccf7dc0268fed90a172dc373e90b63bc2369a5a1bfc78e0c2d7d81e65e970a38ca585248fef53b70452687024b8ecd308930a25414518e3", 0), - creationDate: ISODate("2023-05-05T10:58:12.473Z"), - updateDate: ISODate("2023-05-05T10:58:12.473Z"), - status: 0, - masterKey: { provider: 'local' } - });`); - - await browser.shellEval(`db.runCommand({ - create: '${collectionName}', - encryptedFields: { - fields: [{ - keyId: dataKey, - path: 'v', - bsonType: 'string', - queries: [{ queryType: 'equality' }] - }] - } - });`); - - // these payloads were encrypted using dataKey - await browser.shellEval(`db.runCommand({ - insert: '${collectionName}', - documents: [ - { - _id: 'asdf', - v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b1025438da7f9034a7d6bf03452c9b910381a16b4a0d52592ed6eafc64cc45dde441ac136269b4606f197e939fd54dd9fb257ce2c5afe94853b3b150a9101d65a3063f948ce05350fc4a5811eb5f29793dfd5a9cab77c680bba17f91845895cfd080c123e02a3f1c7e5d5c8c6448a0ac7d624669d0306be6fdcea35106062e742bec39a9873de969196ad95960d4bc247e98dc88a33d9c974646c8283178f3198749c7f24dbd66dc5e7ecf42efc08f64b6a646aa50e872a6f30907b54249039f3226af503d2e2e947323", 6), - __safeContent__: [ - Binary.createFromHexString("91865d04a1a1719e2ef89d66eeb8a35515f22470558831fe9494f011e9a209c3", 0) - ] - }, - { - _id: 'ghjk', - v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b10299f34210f149673b61f0d369f89290577c410b800ff38ed10eec235aef3677d3594c6371dd5b8f8d4c34769228bf7aea00b1754036a5850a4fef25c40969451151695614ae6142e954bab6c72080b5f43ccac774f6a1791bcc2ca4ca8998b9d5148441180631c7d8136034ff5019ca31a082464ec2fdcf212460a121d14dec3b8ee313541dc46689c79636929f0828dfdef7dfd4d53e1a924bbf70be34b1668d9352f6102a32265ec45d9c5cc0d7cf5f9266cf161497ee5b4a9495e16926b09282c6e4029d22d88e", 6), - __safeContent__: [ - Binary.createFromHexString("b04e26633d569cb47b9cbec650d812a597ffdadacb9a61ee7b1661f52228d661", 0) - ] - } - ], - bypassDocumentValidation: true - });`); - - await browser.shellEval(`db.runCommand({ - insert: 'enxcol_.${collectionName}.ecoc', - documents: [ - { - _id: ObjectId("6454e14689ef42f381f7336b"), - fieldName: 'v', - value: Binary.createFromHexString("3eb89d3a95cf955ca0c8c56e54018657a45daaf465dd967d9b24895a188d7e3055734f3c0af88302ceab460874f3806fe52fa4541c9f4b32b5cee6c5a6df9399da664f576dd9bde23bce92f5deea0cb3", 0) - }, - { - _id: ObjectId("6454e14689ef42f381f73385"), - fieldName: 'v', - value: Binary.createFromHexString("2299cd805a28efb6503120e0250798f1b19137d8234690d12eb7e3b7fa74edd28e80c26022c00d53f5983f16e7b5abb7c3b95e30f265a7ba36adb290eda39370b30cedba960a4002089eb5de2fd118fc", 0) - } - ], - bypassDocumentValidation: true - });`); - - await browser.shellEval(`db.runCommand({ - insert: 'enxcol_.${collectionName}.esc', - documents: [ - { - _id: Binary.createFromHexString("51db700df02cbbfa25498921f858d3a9d5568cabb97f7283e7b3c9d0e3520ac4", 0), - value: Binary.createFromHexString("dc7169f28df2c990551b098b8dec8f5b1bfeb65d3f40d0fdb241a518310674a6", 0) - }, - { - _id: Binary.createFromHexString("948b3d29e335485b0503ffc6ade6bfa6fce664c2a1d14790a523c09223da3f09", 0), - value: Binary.createFromHexString("7622097476c59c0ca5bf9d05a52fe725517e03ad811f6c073b0d0184a9d26131", 0) + await browser.shellEval(connectionName, [ + `use ${databaseName}`, + // insert the dataKey that was used to encrypt the payloads used below + 'dataKey = new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1");', + `db.getCollection("keyvault").insertOne({ + _id: new UUID("2871cd1d-8317-4d0c-92be-1ac934ed26b1"), + keyMaterial: Binary.createFromHexString("519e2b15d20f00955a3960aab31e70a8e3fdb661129ef0d8a752291599488f8fda23ca64ddcbced93dbc715d03f45ab53a8e8273f2230c41c0e64d9ef746d6959cbdc1abcf0e9d020856e2da09a91ef129ac60ef13a98abcd5ee0cbfba21f1de153974996ab002bddccf7dc0268fed90a172dc373e90b63bc2369a5a1bfc78e0c2d7d81e65e970a38ca585248fef53b70452687024b8ecd308930a25414518e3", 0), + creationDate: ISODate("2023-05-05T10:58:12.473Z"), + updateDate: ISODate("2023-05-05T10:58:12.473Z"), + status: 0, + masterKey: { provider: 'local' } + });`, + `db.runCommand({ + create: '${collectionName}', + encryptedFields: { + fields: [{ + keyId: dataKey, + path: 'v', + bsonType: 'string', + queries: [{ queryType: 'equality' }] + }] } - ], - bypassDocumentValidation: true - });`); + });`, + // these payloads were encrypted using dataKey + `db.runCommand({ + insert: '${collectionName}', + documents: [ + { + _id: 'asdf', + v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b1025438da7f9034a7d6bf03452c9b910381a16b4a0d52592ed6eafc64cc45dde441ac136269b4606f197e939fd54dd9fb257ce2c5afe94853b3b150a9101d65a3063f948ce05350fc4a5811eb5f29793dfd5a9cab77c680bba17f91845895cfd080c123e02a3f1c7e5d5c8c6448a0ac7d624669d0306be6fdcea35106062e742bec39a9873de969196ad95960d4bc247e98dc88a33d9c974646c8283178f3198749c7f24dbd66dc5e7ecf42efc08f64b6a646aa50e872a6f30907b54249039f3226af503d2e2e947323", 6), + __safeContent__: [ + Binary.createFromHexString("91865d04a1a1719e2ef89d66eeb8a35515f22470558831fe9494f011e9a209c3", 0) + ] + }, + { + _id: 'ghjk', + v: Binary.createFromHexString("072871cd1d83174d0c92be1ac934ed26b10299f34210f149673b61f0d369f89290577c410b800ff38ed10eec235aef3677d3594c6371dd5b8f8d4c34769228bf7aea00b1754036a5850a4fef25c40969451151695614ae6142e954bab6c72080b5f43ccac774f6a1791bcc2ca4ca8998b9d5148441180631c7d8136034ff5019ca31a082464ec2fdcf212460a121d14dec3b8ee313541dc46689c79636929f0828dfdef7dfd4d53e1a924bbf70be34b1668d9352f6102a32265ec45d9c5cc0d7cf5f9266cf161497ee5b4a9495e16926b09282c6e4029d22d88e", 6), + __safeContent__: [ + Binary.createFromHexString("b04e26633d569cb47b9cbec650d812a597ffdadacb9a61ee7b1661f52228d661", 0) + ] + } + ], + bypassDocumentValidation: true + });`, + `db.runCommand({ + insert: 'enxcol_.${collectionName}.ecoc', + documents: [ + { + _id: ObjectId("6454e14689ef42f381f7336b"), + fieldName: 'v', + value: Binary.createFromHexString("3eb89d3a95cf955ca0c8c56e54018657a45daaf465dd967d9b24895a188d7e3055734f3c0af88302ceab460874f3806fe52fa4541c9f4b32b5cee6c5a6df9399da664f576dd9bde23bce92f5deea0cb3", 0) + }, + { + _id: ObjectId("6454e14689ef42f381f73385"), + fieldName: 'v', + value: Binary.createFromHexString("2299cd805a28efb6503120e0250798f1b19137d8234690d12eb7e3b7fa74edd28e80c26022c00d53f5983f16e7b5abb7c3b95e30f265a7ba36adb290eda39370b30cedba960a4002089eb5de2fd118fc", 0) + } + ], + bypassDocumentValidation: true + });`, + `db.runCommand({ + insert: 'enxcol_.${collectionName}.esc', + documents: [ + { + _id: Binary.createFromHexString("51db700df02cbbfa25498921f858d3a9d5568cabb97f7283e7b3c9d0e3520ac4", 0), + value: Binary.createFromHexString("dc7169f28df2c990551b098b8dec8f5b1bfeb65d3f40d0fdb241a518310674a6", 0) + }, + { + _id: Binary.createFromHexString("948b3d29e335485b0503ffc6ade6bfa6fce664c2a1d14790a523c09223da3f09", 0), + value: Binary.createFromHexString("7622097476c59c0ca5bf9d05a52fe725517e03ad811f6c073b0d0184a9d26131", 0) + } + ], + bypassDocumentValidation: true + });`, + ]); - await browser.disconnect(); + await browser.disconnectAll(); // now connect with QE and check that we can query the data stored in a 6.x database await browser.connectWithConnectionForm({ @@ -1006,6 +1069,7 @@ describe('CSFLE / QE', function () { }); await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, databaseName, collectionName, 'Documents' diff --git a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts index 3a2910d60dd..93a9844814f 100644 --- a/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-databases-tab.test.ts @@ -5,8 +5,8 @@ import { init, cleanup, screenshotIfFailed, - connectionNameFromString, DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -30,10 +30,7 @@ describe('Instance databases tab', function () { await createDummyCollections(); await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); }); after(async function () { @@ -103,10 +100,7 @@ describe('Instance databases tab', function () { 'add-database-modal-basic.png' ); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); const selector = Selectors.databaseCard(dbName); await browser.scrollToVirtualItem( @@ -142,7 +136,7 @@ describe('Instance databases tab', function () { // the app should stay on the instance Databases tab. await browser.waitUntilActiveConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'Databases' ); }); @@ -152,10 +146,7 @@ describe('Instance databases tab', function () { const dbSelector = Selectors.databaseCard(db); // Browse to the databases tab - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); // Make sure the db card we're going to drop is in there. await browser.scrollToVirtualItem( diff --git a/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts b/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts index bfe1aa54e25..dcf093c0162 100644 --- a/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts +++ b/packages/compass-e2e-tests/tests/instance-performance-tab.test.ts @@ -5,8 +5,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -23,7 +22,7 @@ describe('Instance performance tab', function () { await browser.connectWithConnectionString(); await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'Performance' ); }); diff --git a/packages/compass-e2e-tests/tests/instance-sidebar.test.ts b/packages/compass-e2e-tests/tests/instance-sidebar.test.ts index 1f669be3705..79b0f019d46 100644 --- a/packages/compass-e2e-tests/tests/instance-sidebar.test.ts +++ b/packages/compass-e2e-tests/tests/instance-sidebar.test.ts @@ -8,7 +8,7 @@ import { DEFAULT_CONNECTION_STRING, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; @@ -19,6 +19,7 @@ const { expect } = chai; describe('Instance sidebar', function () { let compass: Compass; let browser: CompassBrowser; + let connectionId: string | undefined; before(async function () { compass = await init(this.test?.fullTitle()); @@ -28,6 +29,7 @@ describe('Instance sidebar', function () { beforeEach(async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); + connectionId = await browser.getConnectionIdByName(DEFAULT_CONNECTION_NAME); }); after(async function () { @@ -41,11 +43,9 @@ describe('Instance sidebar', function () { it('has a connection info modal with connection info', async function () { skipForWeb(this, "these actions don't exist in compass-web"); - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); - if (TEST_MULTIPLE_CONNECTIONS) { await browser.selectConnectionMenuItem( - connectionName, + DEFAULT_CONNECTION_NAME, Selectors.Multiple.ClusterInfoItem ); } else { @@ -65,12 +65,17 @@ describe('Instance sidebar', function () { it('contains a dbs/collections tree view', async function () { const dbName = 'test'; const collectionName = 'numbers'; - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.clickVisible(Selectors.sidebarDatabaseToggle(dbName)); + await browser.clickVisible( + Selectors.sidebarDatabaseToggle(connectionId, dbName) + ); const collectionSelector = Selectors.sidebarCollection( + connectionId, dbName, collectionName ); @@ -113,10 +118,16 @@ describe('Instance sidebar', function () { return treeItems.length === expectedCount; }); - const dbElement = await browser.$(Selectors.sidebarDatabase('test')); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, 'test') + ); expect(await dbElement.isDisplayed()).to.be.true; - const collectionSelector = Selectors.sidebarCollection('test', 'numbers'); + const collectionSelector = Selectors.sidebarCollection( + connectionId, + 'test', + 'numbers' + ); await browser.scrollToVirtualItem( Selectors.SidebarNavigationTree, collectionSelector, @@ -130,7 +141,9 @@ describe('Instance sidebar', function () { // wait for something that didn't match the previous search to show up to make sure that it reset // (otherwise future tests will fail because the new dbs/collections won't match the filter) - const adminElement = await browser.$(Selectors.sidebarDatabase('admin')); + const adminElement = await browser.$( + Selectors.sidebarDatabase(connectionId, 'admin') + ); await adminElement.waitForDisplayed(); }); @@ -142,7 +155,6 @@ describe('Instance sidebar', function () { ? Selectors.Multiple : Selectors.Single; - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); const dbName = `my-sidebar-database-${Date.now()}`; const collectionName = 'my-collection'; @@ -150,13 +162,23 @@ describe('Instance sidebar', function () { // navigate to the databases tab so that the connection is // active/highlighted and then the add button and three dot menu will // display without needing to hover - await browser.navigateToConnectionTab(connectionName, 'Databases'); + await browser.navigateToConnectionTab( + DEFAULT_CONNECTION_NAME, + 'Databases' + ); } // open the create database modal from the sidebar - await browser.clickVisible(Sidebar.CreateDatabaseButton, { - screenshot: 'before-can-create-a-database-and-drop-it-click.png', - }); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.clickVisible( + Selectors.sidebarConnectionActionButton( + DEFAULT_CONNECTION_NAME, + Sidebar.CreateDatabaseButton + ) + ); + } else { + await browser.clickVisible(Sidebar.CreateDatabaseButton); + } await browser.addDatabase(dbName, collectionName); @@ -167,15 +189,15 @@ describe('Instance sidebar', function () { .$(Selectors.collectionSubTab('Documents', true)) .waitForDisplayed(); - await browser.clickVisible(Selectors.sidebarDatabase(dbName)); + await browser.clickVisible(Selectors.sidebarDatabase(connectionId, dbName)); // wait for it to appear const collectionElement = await browser.$( - Selectors.sidebarCollection(dbName, collectionName) + Selectors.sidebarCollection(connectionId, dbName, collectionName) ); await collectionElement.waitForDisplayed(); - await browser.dropDatabaseFromSidebar(dbName); + await browser.dropDatabaseFromSidebar(DEFAULT_CONNECTION_NAME, dbName); }); it('can create a collection and drop it', async function () { @@ -185,10 +207,12 @@ describe('Instance sidebar', function () { await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); await browser.clickVisible(Selectors.CreateCollectionButton); @@ -200,14 +224,26 @@ describe('Instance sidebar', function () { const tabSelectedSelector = Selectors.collectionSubTab('Documents', true); await browser.$(tabSelectedSelector).waitForDisplayed(); - await browser.dropCollectionFromSidebar(dbName, collectionName); + await browser.dropCollectionFromSidebar( + DEFAULT_CONNECTION_NAME, + dbName, + collectionName + ); }); it('can refresh the databases', async function () { - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); const db = 'test'; const coll = `coll_${Date.now()}`; + // expand the database entry in the sidebar + await browser.clickVisible(Selectors.sidebarDatabase(connectionId, db)); + + // wait until the collections finish loading + const numbersCollectionElement = await browser.$( + Selectors.sidebarCollection(connectionId, db, 'numbers') + ); + await numbersCollectionElement.waitForDisplayed(); + const mongoClient = new MongoClient(DEFAULT_CONNECTION_STRING); await mongoClient.connect(); try { @@ -219,16 +255,17 @@ describe('Instance sidebar', function () { if (TEST_MULTIPLE_CONNECTIONS) { await browser.selectConnectionMenuItem( - connectionName, + DEFAULT_CONNECTION_NAME, Selectors.Multiple.RefreshDatabasesItem ); } else { await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); } - await browser.clickVisible(Selectors.sidebarDatabase(db)); - const collectionElement = await browser.$( - Selectors.sidebarCollection(db, coll) + + // wait for the new collection we added via the driver to appear. + const newCollectionElement = await browser.$( + Selectors.sidebarCollection(connectionId, db, coll) ); - await collectionElement.waitForDisplayed(); + await newCollectionElement.waitForDisplayed(); }); }); diff --git a/packages/compass-e2e-tests/tests/logging.test.ts b/packages/compass-e2e-tests/tests/logging.test.ts index fd12a19f1e6..94fd02fc80d 100644 --- a/packages/compass-e2e-tests/tests/logging.test.ts +++ b/packages/compass-e2e-tests/tests/logging.test.ts @@ -5,6 +5,7 @@ import { screenshotIfFailed, skipForWeb, TEST_MULTIPLE_CONNECTIONS, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import { startTelemetryServer } from '../helpers/telemetry'; @@ -13,11 +14,6 @@ import type { Telemetry, LogEntry } from '../helpers/telemetry'; describe('Logging and Telemetry integration', function () { before(function () { skipForWeb(this, 'telemetry not yet available in compass-web'); - - // TODO(COMPASS-8004): skipping for multiple connections due to the use of shellEval for now - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } }); describe('after running an example path through Compass', function () { @@ -31,8 +27,17 @@ describe('Logging and Telemetry integration', function () { try { await browser.connectWithConnectionString(); - await browser.shellEval('use test'); - await browser.shellEval('db.runCommand({ connectionStatus: 1 })'); + + if (TEST_MULTIPLE_CONNECTIONS) { + // make sure we generate the screen event that the tests expect + await browser.navigateToMyQueries(); + } + + await browser.shellEval(DEFAULT_CONNECTION_NAME, 'use test'); + await browser.shellEval( + DEFAULT_CONNECTION_NAME, + 'db.runCommand({ connectionStatus: 1 })' + ); } finally { await cleanup(compass); await telemetry.stop(); diff --git a/packages/compass-e2e-tests/tests/instance-my-queries-tab.test.ts b/packages/compass-e2e-tests/tests/my-queries-tab.test.ts similarity index 85% rename from packages/compass-e2e-tests/tests/instance-my-queries-tab.test.ts rename to packages/compass-e2e-tests/tests/my-queries-tab.test.ts index ba887ad8d07..3e6f912c905 100644 --- a/packages/compass-e2e-tests/tests/instance-my-queries-tab.test.ts +++ b/packages/compass-e2e-tests/tests/my-queries-tab.test.ts @@ -7,21 +7,13 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, TEST_MULTIPLE_CONNECTIONS, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; -async function navigateToMyQueries(browser: CompassBrowser) { - await browser.clickVisible(Selectors.SidebarMyQueriesTab); - await browser - .$(Selectors.workspaceTab('My Queries', true)) - .waitForDisplayed(); -} - async function openMenuForQueryItem( browser: CompassBrowser, favoriteQueryName: string @@ -48,18 +40,13 @@ async function openMenuForQueryItem( await browser.$(Selectors.SavedItemMenu).waitForDisplayed(); } -describe('Instance my queries tab', function () { +describe('My Queries tab', function () { let compass: Compass; let browser: CompassBrowser; before(async function () { skipForWeb(this, 'saved queries not yet available in compass-web'); - // TODO(COMPASS-8006): best to only skip this until the My Queries tab is ported - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } - compass = await init(this.test?.fullTitle()); browser = compass.browser; }); @@ -72,10 +59,6 @@ describe('Instance my queries tab', function () { return; } - if (TEST_MULTIPLE_CONNECTIONS) { - return; - } - await cleanup(compass); }); afterEach(async function () { @@ -87,7 +70,12 @@ describe('Instance my queries tab', function () { const newFavoriteQueryName = 'my renamed query'; // Run a query - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', `{i: {$gt: 10}}`, { limit: '10', }); @@ -111,11 +99,8 @@ describe('Instance my queries tab', function () { await browser.clickVisible(Selectors.QueryHistorySaveFavoriteItemButton); await browser.closeWorkspaceTabs(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); - await navigateToMyQueries(browser); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); + await browser.navigateToMyQueries(); // open the menu await openMenuForQueryItem(browser, favoriteQueryName); @@ -163,9 +148,22 @@ describe('Instance my queries tab', function () { await renameModal.waitForDisplayed({ reverse: true }); // rename the collection associated with the query to force the open item modal - await browser.shellEval('use test'); - await browser.shellEval('db.numbers.renameCollection("numbers-renamed")'); - await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + await browser.shellEval(DEFAULT_CONNECTION_NAME, 'use test'); + await browser.shellEval( + DEFAULT_CONNECTION_NAME, + 'db.numbers.renameCollection("numbers-renamed")' + ); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + DEFAULT_CONNECTION_NAME, + Selectors.Multiple.RefreshDatabasesItem + ); + + // go to My Queries because for multiple connections it is not the default tab + await browser.navigateToMyQueries(); + } else { + await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + } // browse to the query await browser.clickVisible(Selectors.myQueriesItem(newFavoriteQueryName)); @@ -197,11 +195,8 @@ describe('Instance my queries tab', function () { // back to my queries await browser.closeWorkspaceTabs(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); - await navigateToMyQueries(browser); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); + await browser.navigateToMyQueries(); // open the menu await openMenuForQueryItem(browser, newFavoriteQueryName); @@ -226,7 +221,12 @@ describe('Instance my queries tab', function () { 'list of numbers greater than 10 - aggregation'; // Navigate to aggregation - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); // add stage await browser.clickVisible(Selectors.AddStageButton); await browser.$(Selectors.stageEditor(0)).waitForDisplayed(); @@ -264,7 +264,7 @@ describe('Instance my queries tab', function () { await createButton.click(); await browser.closeWorkspaceTabs(); - await navigateToMyQueries(browser); + await browser.navigateToMyQueries(); await browser.clickVisible(Selectors.myQueriesItem(savedAggregationName)); const namespace = await browser.getActiveTabNamespace(); @@ -277,10 +277,16 @@ describe('Instance my queries tab', function () { const favoriteQueryName = 'list of numbers greater than 10 - query'; const newCollectionName = 'numbers-renamed'; - /** saves a query and renames the collection associated with the query, so that the query must be opened with the "select namespace" modal */ - async function setup() { + it('users can permanently associate a new namespace for an aggregation/query', async function () { + // save a query and rename the collection associated with the query, so that the query must be opened with the "select namespace" modal + // Run a query - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', `{i: {$gt: 10}}`, { limit: '10', }); @@ -307,10 +313,10 @@ describe('Instance my queries tab', function () { await browser.closeWorkspaceTabs(); await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'Databases' ); - await navigateToMyQueries(browser); + await browser.navigateToMyQueries(); // open the menu await openMenuForQueryItem(browser, favoriteQueryName); @@ -337,16 +343,22 @@ describe('Instance my queries tab', function () { } // rename the collection associated with the query to force the open item modal - await browser.shellEval('use test'); + await browser.shellEval(DEFAULT_CONNECTION_NAME, 'use test'); await browser.shellEval( + DEFAULT_CONNECTION_NAME, `db.numbers.renameCollection('${newCollectionName}')` ); - await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); - } - beforeEach(setup); - it('users can permanently associate a new namespace for an aggregation/query', async function () { - await navigateToMyQueries(browser); + if (TEST_MULTIPLE_CONNECTIONS) { + await browser.selectConnectionMenuItem( + DEFAULT_CONNECTION_NAME, + Selectors.Multiple.RefreshDatabasesItem + ); + } else { + await browser.clickVisible(Selectors.Single.RefreshDatabasesButton); + } + + await browser.navigateToMyQueries(); // browse to the query await browser.clickVisible(Selectors.myQueriesItem(favoriteQueryName)); @@ -374,7 +386,7 @@ describe('Instance my queries tab', function () { await confirmOpenButton.click(); await openModal.waitForDisplayed({ reverse: true }); - await navigateToMyQueries(browser); + await browser.navigateToMyQueries(); const [databaseNameElement, collectionNameElement] = [ await browser.$('span=test'), diff --git a/packages/compass-e2e-tests/tests/oidc.test.ts b/packages/compass-e2e-tests/tests/oidc.test.ts index e9191abe9ab..4d0296ef1ed 100644 --- a/packages/compass-e2e-tests/tests/oidc.test.ts +++ b/packages/compass-e2e-tests/tests/oidc.test.ts @@ -7,7 +7,7 @@ import { serverSatisfies, skipForWeb, TEST_COMPASS_WEB, - TEST_MULTIPLE_CONNECTIONS, + connectionNameFromString, } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import type { Compass } from '../helpers/compass'; @@ -60,7 +60,6 @@ function getTestBrowserShellCommand() { describe('OIDC integration', function () { let compass: Compass; let browser: CompassBrowser; - let getTokenPayload: typeof oidcMockProviderConfig.getTokenPayload; let overrideRequestHandler: typeof oidcMockProviderConfig.overrideRequestHandler; let oidcMockProviderConfig: OIDCMockProviderConfig; @@ -71,6 +70,7 @@ describe('OIDC integration', function () { let tmpdir: string; let cluster: MongoCluster; let connectionString: string; + let connectionName: string; let getFavoriteConnectionInfo: ( favoriteName: string ) => Promise | undefined>; @@ -78,11 +78,6 @@ describe('OIDC integration', function () { before(async function () { skipForWeb(this, 'feature flags not yet available in compass-web'); - // TODO(COMPASS-8004): skipping for multiple connections due to the use of shellEval for now - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } - // OIDC is only supported on Linux in the 7.0+ enterprise server. if ( process.platform !== 'linux' || @@ -151,6 +146,7 @@ describe('OIDC integration', function () { cs.searchParams.set('authMechanism', 'MONGODB-OIDC'); connectionString = cs.toString(); + connectionName = connectionNameFromString(connectionString); } { @@ -203,6 +199,7 @@ describe('OIDC integration', function () { }; await browser.connectWithConnectionString(connectionString); const result: any = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 }).authInfo', true ); @@ -243,6 +240,7 @@ describe('OIDC integration', function () { await browser.connectWithConnectionString(connectionString); emitter.emit('secondConnectionEstablished'); const result: any = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 }).authInfo', true ); @@ -264,6 +262,7 @@ describe('OIDC integration', function () { }); const result: any = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 }).authInfo', true ); @@ -297,6 +296,7 @@ describe('OIDC integration', function () { afterReauth = true; await browser.clickVisible(`${modal} ${confirmButton}`); const result: any = await browser.shellEval( + connectionName, 'db.runCommand({ connectionStatus: 1 }).authInfo', true ); @@ -345,11 +345,11 @@ describe('OIDC integration', function () { ); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); await browser.selectConnection(favoriteName); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); const connectionInfo = await getFavoriteConnectionInfo(favoriteName); expect(connectionInfo?.connectionOptions?.oidc?.serializedState).to.be.a( @@ -369,7 +369,7 @@ describe('OIDC integration', function () { await browser.screenshot(`after-creating-favourite-${favoriteName}.png`); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); await browser.screenshot( `after-disconnecting-favourite-${favoriteName}.png` @@ -378,7 +378,7 @@ describe('OIDC integration', function () { // TODO(COMPASS-7810): when clicking on the favourite the element is somehow stale and then webdriverio throws await browser.selectConnection(favoriteName); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); const connectionInfo = await getFavoriteConnectionInfo(favoriteName); expect(connectionInfo?.connectionOptions?.oidc?.serializedState).to.equal( @@ -396,7 +396,7 @@ describe('OIDC integration', function () { ); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); const connectionInfo = await getFavoriteConnectionInfo(favoriteName); expect(connectionInfo?.connectionOptions?.oidc?.serializedState).to.be.a( @@ -412,7 +412,7 @@ describe('OIDC integration', function () { await browser.selectConnection(favoriteName); await browser.doConnect(); - await browser.disconnect(); + await browser.disconnectAll(); expect(oidcMockProviderEndpointAccesses['/authorize']).to.equal(1); }); diff --git a/packages/compass-e2e-tests/tests/read-only.test.ts b/packages/compass-e2e-tests/tests/read-only.test.ts index 0289abf9796..2182dd56c46 100644 --- a/packages/compass-e2e-tests/tests/read-only.test.ts +++ b/packages/compass-e2e-tests/tests/read-only.test.ts @@ -4,8 +4,7 @@ import { screenshotIfFailed, skipForWeb, TEST_MULTIPLE_CONNECTIONS, - connectionNameFromString, - DEFAULT_CONNECTION_STRING, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import { expect } from 'chai'; import * as Selectors from '../helpers/selectors'; @@ -43,18 +42,26 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.setFeature('readOnly', true); await browser.connectWithConnectionString(); - const connectionName = connectionNameFromString(DEFAULT_CONNECTION_STRING); - if (TEST_MULTIPLE_CONNECTIONS) { // navigate to the databases tab so that the connection is // active/highlighted and then the add button and three dot menu will // display without needing to hover - await browser.navigateToConnectionTab(connectionName, 'Databases'); + await browser.navigateToConnectionTab( + DEFAULT_CONNECTION_NAME, + 'Databases' + ); } - expect( - await browser.$(Sidebar.CreateDatabaseButton).isExisting() - ).to.be.equal(false); + const addDatabaseSelector = TEST_MULTIPLE_CONNECTIONS + ? Selectors.sidebarConnectionActionButton( + DEFAULT_CONNECTION_NAME, + Sidebar.CreateDatabaseButton + ) + : Sidebar.CreateDatabaseButton; + + expect(await browser.$(addDatabaseSelector).isExisting()).to.be.equal( + false + ); await browser.openSettingsModal(); const settingsModal = await browser.$(Selectors.SettingsModal); @@ -68,24 +75,31 @@ describe('readOnly: true / Read-Only Edition', function () { await settingsModal.waitForDisplayed({ reverse: true }); if (TEST_MULTIPLE_CONNECTIONS) { - await browser.navigateToConnectionTab(connectionName, 'Databases'); + await browser.navigateToConnectionTab( + DEFAULT_CONNECTION_NAME, + 'Databases' + ); } - expect( - await browser.$(Sidebar.CreateDatabaseButton).isExisting() - ).to.be.equal(true); + expect(await browser.$(addDatabaseSelector).isExisting()).to.be.equal(true); }); it('shows and hides the plus icon on the siderbar to create a collection', async function () { await createNumbersCollection(); await browser.connectWithConnectionString(); + const connectionId = await browser.getConnectionIdByName( + DEFAULT_CONNECTION_NAME + ); + const dbName = 'test'; // existing db await browser.clickVisible(Selectors.SidebarFilterInput); await browser.setValueVisible(Selectors.SidebarFilterInput, dbName); - const dbElement = await browser.$(Selectors.sidebarDatabase(dbName)); + const dbElement = await browser.$( + Selectors.sidebarDatabase(connectionId, dbName) + ); await dbElement.waitForDisplayed(); - await browser.hover(Selectors.sidebarDatabase(dbName)); + await browser.hover(Selectors.sidebarDatabase(connectionId, dbName)); let sidebarCreateCollectionButton = await browser.$( Selectors.CreateCollectionButton @@ -116,10 +130,7 @@ describe('readOnly: true / Read-Only Edition', function () { it('shows and hides the create database button on the instance tab', async function () { await browser.connectWithConnectionString(); - await browser.navigateToConnectionTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), - 'Databases' - ); + await browser.navigateToConnectionTab(DEFAULT_CONNECTION_NAME, 'Databases'); let instanceCreateDatabaseButton = await browser.$( Selectors.InstanceCreateDatabaseButton @@ -152,7 +163,7 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.connectWithConnectionString(); await browser.navigateToDatabaseCollectionsTab( - connectionNameFromString(DEFAULT_CONNECTION_STRING), + DEFAULT_CONNECTION_NAME, 'test' ); @@ -186,7 +197,12 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); let addDataButton = await browser.$(Selectors.AddDataButton); let isAddDataButtonExisting = await addDataButton.isExisting(); @@ -213,7 +229,12 @@ describe('readOnly: true / Read-Only Edition', function () { await browser.connectWithConnectionString(); // Some tests navigate away from the numbers collection aggregations tab - await browser.navigateToCollectionTab('test', 'numbers', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Aggregations' + ); await browser.clickVisible(Selectors.AddStageButton); await browser.$(Selectors.stageEditor(0)).waitForDisplayed(); @@ -261,7 +282,12 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Indexes' + ); let createIndexButton = await browser.$(Selectors.CreateIndexButton); let isCreateIndexButtonExisting = await createIndexButton.isExisting(); @@ -291,7 +317,12 @@ describe('readOnly: true / Read-Only Edition', function () { await createNumbersCollection(); await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Validation'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Validation' + ); await browser.clickVisible(Selectors.AddRuleButton); const element = await browser.$(Selectors.ValidationEditor); await element.waitForDisplayed(); diff --git a/packages/compass-e2e-tests/tests/search-indexes.test.ts b/packages/compass-e2e-tests/tests/search-indexes.test.ts index 58371eaaa6c..3e2971e69b3 100644 --- a/packages/compass-e2e-tests/tests/search-indexes.test.ts +++ b/packages/compass-e2e-tests/tests/search-indexes.test.ts @@ -8,9 +8,9 @@ import { serverSatisfies, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; -import { disconnect } from '../helpers/commands'; import { expect } from 'chai'; import { type Db, MongoClient } from 'mongodb'; @@ -193,7 +193,12 @@ describe('Search Indexes', function () { } await browser.connectWithConnectionString(currentConnectionString); - await browser.navigateToCollectionTab(DB_NAME, collectionName, 'Indexes'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + DB_NAME, + collectionName, + 'Indexes' + ); }); afterEach(async function () { @@ -206,7 +211,7 @@ describe('Search Indexes', function () { } } void mongoClient.close(); - await disconnect(browser); + await browser.disconnectAll(); await screenshotIfFailed(compass, this.currentTest); }); diff --git a/packages/compass-e2e-tests/tests/shell.test.ts b/packages/compass-e2e-tests/tests/shell.test.ts index 5561017d485..c4986670ccb 100644 --- a/packages/compass-e2e-tests/tests/shell.test.ts +++ b/packages/compass-e2e-tests/tests/shell.test.ts @@ -7,6 +7,7 @@ import { screenshotIfFailed, skipForWeb, TEST_COMPASS_WEB, + DEFAULT_CONNECTION_NAME, TEST_MULTIPLE_CONNECTIONS, } from '../helpers/compass'; import type { Compass } from '../helpers/compass'; @@ -20,11 +21,6 @@ describe('Shell', function () { before(async function () { skipForWeb(this, 'shell not available on compass-web'); - // TODO(COMPASS-8004): best to just port this once the shell works with multiple connections - if (TEST_MULTIPLE_CONNECTIONS) { - this.skip(); - } - telemetry = await startTelemetryServer(); compass = await init(this.test?.fullTitle()); browser = compass.browser; @@ -35,10 +31,6 @@ describe('Shell', function () { return; } - if (TEST_MULTIPLE_CONNECTIONS) { - return; - } - await cleanup(compass); await telemetry.stop(); }); @@ -51,7 +43,7 @@ describe('Shell', function () { it('has an info modal', async function () { await browser.connectWithConnectionString(); - await browser.showShell(); + await browser.openShell(DEFAULT_CONNECTION_NAME); await browser.clickVisible(Selectors.ShellInfoButton); const infoModalElement = await browser.$(Selectors.ShellInfoModal); @@ -60,10 +52,17 @@ describe('Shell', function () { await browser.clickVisible(Selectors.ShellInfoModalCloseButton); await infoModalElement.waitForDisplayed({ reverse: true }); - await browser.hideShell(); + await browser.closeShell(DEFAULT_CONNECTION_NAME); }); it('shows and hides shell based on settings', async function () { + // TODO(COMPASS-8071): Leaving this skipped until we decide what we're going + // to do. hide the buttons & menu items, disable them or keep them enabled + // and open a shell tab that just has an error banner. + if (TEST_MULTIPLE_CONNECTIONS) { + this.skip(); + } + await browser.connectWithConnectionString(); // Will fail if shell is not on the screen eventually diff --git a/packages/compass-e2e-tests/tests/tabs.test.ts b/packages/compass-e2e-tests/tests/tabs.test.ts index e418261d91c..53e6aaaa5a1 100644 --- a/packages/compass-e2e-tests/tests/tabs.test.ts +++ b/packages/compass-e2e-tests/tests/tabs.test.ts @@ -1,5 +1,10 @@ import type { CompassBrowser } from '../helpers/compass-browser'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import * as Selectors from '../helpers/selectors'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -36,18 +41,20 @@ describe('Global Tabs', function () { it('should open tabs over each other when not modified', async function () { for (const collName of collections) { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', collName, 'Documents', false ); } - expect(await browser.$$(Selectors.workspaceTab(null))).to.have.lengthOf(1); + expect(await browser.$$(Selectors.workspaceTab())).to.have.lengthOf(1); }); - it('should open tabs over each other when not modified', async function () { + it('should open new tabs when modified', async function () { for (const collName of collections) { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', collName, 'Documents', @@ -58,12 +65,13 @@ describe('Global Tabs', function () { Selectors.queryBarApplyFilterButton('Documents') ); } - expect(await browser.$$(Selectors.workspaceTab(null))).to.have.lengthOf(3); + expect(await browser.$$(Selectors.workspaceTab())).to.have.lengthOf(3); }); it('should close tabs without warning even when "modified" by interacting with the tab', async function () { for (const collName of collections) { await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, 'test', collName, 'Documents', @@ -75,11 +83,16 @@ describe('Global Tabs', function () { ); } await browser.closeWorkspaceTabs(false); - expect(await browser.$$(Selectors.workspaceTab(null))).to.have.lengthOf(0); + expect(await browser.$$(Selectors.workspaceTab())).to.have.lengthOf(0); }); it('should ask for confirmation when closing modified Aggregations tab', async function () { - await browser.navigateToCollectionTab('test', 'a', 'Aggregations'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'a', + 'Aggregations' + ); await browser.clickVisible( Selectors.aggregationPipelineModeToggle('as-text') @@ -101,7 +114,7 @@ describe('Global Tabs', function () { .waitForExist({ reverse: true }); // Checking first that cancel leaves the tab on the screen - expect(await browser.$$(Selectors.workspaceTab(null))).to.have.lengthOf(1); + expect(await browser.$$(Selectors.workspaceTab())).to.have.lengthOf(1); await browser.clickVisible(Selectors.CloseWorkspaceTab); await browser.$(Selectors.ConfirmTabCloseModal).waitForDisplayed(); @@ -114,6 +127,6 @@ describe('Global Tabs', function () { .waitForExist({ reverse: true }); // When confirmed, should remove the tab - expect(await browser.$$(Selectors.workspaceTab(null))).to.have.lengthOf(0); + expect(await browser.$$(Selectors.workspaceTab())).to.have.lengthOf(0); }); }); diff --git a/packages/compass-e2e-tests/tests/time-to-first-query.test.ts b/packages/compass-e2e-tests/tests/time-to-first-query.test.ts index 38ceffd4ef9..30f4f35284b 100644 --- a/packages/compass-e2e-tests/tests/time-to-first-query.test.ts +++ b/packages/compass-e2e-tests/tests/time-to-first-query.test.ts @@ -1,5 +1,10 @@ import { expect } from 'chai'; -import { init, cleanup, screenshotIfFailed } from '../helpers/compass'; +import { + init, + cleanup, + screenshotIfFailed, + DEFAULT_CONNECTION_NAME, +} from '../helpers/compass'; import type { Compass } from '../helpers/compass'; import { createNumbersCollection } from '../helpers/insert-data'; @@ -39,7 +44,12 @@ describe('Time to first query', function () { await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', '{ i: 42 }'); @@ -59,7 +69,12 @@ describe('Time to first query', function () { await browser.connectWithConnectionString(); - await browser.navigateToCollectionTab('test', 'numbers', 'Documents'); + await browser.navigateToCollectionTab( + DEFAULT_CONNECTION_NAME, + 'test', + 'numbers', + 'Documents' + ); await browser.runFindOperation('Documents', '{ i: 42 }'); diff --git a/packages/compass-editor/package.json b/packages/compass-editor/package.json index bab61d8d06d..6353bd93d4f 100644 --- a/packages/compass-editor/package.json +++ b/packages/compass-editor/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.25.0", + "version": "0.27.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -46,7 +46,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -72,8 +72,9 @@ "@codemirror/state": "^6.1.4", "@codemirror/view": "^6.7.1", "@lezer/highlight": "^1.1.3", - "@mongodb-js/compass-components": "^1.26.0", + "@mongodb-js/compass-components": "^1.28.0", "@mongodb-js/mongodb-constants": "^0.10.0", + "mongodb-query-parser": "^4.2.0", "polished": "^4.2.2", "prettier": "^2.7.1", "react": "^17.0.2" diff --git a/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts new file mode 100644 index 00000000000..47b2d0dda73 --- /dev/null +++ b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts @@ -0,0 +1,90 @@ +import { expect } from 'chai'; +import { createQueryWithHistoryAutocompleter } from './query-autocompleter-with-history'; +import { setupCodemirrorCompleter } from '../../test/completer'; +import type { SavedQuery } from '../../dist/codemirror/query-history-autocompleter'; + +describe('query history autocompleter', function () { + const { getCompletions, cleanup } = setupCodemirrorCompleter( + createQueryWithHistoryAutocompleter + ); + + const savedQueries: SavedQuery[] = [ + { + lastExecuted: new Date('2023-06-01T12:00:00Z'), + queryProperties: { + filter: { status: 'active' }, + }, + }, + { + lastExecuted: new Date('2023-06-02T14:00:00Z'), + queryProperties: { + filter: { age: { $gt: 30 } }, + project: { name: 1, age: 1, address: 1 }, + collation: { locale: 'en' }, + sort: { age: 1 }, + skip: 5, + limit: 100, + maxTimeMS: 3000, + }, + }, + { + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: { + filter: { score: { $gte: 85 } }, + project: { studentName: 1, score: 1 }, + sort: { score: -1 }, + hint: { indexName: 'score_1' }, + limit: 20, + maxTimeMS: 1000, + }, + }, + { + lastExecuted: new Date('2023-06-04T18:00:00Z'), + queryProperties: { + filter: { isActive: true }, + project: { userId: 1, isActive: 1 }, + collation: { locale: 'simple' }, + sort: { userId: 1 }, + limit: 10, + maxTimeMS: 500, + }, + }, + { + lastExecuted: new Date('2023-06-05T20:00:00Z'), + queryProperties: { + filter: { category: 'electronics' }, + project: { productId: 1, category: 1, price: 1 }, + sort: { price: -1 }, + limit: 30, + maxTimeMS: 1500, + }, + }, + ]; + + after(cleanup); + + const mockOnApply: (query: SavedQuery['queryProperties']) => any = () => {}; + + it('returns all saved queries as completions on click', function () { + expect( + getCompletions('{}', savedQueries, undefined, mockOnApply) + ).to.have.lengthOf(5); + }); + + it('returns normal autocompletion when user starts typing', function () { + expect( + getCompletions('foo', savedQueries, undefined, mockOnApply) + ).to.have.lengthOf(45); + }); + + it('completes "any text" when inside a string', function () { + expect( + getCompletions( + '{ bar: 1, buz: 2, foo: "b', + savedQueries, + undefined, + mockOnApply + ).map((completion) => completion.label) + ).to.deep.eq(['bar', '1', 'buz', '2', 'foo']); + }); +}); diff --git a/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts new file mode 100644 index 00000000000..cdfa2009e77 --- /dev/null +++ b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts @@ -0,0 +1,30 @@ +import { + type SavedQuery, + createQueryHistoryAutocompleter, +} from './query-history-autocompleter'; +import { createQueryAutocompleter } from './query-autocompleter'; + +import type { + CompletionSource, + CompletionContext, +} from '@codemirror/autocomplete'; +import type { CompletionOptions } from '../autocompleter'; + +export const createQueryWithHistoryAutocompleter = ( + recentQueries: SavedQuery[], + options: Pick = {}, + onApply: (query: SavedQuery['queryProperties']) => void +): CompletionSource => { + const queryHistoryAutocompleter = createQueryHistoryAutocompleter( + recentQueries, + onApply + ); + + const originalQueryAutocompleter = createQueryAutocompleter(options); + + return function fullCompletions(context: CompletionContext) { + if (context.state.doc.toString() !== '{}') + return originalQueryAutocompleter(context); + return queryHistoryAutocompleter(context); + }; +}; diff --git a/packages/compass-editor/src/codemirror/query-history-autocompleter.ts b/packages/compass-editor/src/codemirror/query-history-autocompleter.ts new file mode 100644 index 00000000000..3a7e5dee48c --- /dev/null +++ b/packages/compass-editor/src/codemirror/query-history-autocompleter.ts @@ -0,0 +1,94 @@ +import type { + CompletionContext, + CompletionSource, +} from '@codemirror/autocomplete'; +import { formatDate, spacing } from '@mongodb-js/compass-components'; +import { toJSString } from 'mongodb-query-parser'; +import { css } from '@mongodb-js/compass-components'; + +export type SavedQuery = { + lastExecuted: Date; + queryProperties: { + [properyName: string]: any; + }; +}; + +export const createQueryHistoryAutocompleter = ( + savedQueries: SavedQuery[], + onApply: (query: SavedQuery['queryProperties']) => void +): CompletionSource => { + return function queryCompletions(context: CompletionContext) { + if (savedQueries.length === 0) { + return null; + } + + const options = savedQueries.map((query) => ({ + label: createQuery(query), + type: 'text', + detail: formatDate(query.lastExecuted.getTime()), + info: () => createInfo(query).dom, + apply: () => { + onApply(query.queryProperties); + }, + boost: query.lastExecuted.getTime(), + })); + + return { + from: context.pos, + options: options, + }; + }; +}; + +const queryLabelStyles = css({ + textTransform: 'capitalize', + fontWeight: 'bold', + margin: `${spacing[2]}px 0`, +}); + +const queryCodeStyles = css({ + maxHeight: '30vh', +}); + +function createQuery(query: SavedQuery): string { + let res = ''; + Object.entries(query.queryProperties).forEach(([key, value]) => { + const formattedQuery = toJSString(value); + const noFilterKey = key === 'filter' ? '' : `${key}: `; + res += formattedQuery ? `, ${noFilterKey}${formattedQuery}` : ''; + }); + const len = res.length; + return len <= 100 ? res.slice(2, res.length) : res.slice(2, 100); +} + +function createInfo(query: SavedQuery): { + dom: Node; + destroy?: () => void; +} { + const container = document.createElement('div'); + Object.entries(query.queryProperties).forEach(([key, value]) => { + const formattedQuery = toJSString(value); + const codeDiv = document.createElement('div'); + + const label = document.createElement('label'); + label.className = queryLabelStyles; + label.textContent = key; + + const code = document.createElement('pre'); + code.className = queryCodeStyles; + if (formattedQuery) code.textContent = formattedQuery; + + codeDiv.append(label); + codeDiv.appendChild(code); + container.appendChild(codeDiv); + }); + + return { + dom: container, + destroy: () => { + while (container.firstChild) { + container.removeChild(container.firstChild); + } + }, + }; +} diff --git a/packages/compass-editor/src/editor.tsx b/packages/compass-editor/src/editor.tsx index 7946456e132..9bc368effd6 100644 --- a/packages/compass-editor/src/editor.tsx +++ b/packages/compass-editor/src/editor.tsx @@ -47,6 +47,7 @@ import { closeBrackets, closeBracketsKeymap, snippetCompletion, + startCompletion, } from '@codemirror/autocomplete'; import type { IconGlyph } from '@mongodb-js/compass-components'; import { @@ -344,6 +345,7 @@ function getStylesForTheme(theme: CodemirrorThemeType) { }, '& .cm-tooltip .completion-info p': { margin: 0, + marginRight: `${spacing[2]}px`, marginTop: `${spacing[2]}px`, marginBottom: `${spacing[2]}px`, }, @@ -604,6 +606,7 @@ export type EditorRef = { prettify: () => boolean; applySnippet: (template: string) => boolean; focus: () => boolean; + startCompletion: () => boolean; readonly editorContents: string | null; readonly editor: EditorView | null; }; @@ -713,6 +716,12 @@ const BaseEditor = React.forwardRef(function BaseEditor( editorViewRef.current.focus(); return true; }, + startCompletion() { + if (!editorViewRef.current) { + return false; + } + return startCompletion(editorViewRef.current); + }, get editorContents() { if (!editorViewRef.current) { return null; @@ -1353,6 +1362,9 @@ const MultilineEditor = React.forwardRef( applySnippet(template: string) { return editorRef.current?.applySnippet(template) ?? false; }, + startCompletion() { + return editorRef.current?.startCompletion() ?? false; + }, get editorContents() { return editorRef.current?.editorContents ?? null; }, diff --git a/packages/compass-editor/src/index.ts b/packages/compass-editor/src/index.ts index e06ec89ab65..70024a73d80 100644 --- a/packages/compass-editor/src/index.ts +++ b/packages/compass-editor/src/index.ts @@ -21,3 +21,5 @@ export { createQueryAutocompleter } from './codemirror/query-autocompleter'; export { createStageAutocompleter } from './codemirror/stage-autocompleter'; export { createAggregationAutocompleter } from './codemirror/aggregation-autocompleter'; export { createSearchIndexAutocompleter } from './codemirror/search-index-autocompleter'; +export { createQueryHistoryAutocompleter } from './codemirror/query-history-autocompleter'; +export { createQueryWithHistoryAutocompleter } from './codemirror/query-autocompleter-with-history'; diff --git a/packages/compass-explain-plan/package.json b/packages/compass-explain-plan/package.json index 7cd901b3e10..d924198efdd 100644 --- a/packages/compass-explain-plan/package.json +++ b/packages/compass-explain-plan/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "6.33.0", + "version": "6.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,7 +48,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -58,7 +58,7 @@ "@types/d3-hierarchy": "^3.1.2", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -69,18 +69,18 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/explain-plan-helper": "^1.1.13", - "compass-preferences-model": "^2.23.1", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/explain-plan-helper": "^1.1.14", + "compass-preferences-model": "^2.25.0", "d3": "^3.5.17", "d3-flextree": "^2.1.2", "d3-hierarchy": "^3.1.2", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", "react": "^17.0.2", diff --git a/packages/compass-explain-plan/src/index.ts b/packages/compass-explain-plan/src/index.ts index 7158cf5d091..bc74861baaa 100644 --- a/packages/compass-explain-plan/src/index.ts +++ b/packages/compass-explain-plan/src/index.ts @@ -2,11 +2,12 @@ import ExplainPlanModal from './components/explain-plan-modal'; import { activatePlugin } from './stores'; import { registerHadronPlugin } from 'hadron-app-registry'; import { + connectionInfoAccessLocator, dataServiceLocator, type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; const ExplainPlanModalPlugin = registerHadronPlugin( @@ -17,7 +18,8 @@ const ExplainPlanModalPlugin = registerHadronPlugin( }, { logger: createLoggerLocator('EXPLAIN-PLAN-MODAL-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, + connectionInfoAccess: connectionInfoAccessLocator, dataService: dataServiceLocator as DataServiceLocator< 'explainAggregate' | 'explainFind' | 'isCancelError' >, diff --git a/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts b/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts index 64b80b3d94f..1d6d61aec3e 100644 --- a/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts +++ b/packages/compass-explain-plan/src/stores/explain-plan-modal-store.spec.ts @@ -8,6 +8,7 @@ import { activatePlugin } from './'; import { expect } from 'chai'; import type { Document } from 'mongodb'; import Sinon from 'sinon'; +import type { ConnectionInfo } from '../../../connection-info/dist'; const localAppRegistry = new AppRegistry(); @@ -80,6 +81,12 @@ describe('explain plan modal store', function () { mongoLogId() {}, } as any, track: () => {}, + connectionInfoAccess: { + getCurrentConnectionInfo: () => + ({ + id: 'TEST', + } as ConnectionInfo), + }, preferences: { getPreferences() { return { maxTimeMS: 0 }; diff --git a/packages/compass-explain-plan/src/stores/explain-plan-modal-store.ts b/packages/compass-explain-plan/src/stores/explain-plan-modal-store.ts index 72d826860d1..6a6b4d15a08 100644 --- a/packages/compass-explain-plan/src/stores/explain-plan-modal-store.ts +++ b/packages/compass-explain-plan/src/stores/explain-plan-modal-store.ts @@ -176,10 +176,18 @@ export const openExplainPlanModal = ( return async ( dispatch, getState, - { dataService, preferences, track, logger: { log, mongoLogId } } + { + dataService, + preferences, + track, + connectionInfoAccess, + logger: { log, mongoLogId }, + } ) => { const { id: fetchId, signal } = getAbortSignal(); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + let rawExplainPlan = null; let explainPlan = null; @@ -233,10 +241,14 @@ export const openExplainPlanModal = ( throw err; } - track('Aggregation Explained', { - num_stages: pipeline.length, - index_used: explainPlan.usedIndexes.length > 0, - }); + track( + 'Aggregation Explained', + { + num_stages: pipeline.length, + index_used: explainPlan.usedIndexes.length > 0, + }, + connectionInfo + ); } if (event.query) { @@ -273,10 +285,14 @@ export const openExplainPlanModal = ( throw err; } - track('Explain Plan Executed', { - with_filter: Object.entries(filter).length > 0, - index_used: explainPlan.usedIndexes.length > 0, - }); + track( + 'Explain Plan Executed', + { + with_filter: Object.entries(filter).length > 0, + index_used: explainPlan.usedIndexes.length > 0, + }, + connectionInfo + ); } dispatch({ diff --git a/packages/compass-explain-plan/src/stores/index.ts b/packages/compass-explain-plan/src/stores/index.ts index 5cc97689afc..b015ebf5b01 100644 --- a/packages/compass-explain-plan/src/stores/index.ts +++ b/packages/compass-explain-plan/src/stores/index.ts @@ -9,7 +9,10 @@ import { import type { AggregateOptions, Document, FindOptions } from 'mongodb'; import type AppRegistry from 'hadron-app-registry'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; -import type { DataService } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionInfoAccess, + DataService, +} from '@mongodb-js/compass-connections/provider'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { PreferencesAccess } from 'compass-preferences-model/provider'; @@ -44,6 +47,7 @@ export type ExplainPlanModalServices = { >; logger: Logger; track: TrackFunction; + connectionInfoAccess: ConnectionInfoAccess; preferences: PreferencesAccess; localAppRegistry: AppRegistry; }; diff --git a/packages/compass-export-to-language/package.json b/packages/compass-export-to-language/package.json index e02695d03a3..75a405d1c1f 100644 --- a/packages/compass-export-to-language/package.json +++ b/packages/compass-export-to-language/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "9.9.0", + "version": "9.12.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,27 +48,27 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "bson-transpilers": "^3.0.4", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/shell-bson-parser": "^1.1.0", + "bson-transpilers": "^3.0.5", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/compass-logging": "^1.4.1", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", "chai": "^4.3.6", diff --git a/packages/compass-export-to-language/src/components/modal.tsx b/packages/compass-export-to-language/src/components/modal.tsx index 736b7b96f9d..04ca4fb9e3c 100644 --- a/packages/compass-export-to-language/src/components/modal.tsx +++ b/packages/compass-export-to-language/src/components/modal.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { connect } from 'react-redux'; import { InfoModal, @@ -23,6 +23,7 @@ import { countAggregationStagesInString } from '../modules/count-aggregation-sta import { usePreference } from 'compass-preferences-model/provider'; import { prettify } from '@mongodb-js/compass-editor'; import { closeModal } from '../stores'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; type LanguageOption = { displayName: string; @@ -100,6 +101,7 @@ const ExportToLanguageModal: React.FunctionComponent< } > = ({ modalOpen, onModalClose, inputExpression, uri, namespace }) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const [outputLanguage, setOutputLanguage] = useState('python'); const [includeImports, setIncludeImports] = useState(false); @@ -154,16 +156,21 @@ const ExportToLanguageModal: React.FunctionComponent< : 'Aggregation Export Opened'; if (modalOpen && !wasOpen) { - track(trackingEvent, { - ...stageCountForTelemetry(inputExpression), - }); - track('Screen', { name: 'export_to_language_modal' }); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + track( + trackingEvent, + { + ...stageCountForTelemetry(inputExpression), + }, + connectionInfo + ); + track('Screen', { name: 'export_to_language_modal' }, connectionInfo); } setWasOpen(modalOpen); - }, [modalOpen, wasOpen, mode, inputExpression, track]); + }, [modalOpen, wasOpen, mode, inputExpression, track, connectionInfoAccess]); - function trackCopiedOutput() { + const trackCopiedOutput = useCallback(() => { const trackingEvent = mode === 'Update Query' ? 'Update Exported' @@ -173,14 +180,27 @@ const ExportToLanguageModal: React.FunctionComponent< ? 'Query Exported' : 'Aggregation Exported'; - track(trackingEvent, { - language: outputLanguage, - with_import_statements: includeImports, - with_drivers_syntax: includeDrivers, - with_builders: useBuilders, - ...stageCountForTelemetry(inputExpression), - }); - } + track( + trackingEvent, + { + language: outputLanguage, + with_import_statements: includeImports, + with_drivers_syntax: includeDrivers, + with_builders: useBuilders, + ...stageCountForTelemetry(inputExpression), + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); + }, [ + track, + connectionInfoAccess, + outputLanguage, + includeImports, + includeDrivers, + useBuilders, + inputExpression, + mode, + ]); const prettyInput = useMemo(() => { return prettify(input, 'javascript-expression'); diff --git a/packages/compass-export-to-language/src/index.spec.tsx b/packages/compass-export-to-language/src/index.spec.tsx index b457422fb81..9819476fb8d 100644 --- a/packages/compass-export-to-language/src/index.spec.tsx +++ b/packages/compass-export-to-language/src/index.spec.tsx @@ -167,6 +167,7 @@ result = client['db']['coll'].find( with_drivers_syntax: false, with_builders: false, num_stages: 0, + connection_id: 'TEST', }); }); }); diff --git a/packages/compass-export-to-language/src/modules/count-aggregation-stages-in-string.ts b/packages/compass-export-to-language/src/modules/count-aggregation-stages-in-string.ts index 19608536ad3..c5caf6f46ba 100644 --- a/packages/compass-export-to-language/src/modules/count-aggregation-stages-in-string.ts +++ b/packages/compass-export-to-language/src/modules/count-aggregation-stages-in-string.ts @@ -1,4 +1,4 @@ -import parseShellBSON, { ParseMode } from 'ejson-shell-parser'; +import parseShellBSON, { ParseMode } from '@mongodb-js/shell-bson-parser'; export function countAggregationStagesInString(source: string): number { const parsed = parseShellBSON(source, { mode: ParseMode.Loose }); diff --git a/packages/compass-field-store/package.json b/packages/compass-field-store/package.json index 1bb65c3b535..02355d0c217 100644 --- a/packages/compass-field-store/package.json +++ b/packages/compass-field-store/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "9.8.0", + "version": "9.11.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,7 +49,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -70,8 +70,8 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-connections": "^1.33.0", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-connections": "^1.36.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb-schema": "^12.2.0", "react": "^17.0.2", diff --git a/packages/compass-find-in-page/package.json b/packages/compass-find-in-page/package.json index deab3aed90f..28ce1bef533 100644 --- a/packages/compass-find-in-page/package.json +++ b/packages/compass-find-in-page/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "4.26.0", + "version": "4.29.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,7 +48,7 @@ }, "license": "SSPL", "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -62,7 +62,7 @@ "@types/sinon-chai": "^3.2.5", "chai": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -74,9 +74,9 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "@mongodb-js/compass-components": "^1.28.0", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "react": "^17.0.2", "react-redux": "^8.1.3", "redux": "^4.2.1", diff --git a/packages/compass-generative-ai/package.json b/packages/compass-generative-ai/package.json index a06dcf9a30d..e99802c6eb4 100644 --- a/packages/compass-generative-ai/package.json +++ b/packages/compass-generative-ai/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.16.0", + "version": "0.19.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -53,19 +53,19 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-intercom": "^0.7.1", - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-intercom": "^0.9.0", + "@mongodb-js/compass-logging": "^1.4.1", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "mongodb": "^6.7.0", "mongodb-schema": "^12.2.0", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -83,7 +83,7 @@ "decomment": "^0.9.5", "depcheck": "^1.4.1", "digest-fetch": "^2.0.3", - "ejson-shell-parser": "^2.0.1", + "@mongodb-js/shell-bson-parser": "^1.1.0", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", diff --git a/packages/compass-generative-ai/scripts/ai-accuracy-tests/ai-accuracy-tests.ts b/packages/compass-generative-ai/scripts/ai-accuracy-tests/ai-accuracy-tests.ts index 1ce41a8944c..5d35ffe7ecc 100644 --- a/packages/compass-generative-ai/scripts/ai-accuracy-tests/ai-accuracy-tests.ts +++ b/packages/compass-generative-ai/scripts/ai-accuracy-tests/ai-accuracy-tests.ts @@ -18,7 +18,7 @@ import { MongoCluster } from 'mongodb-runner'; import os from 'os'; import assert from 'assert'; -import ejsonShellParser from 'ejson-shell-parser'; +import ejsonShellParser from '@mongodb-js/shell-bson-parser'; import { MongoClient } from 'mongodb'; import { EJSON } from 'bson'; import type { Document } from 'bson'; diff --git a/packages/compass-import-export/package.json b/packages/compass-import-export/package.json index 7662dc9e696..64d1d29ede5 100644 --- a/packages/compass-import-export/package.json +++ b/packages/compass-import-export/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "7.32.0", + "version": "7.35.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,25 +49,25 @@ }, "dependencies": { "@electron/remote": "^2.1.2", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-workspaces": "^0.14.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-workspaces": "^0.17.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "debug": "^4.3.4", - "electron": "^29.4.3", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", - "hadron-ipc": "^3.2.16", + "electron": "^29.4.5", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", + "hadron-ipc": "^3.2.18", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "mongodb-schema": "^12.2.0", "papaparse": "^5.3.2", "react": "^17.0.2", @@ -78,8 +78,8 @@ "strip-bom-stream": "^4.0.0" }, "devDependencies": { - "@mongodb-js/compass-test-server": "^0.1.17", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/compass-test-server": "^0.1.18", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-import-export/src/components/export-modal.spec.tsx b/packages/compass-import-export/src/components/export-modal.spec.tsx index 7f71b556ff6..e68b052fa2a 100644 --- a/packages/compass-import-export/src/components/export-modal.spec.tsx +++ b/packages/compass-import-export/src/components/export-modal.spec.tsx @@ -9,6 +9,7 @@ import { closeExport, openExport } from '../modules/export'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; +import { type ConnectionRepository } from '@mongodb-js/compass-connections/provider'; function renderModal(exportState: any = {}) { // TODO: mutating state directly doesn't guarantee that we are testing the @@ -20,6 +21,9 @@ function renderModal(exportState: any = {}) { globalAppRegistry: {}, logger: createNoopLogger(), track: createNoopTrack(), + connectionRepository: { + getConnectionInfoById: () => ({ id: 'TEST' }), + } as unknown as ConnectionRepository, } as any); const state = store.getState(); state.export = { diff --git a/packages/compass-import-export/src/index.ts b/packages/compass-import-export/src/index.ts index 88022bfc490..411aa09e62a 100644 --- a/packages/compass-import-export/src/index.ts +++ b/packages/compass-import-export/src/index.ts @@ -7,7 +7,8 @@ import { activatePlugin as activateExportPlugin } from './stores/export-store'; import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { connectionRepositoryAccessLocator } from '@mongodb-js/compass-connections/provider'; /** * The import plugin. @@ -20,10 +21,11 @@ export const ImportPlugin = registerHadronPlugin( }, { connectionsManager: connectionsManagerLocator, + connectionRepository: connectionRepositoryAccessLocator, workspaces: workspacesServiceLocator, preferences: preferencesLocator, logger: createLoggerLocator('COMPASS-IMPORT-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, } ); @@ -38,8 +40,9 @@ export const ExportPlugin = registerHadronPlugin( }, { connectionsManager: connectionsManagerLocator, + connectionRepository: connectionRepositoryAccessLocator, preferences: preferencesLocator, logger: createLoggerLocator('COMPASS-EXPORT-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, } ); diff --git a/packages/compass-import-export/src/modules/export.spec.ts b/packages/compass-import-export/src/modules/export.spec.ts index 4ab0377f4dd..7a863021e10 100644 --- a/packages/compass-import-export/src/modules/export.spec.ts +++ b/packages/compass-import-export/src/modules/export.spec.ts @@ -26,7 +26,10 @@ import { import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; -import { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import { + ConnectionsManager, + type ConnectionRepository, +} from '@mongodb-js/compass-connections/provider'; import { type PreferencesAccess } from 'compass-preferences-model/provider'; const logger = createNoopLogger(); @@ -38,11 +41,15 @@ const dataService = { const connectionsManager = new ConnectionsManager({ logger: logger.log.unbound, }); +const connectionRepository = { + getConnectionInfoById: () => ({ id: 'TEST' }), +} as unknown as ConnectionRepository; const mockServices: ExportPluginServices = { connectionsManager, globalAppRegistry: new AppRegistry(), logger: createNoopLogger(), track: createNoopTrack(), + connectionRepository, preferences: {} as PreferencesAccess, }; @@ -346,6 +353,7 @@ describe('export [module]', function () { logger, track, connectionsManager, + connectionRepository, }); }); diff --git a/packages/compass-import-export/src/modules/export.ts b/packages/compass-import-export/src/modules/export.ts index 96ee1b4e2dd..bb3552bf609 100644 --- a/packages/compass-import-export/src/modules/export.ts +++ b/packages/compass-import-export/src/modules/export.ts @@ -133,11 +133,15 @@ type OpenExportAction = { export const openExport = ( exportOptions: Omit ): ExportThunkAction => { - return (dispatch, _getState, { track }) => { - track('Export Opened', { - type: exportOptions.aggregation ? 'aggregation' : 'query', - origin: exportOptions.origin, - }); + return (dispatch, _getState, { track, connectionRepository }) => { + track( + 'Export Opened', + { + type: exportOptions.aggregation ? 'aggregation' : 'query', + origin: exportOptions.origin, + }, + connectionRepository.getConnectionInfoById(exportOptions.connectionId) + ); dispatch({ type: ExportActionTypes.OpenExport, ...exportOptions, @@ -149,6 +153,20 @@ type CloseExportAction = { type: ExportActionTypes.CloseExport; }; +export const connectionDisconnected = ( + connectionId: string +): ExportThunkAction => { + return (dispatch, getState, { logger: { debug } }) => { + const currentConnectionId = getState().export.connectionId; + debug('connectionDisconnected', { connectionId, currentConnectionId }); + if (connectionId === currentConnectionId) { + // unlike cancelExport() close also cancels fieldsToExportAbortController + // and it hides the modal + dispatch(closeExport()); + } + }; +}; + export const closeExport = (): CloseExportAction => ({ type: ExportActionTypes.CloseExport, }); @@ -350,7 +368,13 @@ export const runExport = ({ return async ( dispatch, getState, - { connectionsManager, preferences, track, logger: { log, mongoLogId } } + { + connectionsManager, + connectionRepository, + preferences, + track, + logger: { log, mongoLogId }, + } ) => { let outputWriteStream: fs.WriteStream; try { @@ -515,36 +539,42 @@ export const runExport = ({ const aborted = !!( exportAbortController.signal.aborted || exportResult?.aborted ); - track('Export Completed', { - type: aggregation ? 'aggregation' : 'query', - all_docs: exportFullCollection, - has_projection: - exportFullCollection || aggregation || !_query - ? undefined - : queryHasProjection(_query), - field_option: - exportFullCollection || - aggregation || - (_query && queryHasProjection(_query)) - ? undefined - : selectedFieldOption, - file_type: fileType, - json_format: fileType === 'json' ? jsonFormatVariant : undefined, - field_count: - selectedFieldOption === 'select-fields' - ? fieldsIncludedCount - : undefined, - fields_added_count: - selectedFieldOption === 'select-fields' ? fieldsAddedCount : undefined, - fields_not_selected_count: - selectedFieldOption === 'select-fields' - ? fieldsExcludedCount - : undefined, - number_of_docs: exportResult?.docsWritten, - success: exportSucceeded, - stopped: aborted, - duration: Date.now() - startTime, - }); + track( + 'Export Completed', + { + type: aggregation ? 'aggregation' : 'query', + all_docs: exportFullCollection, + has_projection: + exportFullCollection || aggregation || !_query + ? undefined + : queryHasProjection(_query), + field_option: + exportFullCollection || + aggregation || + (_query && queryHasProjection(_query)) + ? undefined + : selectedFieldOption, + file_type: fileType, + json_format: fileType === 'json' ? jsonFormatVariant : undefined, + field_count: + selectedFieldOption === 'select-fields' + ? fieldsIncludedCount + : undefined, + fields_added_count: + selectedFieldOption === 'select-fields' + ? fieldsAddedCount + : undefined, + fields_not_selected_count: + selectedFieldOption === 'select-fields' + ? fieldsExcludedCount + : undefined, + number_of_docs: exportResult?.docsWritten, + success: exportSucceeded, + stopped: aborted, + duration: Date.now() - startTime, + }, + connectionRepository.getConnectionInfoById(connectionId) + ); if (!exportSucceeded) { return; diff --git a/packages/compass-import-export/src/modules/import.spec.ts b/packages/compass-import-export/src/modules/import.spec.ts index 59790283fe2..9b673f833f6 100644 --- a/packages/compass-import-export/src/modules/import.spec.ts +++ b/packages/compass-import-export/src/modules/import.spec.ts @@ -6,7 +6,10 @@ import { configureStore, } from '../stores/import-store'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; -import { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import { + type ConnectionRepository, + ConnectionsManager, +} from '@mongodb-js/compass-connections/provider'; import { AppRegistry } from 'hadron-app-registry'; import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; @@ -20,6 +23,9 @@ const mockServices = { track, connectionsManager: new ConnectionsManager({ logger: logger.log.unbound }), workspaces: {} as WorkspacesService, + connectionRepository: { + getConnectionInfoById: () => ({ id: 'TEST' }), + } as unknown as ConnectionRepository, } as ImportPluginServices; describe('import [module]', function () { diff --git a/packages/compass-import-export/src/modules/import.ts b/packages/compass-import-export/src/modules/import.ts index 8d3e140f32a..fffbe59e22d 100644 --- a/packages/compass-import-export/src/modules/import.ts +++ b/packages/compass-import-export/src/modules/import.ts @@ -191,6 +191,7 @@ export const startImport = (): ImportThunkAction> => { getState, { connectionsManager, + connectionRepository, globalAppRegistry: appRegistry, workspaces, track, @@ -351,18 +352,22 @@ export const startImport = (): ImportThunkAction> => { progressCallback.flush(); } catch (err: any) { - track('Import Completed', { - duration: Date.now() - startTime, - delimiter: fileType === 'csv' ? delimiter ?? ',' : undefined, - newline: fileType === 'csv' ? newline : undefined, - file_type: fileType, - all_fields: exclude.length === 0, - stop_on_error_selected: stopOnErrors, - number_of_docs: err.result.docsWritten, - success: !err, - aborted: abortSignal.aborted, - ignore_empty_strings: fileType === 'csv' ? ignoreBlanks : undefined, - }); + track( + 'Import Completed', + { + duration: Date.now() - startTime, + delimiter: fileType === 'csv' ? delimiter ?? ',' : undefined, + newline: fileType === 'csv' ? newline : undefined, + file_type: fileType, + all_fields: exclude.length === 0, + stop_on_error_selected: stopOnErrors, + number_of_docs: err.result.docsWritten, + success: !err, + aborted: abortSignal.aborted, + ignore_empty_strings: fileType === 'csv' ? ignoreBlanks : undefined, + }, + connectionRepository.getConnectionInfoById(connectionId) + ); log.error(mongoLogId(1001000081), 'Import', 'Import failed', { ns, @@ -381,18 +386,22 @@ export const startImport = (): ImportThunkAction> => { errorLogWriteStream?.close(); } - track('Import Completed', { - duration: Date.now() - startTime, - delimiter: fileType === 'csv' ? delimiter ?? ',' : undefined, - newline: fileType === 'csv' ? newline : undefined, - file_type: fileType, - all_fields: exclude.length === 0, - stop_on_error_selected: stopOnErrors, - number_of_docs: result.docsWritten, - success: true, - aborted: result.aborted, - ignore_empty_strings: fileType === 'csv' ? ignoreBlanks : undefined, - }); + track( + 'Import Completed', + { + duration: Date.now() - startTime, + delimiter: fileType === 'csv' ? delimiter ?? ',' : undefined, + newline: fileType === 'csv' ? newline : undefined, + file_type: fileType, + all_fields: exclude.length === 0, + stop_on_error_selected: stopOnErrors, + number_of_docs: result.docsWritten, + success: true, + aborted: result.aborted, + ignore_empty_strings: fileType === 'csv' ? ignoreBlanks : undefined, + }, + connectionRepository.getConnectionInfoById(connectionId) + ); log.info(mongoLogId(1001000082), 'Import', 'Import completed', { ns, @@ -403,9 +412,13 @@ export const startImport = (): ImportThunkAction> => { const openErrorLogFilePathActionHandler = errorLogFilePath ? () => { if (errorLogFilePath) { - track('Import Error Log Opened', { - errorCount: errors.length, - }); + track( + 'Import Error Log Opened', + { + errorCount: errors.length, + }, + connectionRepository.getConnectionInfoById(connectionId) + ); void openFile(errorLogFilePath); } } @@ -476,6 +489,18 @@ export const startImport = (): ImportThunkAction> => { }; }; +export const connectionDisconnected = ( + connectionId: string +): ImportThunkAction => { + return (dispatch, getState, { logger: { debug } }) => { + const currentConnectionId = getState().import.connectionId; + debug('connectionDisconnected', { connectionId, currentConnectionId }); + if (connectionId === currentConnectionId) { + dispatch(cancelImport()); + } + }; +}; + /** * Cancels an active import if there is one, noop if not. * @@ -855,7 +880,7 @@ export const openImport = ({ namespace: string; origin: 'menu' | 'crud-toolbar' | 'empty-state'; }): ImportThunkAction => { - return (dispatch, getState, { track }) => { + return (dispatch, getState, { track, connectionRepository }) => { const { status } = getState().import; if (status === 'STARTED') { dispatch({ @@ -863,9 +888,13 @@ export const openImport = ({ }); return; } - track('Import Opened', { - origin, - }); + track( + 'Import Opened', + { + origin, + }, + connectionRepository.getConnectionInfoById(connectionId) + ); dispatch({ type: OPEN, namespace, connectionId }); }; }; diff --git a/packages/compass-import-export/src/stores/export-store.spec.tsx b/packages/compass-import-export/src/stores/export-store.spec.tsx index 141d9312ccb..54d74d85cd8 100644 --- a/packages/compass-import-export/src/stores/export-store.spec.tsx +++ b/packages/compass-import-export/src/stores/export-store.spec.tsx @@ -1,7 +1,10 @@ import { createActivateHelpers } from 'hadron-app-registry'; import AppRegistry from 'hadron-app-registry'; import { activatePlugin } from './export-store'; -import { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import { + type ConnectionRepository, + ConnectionsManager, +} from '@mongodb-js/compass-connections/provider'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; import { expect } from 'chai'; @@ -13,6 +16,7 @@ describe('ExportStore [Store]', function () { let globalAppRegistry: AppRegistry; let connectionsManager: ConnectionsManager; const preferences = {} as PreferencesAccess; + const connectionId = 'TEST'; beforeEach(function () { const logger = createNoopLogger(); @@ -21,6 +25,9 @@ describe('ExportStore [Store]', function () { connectionsManager = new ConnectionsManager({ logger: logger.log.unbound, }); + const connectionRepository = { + getConnectionInfoById: () => ({ id: connectionId }), + } as unknown as ConnectionRepository; ({ store, deactivate } = activatePlugin( {}, @@ -30,6 +37,7 @@ describe('ExportStore [Store]', function () { logger, track, preferences, + connectionRepository, }, createActivateHelpers() )); @@ -52,9 +60,9 @@ describe('ExportStore [Store]', function () { globalAppRegistry.emit( 'open-export', { namespace: 'test.coll', origin: 'menu' }, - { connectionId: 'TEST' } + { connectionId } ); - expect(store.getState().export.connectionId).to.equal('TEST'); + expect(store.getState().export.connectionId).to.equal(connectionId); expect(store.getState().export.namespace).to.equal('test.coll'); }); }); diff --git a/packages/compass-import-export/src/stores/export-store.ts b/packages/compass-import-export/src/stores/export-store.ts index bc09eaeb269..015de3486d2 100644 --- a/packages/compass-import-export/src/stores/export-store.ts +++ b/packages/compass-import-export/src/stores/export-store.ts @@ -3,11 +3,20 @@ import type { Action, AnyAction } from 'redux'; import { createStore, applyMiddleware, combineReducers } from 'redux'; import type { ThunkAction } from 'redux-thunk'; import thunk from 'redux-thunk'; -import { closeExport, exportReducer, openExport } from '../modules/export'; +import { + closeExport, + exportReducer, + openExport, + connectionDisconnected, +} from '../modules/export'; import type { PreferencesAccess } from 'compass-preferences-model'; import type { Logger } from '@mongodb-js/compass-logging/provider'; +import { ConnectionsManagerEvents } from '@mongodb-js/compass-connections/provider'; import type { ActivateHelpers } from 'hadron-app-registry'; -import type { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionRepositoryAccess, + ConnectionsManager, +} from '@mongodb-js/compass-connections/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; export function configureStore(services: ExportPluginServices) { @@ -26,6 +35,7 @@ export type RootExportState = ReturnType< export type ExportPluginServices = { globalAppRegistry: AppRegistry; connectionsManager: ConnectionsManager; + connectionRepository: ConnectionRepositoryAccess; preferences: PreferencesAccess; logger: Logger; track: TrackFunction; @@ -55,6 +65,7 @@ export function activatePlugin( { globalAppRegistry, connectionsManager, + connectionRepository, preferences, logger, track, @@ -64,6 +75,7 @@ export function activatePlugin( const store = configureStore({ globalAppRegistry, connectionsManager, + connectionRepository, preferences, logger, track, @@ -104,6 +116,13 @@ export function activatePlugin( ); } ); + on( + connectionsManager, + ConnectionsManagerEvents.ConnectionDisconnected, + function (connectionId: string) { + store.dispatch(connectionDisconnected(connectionId)); + } + ); addCleanup(() => { // We use close and not cancel because cancel doesn't actually cancel diff --git a/packages/compass-import-export/src/stores/import-store.spec.tsx b/packages/compass-import-export/src/stores/import-store.spec.tsx index e1383f115f3..74e922b269d 100644 --- a/packages/compass-import-export/src/stores/import-store.spec.tsx +++ b/packages/compass-import-export/src/stores/import-store.spec.tsx @@ -1,7 +1,10 @@ import { createActivateHelpers } from 'hadron-app-registry'; import AppRegistry from 'hadron-app-registry'; import { activatePlugin } from './import-store'; -import { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import { + type ConnectionRepository, + ConnectionsManager, +} from '@mongodb-js/compass-connections/provider'; import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; @@ -13,6 +16,7 @@ describe('ImportStore [Store]', function () { let globalAppRegistry: AppRegistry; let connectionsManager: ConnectionsManager; let workspaces: WorkspacesService; + const connectionId = 'TEST'; beforeEach(function () { const logger = createNoopLogger(); @@ -21,6 +25,9 @@ describe('ImportStore [Store]', function () { connectionsManager = new ConnectionsManager({ logger: logger.log.unbound, }); + const connectionRepository = { + getConnectionInfoById: () => ({ id: connectionId }), + } as unknown as ConnectionRepository; ({ store, deactivate } = activatePlugin( {}, @@ -30,6 +37,7 @@ describe('ImportStore [Store]', function () { logger, track, workspaces, + connectionRepository, }, createActivateHelpers() )); @@ -52,9 +60,9 @@ describe('ImportStore [Store]', function () { globalAppRegistry.emit( 'open-import', { namespace: 'test.coll', origin: 'menu' }, - { connectionId: 'TEST' } + { connectionId } ); - expect(store.getState().import.connectionId).to.equal('TEST'); + expect(store.getState().import.connectionId).to.equal(connectionId); expect(store.getState().import.namespace).to.equal('test.coll'); }); }); diff --git a/packages/compass-import-export/src/stores/import-store.ts b/packages/compass-import-export/src/stores/import-store.ts index d692f362a87..da57bb92cd2 100644 --- a/packages/compass-import-export/src/stores/import-store.ts +++ b/packages/compass-import-export/src/stores/import-store.ts @@ -3,10 +3,19 @@ import type { Action, AnyAction } from 'redux'; import { createStore, applyMiddleware, combineReducers } from 'redux'; import type { ThunkAction } from 'redux-thunk'; import thunk from 'redux-thunk'; -import { cancelImport, importReducer, openImport } from '../modules/import'; +import { + cancelImport, + importReducer, + openImport, + connectionDisconnected, +} from '../modules/import'; import type { WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import type { Logger } from '@mongodb-js/compass-logging/provider'; -import type { ConnectionsManager } from '@mongodb-js/compass-connections/provider'; +import { ConnectionsManagerEvents } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionRepositoryAccess, + ConnectionsManager, +} from '@mongodb-js/compass-connections/provider'; import type { ActivateHelpers } from 'hadron-app-registry'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; @@ -16,6 +25,7 @@ export type ImportPluginServices = { logger: Logger; track: TrackFunction; connectionsManager: ConnectionsManager; + connectionRepository: ConnectionRepositoryAccess; }; export function configureStore(services: ImportPluginServices) { @@ -52,6 +62,7 @@ export function activatePlugin( { globalAppRegistry, connectionsManager, + connectionRepository, workspaces, logger, track, @@ -64,6 +75,7 @@ export function activatePlugin( logger, track, connectionsManager, + connectionRepository, }); addCleanup(() => { @@ -85,6 +97,14 @@ export function activatePlugin( } ); + on( + connectionsManager, + ConnectionsManagerEvents.ConnectionDisconnected, + function (connectionId: string) { + store.dispatch(connectionDisconnected(connectionId)); + } + ); + return { store, deactivate: cleanup, diff --git a/packages/compass-indexes/package.json b/packages/compass-indexes/package.json index af1802b1856..b68d0aba76a 100644 --- a/packages/compass-indexes/package.json +++ b/packages/compass-indexes/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "5.32.0", + "version": "5.35.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,7 +48,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -56,7 +56,7 @@ "@testing-library/user-event": "^13.5.0", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -67,25 +67,25 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", "@mongodb-js/mongodb-constants": "^0.10.0", + "@mongodb-js/shell-bson-parser": "^1.1.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-data-service": "^22.21.1", - "mongodb-query-parser": "^4.1.2", + "mongodb-data-service": "^22.22.1", + "mongodb-query-parser": "^4.2.0", "numeral": "^2.0.6", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx b/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx index c4a5e3d9133..c8af3391597 100644 --- a/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx +++ b/packages/compass-indexes/src/components/create-index-modal/create-index-modal.tsx @@ -23,6 +23,7 @@ import { useTrackOnChange, type TrackFunction, } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; type CreateIndexModalProps = React.ComponentProps & { isVisible: boolean; @@ -44,6 +45,7 @@ function CreateIndexModal({ closeCreateIndexModal, ...props }: CreateIndexModalProps) { + const connectionInfoAccess = useConnectionInfoAccess(); const onSetOpen = useCallback( (open) => { if (!open) { @@ -55,14 +57,19 @@ function CreateIndexModal({ useTrackOnChange( (track: TrackFunction) => { + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); if (isVisible) { - track('Screen', { name: 'create_index_modal' }); - track('Index Create Opened', { - atlas_search: false, - }); + track('Screen', { name: 'create_index_modal' }, connectionInfo); + track( + 'Index Create Opened', + { + atlas_search: false, + }, + connectionInfo + ); } }, - [isVisible], + [isVisible, connectionInfoAccess], undefined ); diff --git a/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx b/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx index 2ea53ae0fa5..6d95b91d965 100644 --- a/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx +++ b/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx @@ -32,7 +32,7 @@ import { createSearchIndexAutocompleter, } from '@mongodb-js/compass-editor'; import type { EditorRef } from '@mongodb-js/compass-editor'; -import _parseShellBSON, { ParseMode } from 'ejson-shell-parser'; +import _parseShellBSON, { ParseMode } from '@mongodb-js/shell-bson-parser'; import type { Document } from 'mongodb'; import { SearchIndexTemplateDropdown } from '../search-index-template-dropdown'; import { @@ -45,6 +45,7 @@ import { useTrackOnChange, type TrackFunction, } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; // Copied from packages/compass-aggregations/src/modules/pipeline-builder/pipeline-parser/utils.ts function parseShellBSON(source: string): Document[] { @@ -157,6 +158,7 @@ export const BaseSearchIndexModal: React.FunctionComponent< onClose, }) => { const editorRef = useRef(null); + const connectionInfoAccess = useConnectionInfoAccess(); const [indexName, setIndexName] = useState(initialIndexName); const [searchIndexType, setSearchIndexType] = useState( @@ -190,15 +192,20 @@ export const BaseSearchIndexModal: React.FunctionComponent< useTrackOnChange( (track: TrackFunction) => { if (isModalOpen) { - track('Screen', { name: `${mode}_search_index_modal` }); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + track('Screen', { name: `${mode}_search_index_modal` }, connectionInfo); if (mode === 'create') { - track('Index Create Opened', { - atlas_search: true, - }); + track( + 'Index Create Opened', + { + atlas_search: true, + }, + connectionInfo + ); } } }, - [isModalOpen, mode], + [isModalOpen, mode, connectionInfoAccess], undefined ); diff --git a/packages/compass-indexes/src/index.ts b/packages/compass-indexes/src/index.ts index 3b9e4420b2b..7e83527fdf4 100644 --- a/packages/compass-indexes/src/index.ts +++ b/packages/compass-indexes/src/index.ts @@ -13,6 +13,8 @@ import { } from './stores/store'; import Indexes from './components/indexes/indexes'; import { + type ConnectionInfoAccess, + connectionInfoAccessLocator, dataServiceLocator, type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; @@ -21,7 +23,7 @@ import { mongoDBInstanceLocator } from '@mongodb-js/compass-app-stores/provider' import type { Logger } from '@mongodb-js/compass-logging'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; import { - createTelemetryLocator, + telemetryLocator, type TrackFunction, } from '@mongodb-js/compass-telemetry/provider'; @@ -29,6 +31,7 @@ export const CompassIndexesHadronPlugin = registerHadronPlugin< CollectionTabPluginMetadata, { dataService: () => IndexesDataService; + connectionInfoAccess: () => ConnectionInfoAccess; instance: () => MongoDBInstance; logger: () => Logger; track: () => TrackFunction; @@ -42,9 +45,10 @@ export const CompassIndexesHadronPlugin = registerHadronPlugin< { dataService: dataServiceLocator as DataServiceLocator, + connectionInfoAccess: connectionInfoAccessLocator, instance: mongoDBInstanceLocator, logger: createLoggerLocator('COMPASS-INDEXES-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, } ); @@ -62,7 +66,8 @@ export const CreateIndexPlugin = registerHadronPlugin( { dataService: dataServiceLocator as DataServiceLocator<'createIndex'>, logger: createLoggerLocator('COMPASS-INDEXES-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, + connectionInfoAccess: connectionInfoAccessLocator, } ); @@ -75,6 +80,7 @@ export const DropIndexPlugin = registerHadronPlugin( { dataService: dataServiceLocator as DataServiceLocator<'dropIndex'>, logger: createLoggerLocator('COMPASS-INDEXES-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, + connectionInfoAccess: connectionInfoAccessLocator, } ); diff --git a/packages/compass-indexes/src/modules/create-index/index.spec.js b/packages/compass-indexes/src/modules/create-index/index.spec.js index f622271866e..0ba9bf52ef4 100644 --- a/packages/compass-indexes/src/modules/create-index/index.spec.js +++ b/packages/compass-indexes/src/modules/create-index/index.spec.js @@ -23,6 +23,7 @@ const thunkArgs = { localAppRegistry: { emit() {} }, dataService: { createIndex() {} }, track: () => {}, + connectionInfoAccess: { getCurrentConnectionInfo() {} }, }; describe('create index module', function () { diff --git a/packages/compass-indexes/src/modules/create-index/index.ts b/packages/compass-indexes/src/modules/create-index/index.ts index efb1cb615c7..41d2c4aa91b 100644 --- a/packages/compass-indexes/src/modules/create-index/index.ts +++ b/packages/compass-indexes/src/modules/create-index/index.ts @@ -106,7 +106,7 @@ export const createIndex = (): CreateIndexThunkAction> => { return async ( dispatch, getState, - { dataService, localAppRegistry, track } + { dataService, localAppRegistry, track, connectionInfoAccess } ) => { const state = getState(); const spec = {} as CreateIndexSpec; @@ -243,7 +243,11 @@ export const createIndex = (): CreateIndexThunkAction> => { try { await dataService.createIndex(ns, spec as IndexSpecification, options); - track('Index Created', trackEvent); + track( + 'Index Created', + trackEvent, + connectionInfoAccess.getCurrentConnectionInfo() + ); dispatch(resetForm()); dispatch(toggleInProgress(false)); dispatch(toggleIsVisible(false)); diff --git a/packages/compass-indexes/src/modules/index.ts b/packages/compass-indexes/src/modules/index.ts index 9f561de2523..9a3b4e549bb 100644 --- a/packages/compass-indexes/src/modules/index.ts +++ b/packages/compass-indexes/src/modules/index.ts @@ -13,6 +13,7 @@ import namespace from './namespace'; import type { ThunkAction, ThunkDispatch } from 'redux-thunk'; import type { Logger } from '@mongodb-js/compass-logging'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const reducer = combineReducers({ isWritable, @@ -34,6 +35,7 @@ export type IndexesExtraArgs = { localAppRegistry: AppRegistry; logger: Logger; track: TrackFunction; + connectionInfoAccess: ConnectionInfoAccess; }; export type IndexesThunkDispatch = ThunkDispatch< RootState, diff --git a/packages/compass-indexes/src/modules/search-indexes.ts b/packages/compass-indexes/src/modules/search-indexes.ts index f508129c702..7ded17fe313 100644 --- a/packages/compass-indexes/src/modules/search-indexes.ts +++ b/packages/compass-indexes/src/modules/search-indexes.ts @@ -387,7 +387,7 @@ export const createIndex = ({ type?: string; definition: Document; }): IndexesThunkAction> => { - return async function (dispatch, getState, { track }) { + return async function (dispatch, getState, { track, connectionInfoAccess }) { const { namespace, dataService } = getState(); dispatch({ type: ActionTypes.CreateSearchIndexStarted }); @@ -420,10 +420,14 @@ export const createIndex = ({ } dispatch({ type: ActionTypes.CreateSearchIndexSucceeded }); - track('Index Created', { - atlas_search: true, - type, - }); + track( + 'Index Created', + { + atlas_search: true, + type, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); openToast('search-index-creation-in-progress', { title: `Your index ${name} is in progress.`, @@ -445,7 +449,7 @@ export const updateIndex = ({ type?: string; definition: Document; }): IndexesThunkAction> => { - return async function (dispatch, getState, { track }) { + return async function (dispatch, getState, { track, connectionInfoAccess }) { const { namespace, dataService, @@ -464,9 +468,13 @@ export const updateIndex = ({ dispatch({ type: ActionTypes.UpdateSearchIndexStarted }); await dataService?.updateSearchIndex(namespace, name, definition); dispatch({ type: ActionTypes.UpdateSearchIndexSucceeded }); - track('Index Edited', { - atlas_search: true, - }); + track( + 'Index Edited', + { + atlas_search: true, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); openToast('search-index-update-in-progress', { title: `Your index ${name} is being updated.`, dismissible: true, @@ -563,7 +571,7 @@ export const showConfirmation = showConfirmationModal; export const dropSearchIndex = ( name: string ): IndexesThunkAction> => { - return async function (dispatch, getState, { track }) { + return async function (dispatch, getState, { track, connectionInfoAccess }) { const { namespace, dataService } = getState(); if (!dataService) { return; @@ -583,9 +591,13 @@ export const dropSearchIndex = ( try { await dataService.dropSearchIndex(namespace, name); - track('Index Dropped', { - atlas_search: true, - }); + track( + 'Index Dropped', + { + atlas_search: true, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); openToast('search-index-delete-in-progress', { title: `Your index ${name} is being deleted.`, dismissible: true, diff --git a/packages/compass-indexes/src/stores/create-index.ts b/packages/compass-indexes/src/stores/create-index.ts index ff47c711921..551a14d2d89 100644 --- a/packages/compass-indexes/src/stores/create-index.ts +++ b/packages/compass-indexes/src/stores/create-index.ts @@ -8,6 +8,7 @@ import type AppRegistry from 'hadron-app-registry'; import type { DataService } from 'mongodb-data-service'; import type { Logger } from '@mongodb-js/compass-logging'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; type CreateIndexPluginOptions = Pick< CollectionTabPluginMetadata, @@ -18,20 +19,33 @@ export type CreateIndexPluginServices = { globalAppRegistry: AppRegistry; localAppRegistry: AppRegistry; dataService: Pick; + connectionInfoAccess: ConnectionInfoAccess; logger: Logger; track: TrackFunction; }; export function activatePlugin( { namespace, serverVersion }: CreateIndexPluginOptions, - { localAppRegistry, dataService, logger, track }: CreateIndexPluginServices, + { + localAppRegistry, + dataService, + logger, + track, + connectionInfoAccess, + }: CreateIndexPluginServices, { on, cleanup }: ActivateHelpers ) { const store = createStore( reducer, { namespace, serverVersion }, applyMiddleware( - thunk.withExtraArgument({ localAppRegistry, dataService, logger, track }) + thunk.withExtraArgument({ + localAppRegistry, + dataService, + logger, + track, + connectionInfoAccess, + }) ) ); diff --git a/packages/compass-indexes/src/stores/drop-index.tsx b/packages/compass-indexes/src/stores/drop-index.tsx index 9f3ef322e24..041622e683b 100644 --- a/packages/compass-indexes/src/stores/drop-index.tsx +++ b/packages/compass-indexes/src/stores/drop-index.tsx @@ -10,24 +10,32 @@ import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection import type { DataService } from 'mongodb-data-service'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; type DropIndexInitialProps = Pick; type DropIndexServices = { localAppRegistry: AppRegistry; dataService: Pick; + connectionInfoAccess: ConnectionInfoAccess; logger: Logger; track: TrackFunction; }; export function activatePlugin( { namespace }: DropIndexInitialProps, - { localAppRegistry, dataService, track }: DropIndexServices, + { + localAppRegistry, + dataService, + track, + connectionInfoAccess, + }: DropIndexServices, { on, cleanup, signal }: ActivateHelpers ) { on(localAppRegistry, 'open-drop-index-modal', async (indexName: string) => { try { - track('Screen', { name: 'drop_index_modal' }); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + track('Screen', { name: 'drop_index_modal' }, connectionInfo); const confirmed = await showConfirmation({ variant: 'danger', title: 'Drop Index', @@ -41,7 +49,7 @@ export function activatePlugin( return; } await dataService.dropIndex(namespace, indexName); - track('Index Dropped', { atlas_search: false }); + track('Index Dropped', { atlas_search: false }, connectionInfo); localAppRegistry.emit('refresh-regular-indexes'); openToast('drop-index-success', { variant: 'success', diff --git a/packages/compass-indexes/src/stores/store.spec.ts b/packages/compass-indexes/src/stores/store.spec.ts index ea14fa48917..f7d374b3acb 100644 --- a/packages/compass-indexes/src/stores/store.spec.ts +++ b/packages/compass-indexes/src/stores/store.spec.ts @@ -6,6 +6,7 @@ import { activateIndexesPlugin, type IndexesStore } from './store'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; +import type { ConnectionInfo } from '../../../connection-info/dist'; class FakeInstance extends EventEmitter { isWritable = true; @@ -44,6 +45,9 @@ describe('IndexesStore [Store]', function () { } as unknown as IndexesDataService, logger: createNoopLogger(), track: createNoopTrack(), + connectionInfoAccess: { + getCurrentConnectionInfo: () => ({ id: 'TEST' } as ConnectionInfo), + }, }, createActivateHelpers() ); diff --git a/packages/compass-indexes/src/stores/store.ts b/packages/compass-indexes/src/stores/store.ts index 57caf7fbc19..dbf4f74b2a4 100644 --- a/packages/compass-indexes/src/stores/store.ts +++ b/packages/compass-indexes/src/stores/store.ts @@ -26,6 +26,7 @@ import type { ActivateHelpers } from 'hadron-app-registry'; import type { MongoDBInstance } from '@mongodb-js/compass-app-stores/provider'; import type { Logger } from '@mongodb-js/compass-logging'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; export type IndexesDataServiceProps = | 'indexes' @@ -41,6 +42,7 @@ export type IndexesDataService = Pick; export type IndexesPluginServices = { dataService: IndexesDataService; + connectionInfoAccess: ConnectionInfoAccess; instance: MongoDBInstance; localAppRegistry: Pick; globalAppRegistry: Pick; @@ -63,6 +65,7 @@ export function activateIndexesPlugin( options: IndexesPluginOptions, { dataService, + connectionInfoAccess, instance, localAppRegistry, globalAppRegistry, @@ -92,6 +95,7 @@ export function activateIndexesPlugin( globalAppRegistry, logger, track, + connectionInfoAccess, }) ) ); diff --git a/packages/compass-indexes/test/setup-store.ts b/packages/compass-indexes/test/setup-store.ts index da3fec1346e..fa63168e3e6 100644 --- a/packages/compass-indexes/test/setup-store.ts +++ b/packages/compass-indexes/test/setup-store.ts @@ -10,6 +10,8 @@ import { activateIndexesPlugin } from '../src/stores/store'; import { createActivateHelpers } from 'hadron-app-registry'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; +import type { ConnectionInfo } from '../../connection-info/dist'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const NOOP_DATA_PROVIDER: IndexesDataService = { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -79,6 +81,10 @@ export const setupStore = ( getStore: Sinon.spy(), } as unknown as AppRegistry; + const connectionInfoAccess: ConnectionInfoAccess = { + getCurrentConnectionInfo: () => ({ id: 'TEST' } as ConnectionInfo), + }; + return activateIndexesPlugin( { namespace: 'citibike.trips', @@ -94,6 +100,7 @@ export const setupStore = ( instance: fakeInstance as any, logger: createNoopLogger('TEST'), track: createNoopTrack(), + connectionInfoAccess, ...services, }, createActivateHelpers() diff --git a/packages/compass-intercom/package.json b/packages/compass-intercom/package.json index bdaf7611511..fae222f0699 100644 --- a/packages/compass-intercom/package.json +++ b/packages/compass-intercom/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.7.1", + "version": "0.9.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,7 +50,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -67,7 +67,7 @@ "typescript": "^5.0.4" }, "dependencies": { - "compass-preferences-model": "^2.23.1", - "@mongodb-js/compass-logging": "^1.3.1" + "compass-preferences-model": "^2.25.0", + "@mongodb-js/compass-logging": "^1.4.1" } } diff --git a/packages/compass-logging/package.json b/packages/compass-logging/package.json index 94d31874e8e..bdedf168e2f 100644 --- a/packages/compass-logging/package.json +++ b/packages/compass-logging/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.3.1", + "version": "1.4.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -52,14 +52,14 @@ }, "dependencies": { "debug": "^4.3.4", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "is-electron-renderer": "^2.0.1", "mongodb-log-writer": "^1.4.2", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-maybe-protect-connection-string/package.json b/packages/compass-maybe-protect-connection-string/package.json index 6f030735463..8e8bbc99417 100644 --- a/packages/compass-maybe-protect-connection-string/package.json +++ b/packages/compass-maybe-protect-connection-string/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.21.1", + "version": "0.23.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,11 +50,11 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "mongodb-connection-string-url": "^3.0.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-preferences-model/package.json b/packages/compass-preferences-model/package.json index af2e876701b..13d6f64719a 100644 --- a/packages/compass-preferences-model/package.json +++ b/packages/compass-preferences-model/package.json @@ -2,7 +2,7 @@ "name": "compass-preferences-model", "description": "Compass preferences model", "author": "Lucas Hrabovsky ", - "version": "2.23.1", + "version": "2.25.0", "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" @@ -49,11 +49,11 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-user-data": "^0.2.1", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-user-data": "^0.3.1", "bson": "^6.7.0", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "react": "^17.0.2", @@ -61,7 +61,7 @@ "zod": "^3.22.3" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@testing-library/react": "^12.1.5", "@types/js-yaml": "^4.0.5", diff --git a/packages/compass-preferences-model/src/feature-flags.ts b/packages/compass-preferences-model/src/feature-flags.ts index 75a6f59ce8d..235b8f9360c 100644 --- a/packages/compass-preferences-model/src/feature-flags.ts +++ b/packages/compass-preferences-model/src/feature-flags.ts @@ -19,6 +19,7 @@ export type FeatureFlags = { showInsights: boolean; enableRenameCollectionModal: boolean; enableNewMultipleConnectionSystem: boolean; + enableQueryHistoryAutocomplete: boolean; }; export const featureFlags: Required<{ @@ -73,4 +74,15 @@ export const featureFlags: Required<{ long: 'Allows users to open multiple connections in the same window.', }, }, + + /** + * Feature flag for adding query history items to the query bar autocompletion. COMPASS-8096 + */ + enableQueryHistoryAutocomplete: { + stage: 'development', + description: { + short: + 'Enables showing query history items in the query bar autocomplete.', + }, + }, }; diff --git a/packages/compass-preferences-model/src/react.ts b/packages/compass-preferences-model/src/react.ts index c83b8752daa..f44a007e60a 100644 --- a/packages/compass-preferences-model/src/react.ts +++ b/packages/compass-preferences-model/src/react.ts @@ -5,11 +5,14 @@ import { createElement, createContext, useContext, + useRef, + useCallback, } from 'react'; import { type AllPreferences } from './'; import type { PreferencesAccess } from './preferences'; import { ReadOnlyPreferenceAccess } from './read-only-preferences-access'; import { createServiceLocator } from 'hadron-app-registry'; +import { pick } from 'lodash'; const PreferencesContext = createContext( // Our context starts with our read-only preference access but we expect @@ -44,11 +47,64 @@ export function usePreference( return value; } +/** + * A version of usePreference hook that allows to get multiple preferences in a + * single object for brevity + * + * @example + * const { + * enableShell, + * readOnly, + * } = usePreferences(['enableShell', 'readOnly']); + * + * @param keys list of preferences keys to return as an object + */ +export function usePreferences( + keys: K +): Pick { + const preferences = usePreferencesContext(); + const keysRef = useRef(keys); + keysRef.current = keys; + const [values, setValues] = useState(() => { + return pick(preferences.getPreferences(), keys); + }); + const updateValue = useCallback((key: keyof AllPreferences, newValue) => { + setValues((values) => { + if (newValue === values[key]) { + return values; + } + return { + ...values, + [key]: newValue, + }; + }); + }, []); + useEffect(() => { + const unsubscribe = keysRef.current.map((key) => { + return preferences.onPreferenceValueChanged(key, (newValue) => { + updateValue(key, newValue); + }); + }); + return () => { + unsubscribe.forEach((fn) => { + fn(); + }); + }; + }, [ + // An easy way to depend on actual array values instead of the array itself + // and avoid extra effect calls if array defined inline + keysRef.current.join(''), + preferences, + ]); + return values; +} + type FirstArgument = F extends (...args: [infer A, ...any]) => any ? A : F extends { new (...args: [infer A, ...any]): any } ? A : never; + type OptionalOmit = Omit & Partial>; /** Use as: const WrappedComponent = withPreferences(Component, ['enableMaps', 'trackUsageStatistics'], React); */ diff --git a/packages/compass-query-bar/package.json b/packages/compass-query-bar/package.json index 4a880240626..7dfddd03530 100644 --- a/packages/compass-query-bar/package.json +++ b/packages/compass-query-bar/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "8.34.0", + "version": "8.37.0", "homepage": "https://github.com/mongodb-js/compass", "license": "SSPL", "bugs": { @@ -48,7 +48,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -57,7 +57,7 @@ "@testing-library/user-event": "^13.5.0", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", @@ -68,27 +68,27 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", "@mongodb-js/mongodb-constants": "^0.10.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", - "mongodb-query-util": "^2.2.3", + "mongodb-query-parser": "^4.2.0", + "mongodb-query-util": "^2.2.4", "mongodb-schema": "^12.2.0", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-query-bar/src/components/option-editor.spec.tsx b/packages/compass-query-bar/src/components/option-editor.spec.tsx index f59d8230eab..923a213bc50 100644 --- a/packages/compass-query-bar/src/components/option-editor.spec.tsx +++ b/packages/compass-query-bar/src/components/option-editor.spec.tsx @@ -3,6 +3,12 @@ import { expect } from 'chai'; import { cleanup, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { OptionEditor } from './option-editor'; +import type { SinonSpy } from 'sinon'; +import { applyFromHistory } from '../stores/query-bar-reducer'; +import sinon from 'sinon'; +import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; +import type { PreferencesAccess } from 'compass-preferences-model'; +import { PreferencesProvider } from 'compass-preferences-model/provider'; class MockPasteEvent extends window.Event { constructor(private text: string) { @@ -35,6 +41,8 @@ describe('OptionEditor', function () { insertEmptyDocOnFocus onChange={() => {}} value="" + savedQueries={[]} + onApplyQuery={applyFromHistory} > ); @@ -54,6 +62,8 @@ describe('OptionEditor', function () { insertEmptyDocOnFocus onChange={() => {}} value="{ foo: 1 }" + savedQueries={[]} + onApplyQuery={applyFromHistory} > ); @@ -73,6 +83,8 @@ describe('OptionEditor', function () { insertEmptyDocOnFocus onChange={() => {}} value="" + savedQueries={[]} + onApplyQuery={applyFromHistory} > ); @@ -98,6 +110,8 @@ describe('OptionEditor', function () { insertEmptyDocOnFocus onChange={() => {}} value="" + savedQueries={[]} + onApplyQuery={applyFromHistory} > ); @@ -125,6 +139,8 @@ describe('OptionEditor', function () { insertEmptyDocOnFocus onChange={() => {}} value="" + savedQueries={[]} + onApplyQuery={applyFromHistory} > ); @@ -140,4 +156,66 @@ describe('OptionEditor', function () { }); }); }); + + describe('when render with the query history autocompleter', function () { + let onApplySpy: SinonSpy; + let preferencesAccess: PreferencesAccess; + + beforeEach(async function () { + preferencesAccess = await createSandboxFromDefaultPreferences(); + await preferencesAccess.savePreferences({ + enableQueryHistoryAutocomplete: true, + }); + + onApplySpy = sinon.spy(); + render( + + {}} + value="" + savedQueries={[ + { + _id: '1', + _ns: '1', + filter: { a: 1 }, + _lastExecuted: new Date(), + }, + { + _id: '1', + _ns: '1', + filter: { a: 2 }, + sort: { a: -1 }, + _lastExecuted: new Date(), + }, + ]} + onApplyQuery={onApplySpy} + /> + + ); + }); + + afterEach(function () { + cleanup(); + }); + + it('filter applied correctly when autocomplete option is clicked', async function () { + userEvent.click(screen.getByRole('textbox')); + await waitFor(() => { + expect(screen.getAllByText('{ a: 1 }')[0]).to.be.visible; + expect(screen.getAllByText('{ a: 1 }')[1]).to.be.visible; + expect(screen.getByText('{ a: 2 }, sort: { a: -1 }')).to.be.visible; + }); + + // Simulate selecting the autocomplete option + userEvent.click(screen.getByText('{ a: 2 }, sort: { a: -1 }')); + await waitFor(() => { + expect(onApplySpy.lastCall).to.be.calledWithExactly({ + filter: { a: 2 }, + sort: { a: -1 }, + }); + }); + }); + }); }); diff --git a/packages/compass-query-bar/src/components/option-editor.tsx b/packages/compass-query-bar/src/components/option-editor.tsx index 2512b99f513..307595d1f92 100644 --- a/packages/compass-query-bar/src/components/option-editor.tsx +++ b/packages/compass-query-bar/src/components/option-editor.tsx @@ -13,12 +13,17 @@ import type { Command, EditorRef } from '@mongodb-js/compass-editor'; import { CodemirrorInlineEditor as InlineEditor, createQueryAutocompleter, + createQueryWithHistoryAutocompleter, } from '@mongodb-js/compass-editor'; import { connect } from '../stores/context'; import { usePreference } from 'compass-preferences-model/provider'; import { lenientlyFixQuery } from '../query/leniently-fix-query'; import type { RootState } from '../stores/query-bar-store'; import { useAutocompleteFields } from '@mongodb-js/compass-field-store'; +import type { RecentQuery } from '@mongodb-js/my-queries-storage'; +import { applyFromHistory } from '../stores/query-bar-reducer'; +import { getQueryAttributes } from '../utils'; +import type { BaseQuery } from '../constants/query-properties'; const editorContainerStyles = css({ position: 'relative', @@ -94,6 +99,8 @@ type OptionEditorProps = { ['data-testid']?: string; insights?: Signal | Signal[]; disabled?: boolean; + savedQueries: RecentQuery[]; + onApplyQuery: (query: BaseQuery) => void; }; export const OptionEditor: React.FunctionComponent = ({ @@ -110,10 +117,15 @@ export const OptionEditor: React.FunctionComponent = ({ ['data-testid']: dataTestId, insights, disabled = false, + savedQueries, + onApplyQuery, }) => { const showInsights = usePreference('showInsights'); const editorContainerRef = useRef(null); const editorRef = useRef(null); + const isQueryHistoryAutocompleteEnabled = usePreference( + 'enableQueryHistoryAutocomplete' + ); const focusRingProps = useFocusRing({ outer: true, @@ -140,11 +152,31 @@ export const OptionEditor: React.FunctionComponent = ({ const schemaFields = useAutocompleteFields(namespace); const completer = useMemo(() => { - return createQueryAutocompleter({ - fields: schemaFields, - serverVersion, - }); - }, [schemaFields, serverVersion]); + return isQueryHistoryAutocompleteEnabled + ? createQueryWithHistoryAutocompleter( + savedQueries + .filter((query) => !('update' in query)) + .map((query) => ({ + lastExecuted: query._lastExecuted, + queryProperties: getQueryAttributes(query), + })), + { + fields: schemaFields, + serverVersion, + }, + onApplyQuery + ) + : createQueryAutocompleter({ + fields: schemaFields, + serverVersion, + }); + }, [ + savedQueries, + schemaFields, + serverVersion, + onApplyQuery, + isQueryHistoryAutocompleteEnabled, + ]); const onFocus = () => { if (insertEmptyDocOnFocus) { @@ -152,6 +184,8 @@ export const OptionEditor: React.FunctionComponent = ({ if (editorRef.current?.editorContents === '') { editorRef.current?.applySnippet('\\{${}}'); } + if (isQueryHistoryAutocompleteEnabled && editorRef.current?.editor) + editorRef.current?.startCompletion(); }); } }; @@ -215,11 +249,17 @@ export const OptionEditor: React.FunctionComponent = ({ ); }; -const ConnectedOptionEditor = connect((state: RootState) => { - return { - namespace: state.queryBar.namespace, - serverVersion: state.queryBar.serverVersion, - }; -})(OptionEditor); +const ConnectedOptionEditor = (state: RootState) => ({ + namespace: state.queryBar.namespace, + serverVersion: state.queryBar.serverVersion, + savedQueries: [ + ...state.queryBar.recentQueries, + ...state.queryBar.favoriteQueries, + ], +}); + +const mapDispatchToProps = { + onApplyQuery: applyFromHistory, +}; -export default ConnectedOptionEditor; +export default connect(ConnectedOptionEditor, mapDispatchToProps)(OptionEditor); diff --git a/packages/compass-query-bar/src/components/query-ai.spec.tsx b/packages/compass-query-bar/src/components/query-ai.spec.tsx index 59ffbe156c1..ef2b9137851 100644 --- a/packages/compass-query-bar/src/components/query-ai.spec.tsx +++ b/packages/compass-query-bar/src/components/query-ai.spec.tsx @@ -166,6 +166,7 @@ describe('QueryAI Component', function () { feedback: 'positive', request_id: 'pineapple', text: 'this is the query I was looking for', + connection_id: 'TEST', }, }, ]); diff --git a/packages/compass-query-bar/src/components/query-ai.tsx b/packages/compass-query-bar/src/components/query-ai.tsx index 9d589a33621..626b27e72ea 100644 --- a/packages/compass-query-bar/src/components/query-ai.tsx +++ b/packages/compass-query-bar/src/components/query-ai.tsx @@ -13,10 +13,12 @@ import { import { useLogger } from '@mongodb-js/compass-logging/provider'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; import { isEqualDefaultQuery } from '../utils/query'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const useOnSubmitFeedback = (lastAIQueryRequestId: string | null) => { const logger = useLogger('AI-QUERY-UI'); const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); return useCallback( (feedback: 'positive' | 'negative', text: string) => { const { log, mongoLogId } = logger; @@ -26,11 +28,15 @@ const useOnSubmitFeedback = (lastAIQueryRequestId: string | null) => { text, }); - track('AI Query Feedback', () => ({ - feedback, - text, - request_id: lastAIQueryRequestId, - })); + track( + 'AI Query Feedback', + () => ({ + feedback, + text, + request_id: lastAIQueryRequestId, + }), + connectionInfoAccess.getCurrentConnectionInfo() + ); openToast('query-ai-feedback-submitted', { variant: 'success', @@ -38,7 +44,7 @@ const useOnSubmitFeedback = (lastAIQueryRequestId: string | null) => { timeout: 10_000, }); }, - [logger, lastAIQueryRequestId, track] + [logger, lastAIQueryRequestId, track, connectionInfoAccess] ); }; diff --git a/packages/compass-query-bar/src/components/query-history-button-popover.tsx b/packages/compass-query-bar/src/components/query-history-button-popover.tsx index 7fe44f426a7..fae6dbebbf6 100644 --- a/packages/compass-query-bar/src/components/query-history-button-popover.tsx +++ b/packages/compass-query-bar/src/components/query-history-button-popover.tsx @@ -9,11 +9,12 @@ import { } from '@mongodb-js/compass-components'; import QueryHistory from './query-history'; -import { fetchSavedQueries } from '../stores/query-bar-reducer'; import { useTrackOnChange, type TrackFunction, } from '@mongodb-js/compass-telemetry/provider'; +import { fetchSavedQueries } from '../stores/query-bar-reducer'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const openQueryHistoryButtonStyles = css( { @@ -42,16 +43,18 @@ const QueryHistoryButtonPopover = ({ onOpenPopover: () => void; }) => { const [isOpen, setIsOpen] = React.useState(false); + const connectionInfoAccess = useConnectionInfoAccess(); useTrackOnChange( (track: TrackFunction) => { + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); if (isOpen) { - track('Query History Opened'); + track('Query History Opened', {}, connectionInfo); } else { - track('Query History Closed'); + track('Query History Closed', {}, connectionInfo); } }, - [isOpen], + [isOpen, connectionInfoAccess], undefined ); diff --git a/packages/compass-query-bar/src/components/query-history/favorite-list.tsx b/packages/compass-query-bar/src/components/query-history/favorite-list.tsx index 9cbc81b275c..eeada773310 100644 --- a/packages/compass-query-bar/src/components/query-history/favorite-list.tsx +++ b/packages/compass-query-bar/src/components/query-history/favorite-list.tsx @@ -19,6 +19,7 @@ import type { RootState } from '../../stores/query-bar-store'; import { OpenBulkUpdateActionButton } from './query-item/query-item-action-buttons'; import { usePreference } from 'compass-preferences-model/provider'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; export type FavoriteActions = { onApply: (query: BaseQuery) => void; @@ -37,17 +38,22 @@ const FavoriteItem = ({ isReadonly: boolean; }) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const readOnlyCompass = usePreference('readOnly'); const isUpdateQuery = !!query.update; const isDisabled = isUpdateQuery && (isReadonly || readOnlyCompass); const attributes = useMemo(() => getQueryAttributes(query), [query]); const onCardClick = useCallback(() => { - track('Query History Favorite Used', { - id: query._id, - screen: 'documents', - isUpdateQuery, - }); + track( + 'Query History Favorite Used', + { + id: query._id, + screen: 'documents', + isUpdateQuery, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); if (isDisabled) { return; @@ -66,16 +72,21 @@ const FavoriteItem = ({ onApply, attributes, onUpdateFavoriteChoosen, + connectionInfoAccess, ]); const onDeleteClick = useCallback(() => { - track('Query History Favorite Removed', { - id: query._id, - screen: 'documents', - isUpdateQuery, - }); + track( + 'Query History Favorite Removed', + { + id: query._id, + screen: 'documents', + isUpdateQuery, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); onDelete(query._id); - }, [track, query._id, isUpdateQuery, onDelete]); + }, [track, query._id, isUpdateQuery, onDelete, connectionInfoAccess]); return ( { const [tab, setTab] = useState('recent'); + const connectionInfoAccess = useConnectionInfoAccess(); useTrackOnChange( (track: TrackFunction) => { + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); if (tab === 'favorite') { - track('Query History Favorites'); + track('Query History Favorites', {}, connectionInfo); } else { - track('Query History Recent'); + track('Query History Recent', {}, connectionInfo); } }, - [tab], + [tab, connectionInfoAccess], undefined ); diff --git a/packages/compass-query-bar/src/components/query-history/recent-list.tsx b/packages/compass-query-bar/src/components/query-history/recent-list.tsx index 415dd07cfec..16b525e7e45 100644 --- a/packages/compass-query-bar/src/components/query-history/recent-list.tsx +++ b/packages/compass-query-bar/src/components/query-history/recent-list.tsx @@ -23,6 +23,7 @@ import { SaveQueryForm } from './save-query-form'; import { formatQuery, copyToClipboard, getQueryAttributes } from '../../utils'; import type { BaseQuery } from '../../constants/query-properties'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; type RecentActions = { onFavorite: (query: RecentQuery, name: string) => Promise; @@ -43,6 +44,7 @@ const RecentItem = ({ isReadonly: boolean; }) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const readOnlyCompass = usePreference('readOnly'); const isUpdateQuery = !!query.update; const isDisabled = isUpdateQuery && (isReadonly || readOnlyCompass); @@ -61,9 +63,13 @@ const RecentItem = ({ onUpdateRecentChoosen(); } - track('Query History Recent Used', { - isUpdateQuery, - }); + track( + 'Query History Recent Used', + { + isUpdateQuery, + }, + connectionInfoAccess.getCurrentConnectionInfo() + ); onApply(attributes); }, [ isDisabled, @@ -72,6 +78,7 @@ const RecentItem = ({ onApply, attributes, onUpdateRecentChoosen, + connectionInfoAccess, ]); const onCardClick = useCallback( @@ -88,10 +95,14 @@ const RecentItem = ({ const onSaveQuery = useCallback( (name: string) => { - track('Query History Favorite Added', { isUpdateQuery }); + track( + 'Query History Favorite Added', + { isUpdateQuery }, + connectionInfoAccess.getCurrentConnectionInfo() + ); void onFavorite(query, name); }, - [track, isUpdateQuery, onFavorite, query] + [track, isUpdateQuery, onFavorite, query, connectionInfoAccess] ); return ( diff --git a/packages/compass-query-bar/src/components/query-option.tsx b/packages/compass-query-bar/src/components/query-option.tsx index 9aac56e458c..bf79d36d9ed 100644 --- a/packages/compass-query-bar/src/components/query-option.tsx +++ b/packages/compass-query-bar/src/components/query-option.tsx @@ -17,6 +17,7 @@ import { changeField } from '../stores/query-bar-reducer'; import type { QueryProperty } from '../constants/query-properties'; import type { RootState } from '../stores/query-bar-store'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const queryOptionStyles = css({ display: 'flex', @@ -122,6 +123,7 @@ const QueryOption: React.FunctionComponent = ({ disabled = false, }) => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const darkMode = useDarkMode(); const editorInitialValueRef = useRef(value); const editorCurrentValueRef = useRef(value); @@ -146,10 +148,14 @@ const QueryOption: React.FunctionComponent = ({ editorCurrentValueRef.current !== editorInitialValueRef.current && (editorInitialValueRef.current || editorCurrentValueRef.current !== '{}') ) { - track('Query Edited', { option_name: name }); + track( + 'Query Edited', + { option_name: name }, + connectionInfoAccess.getCurrentConnectionInfo() + ); editorInitialValueRef.current = editorCurrentValueRef.current; } - }, [track, name]); + }, [track, name, connectionInfoAccess]); return (
({ + id: 'TEST', + }), + }; + describe('with a successful server response', function () { it('should succeed', async function () { const mockAtlasAiService = { @@ -54,6 +60,7 @@ describe('aiQueryReducer', function () { }, { dataService: mockDataService, + connectionInfoAccess, atlasAuthService: { on: sandbox.stub() }, atlasAiService: mockAtlasAiService, preferences, @@ -99,6 +106,7 @@ describe('aiQueryReducer', function () { const store = createStore({}, { atlasAuthService: { on: sandbox.stub() }, atlasAiService: mockAtlasAiService, + connectionInfoAccess, dataService: { sample() { return Promise.resolve([]); @@ -131,6 +139,7 @@ describe('aiQueryReducer', function () { return Promise.resolve([]); }, }, + connectionInfoAccess, preferences, logger: createNoopLogger(), track: createNoopTrack(), @@ -172,6 +181,7 @@ describe('aiQueryReducer', function () { }, { dataService: mockDataService, + connectionInfoAccess, atlasAuthService: { on: sandbox.stub() }, atlasAiService: mockAtlasAiService, preferences, @@ -212,6 +222,7 @@ describe('aiQueryReducer', function () { }, { dataService: mockDataService, + connectionInfoAccess, atlasAuthService: { on: sandbox.stub() }, atlasAiService: mockAtlasAiService, preferences, diff --git a/packages/compass-query-bar/src/stores/ai-query-reducer.ts b/packages/compass-query-bar/src/stores/ai-query-reducer.ts index f7530728493..0c6c7c43ee3 100644 --- a/packages/compass-query-bar/src/stores/ai-query-reducer.ts +++ b/packages/compass-query-bar/src/stores/ai-query-reducer.ts @@ -16,6 +16,7 @@ import type { AtlasServiceError } from '@mongodb-js/atlas-service/renderer'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import { mongoLogId } from '@mongodb-js/compass-logging/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; type AIQueryStatus = 'ready' | 'fetching' | 'success'; @@ -115,6 +116,7 @@ type FailedResponseTrackMessage = { log: Logger['log']; track: TrackFunction; requestId: string; + connectionInfo: ConnectionInfo; }; function trackAndLogFailed({ @@ -125,6 +127,7 @@ function trackAndLogFailed({ log, track, requestId, + connectionInfo, }: FailedResponseTrackMessage) { log.warn(mongoLogId(1_001_000_198), 'AIQuery', 'AI query request failed', { statusCode, @@ -133,13 +136,17 @@ function trackAndLogFailed({ errorCode, requestId, }); - track('AI Response Failed', () => ({ - editor_view_type: 'find', - error_name: errorName, - status_code: statusCode, - error_code: errorCode ?? '', - request_id: requestId, - })); + track( + 'AI Response Failed', + () => ({ + editor_view_type: 'find', + error_name: errorName, + status_code: statusCode, + error_code: errorCode ?? '', + request_id: requestId, + }), + connectionInfo + ); } export const runAIQuery = ( @@ -157,6 +164,7 @@ export const runAIQuery = ( preferences, atlasAiService, logger: { log }, + connectionInfoAccess, track, } ) => { @@ -165,12 +173,18 @@ export const runAIQuery = ( const abortController = new AbortController(); const { id: requestId, signal } = getAbortSignal(); - track('AI Prompt Submitted', () => ({ - editor_view_type: 'find', - user_input_length: userInput.length, - has_sample_documents: provideSampleDocuments, - request_id: requestId, - })); + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); + + track( + 'AI Prompt Submitted', + () => ({ + editor_view_type: 'find', + user_input_length: userInput.length, + has_sample_documents: provideSampleDocuments, + request_id: requestId, + }), + connectionInfo + ); const { aiQuery: { aiQueryRequestId: existingRequestId }, @@ -234,6 +248,7 @@ export const runAIQuery = ( log, track, requestId, + connectionInfo, }); // We're going to reset input state with this error, show the error in the // toast instead @@ -286,6 +301,7 @@ export const runAIQuery = ( log, track, requestId, + connectionInfo, }); dispatch({ type: AIQueryActionTypes.AIQueryFailed, @@ -314,6 +330,7 @@ export const runAIQuery = ( log, track, requestId, + connectionInfo, }); return; } @@ -326,6 +343,7 @@ export const runAIQuery = ( log, track, requestId, + connectionInfo, }); dispatch({ type: AIQueryActionTypes.AIQueryFailed, @@ -351,11 +369,15 @@ export const runAIQuery = ( shape: Object.keys(generatedFields), } ); - track('AI Response Generated', () => ({ - editor_view_type: 'find', - query_shape: Object.keys(generatedFields), - request_id: requestId, - })); + track( + 'AI Response Generated', + () => ({ + editor_view_type: 'find', + query_shape: Object.keys(generatedFields), + request_id: requestId, + }), + connectionInfo + ); dispatch({ type: AIQueryActionTypes.AIQuerySucceeded, diff --git a/packages/compass-query-bar/src/stores/query-bar-reducer.ts b/packages/compass-query-bar/src/stores/query-bar-reducer.ts index 71da0837305..0996a5c9036 100644 --- a/packages/compass-query-bar/src/stores/query-bar-reducer.ts +++ b/packages/compass-query-bar/src/stores/query-bar-reducer.ts @@ -394,7 +394,7 @@ const saveRecentQuery = ( query: Omit ): QueryBarThunkAction> => { return async ( - _dispatch, + dispatch, getState, { recentQueryStorage, logger: { debug } } ) => { @@ -424,6 +424,7 @@ const saveRecentQuery = ( existingQuery._id, updateAttributes ); + dispatch(fetchSavedQueries()); return; } @@ -432,6 +433,7 @@ const saveRecentQuery = ( _ns: namespace, _host: host ?? '', }); + dispatch(fetchSavedQueries()); } catch (e) { debug('Failed to save recent query', e); } diff --git a/packages/compass-query-bar/src/stores/query-bar-store.spec.ts b/packages/compass-query-bar/src/stores/query-bar-store.spec.ts new file mode 100644 index 00000000000..370507d03ec --- /dev/null +++ b/packages/compass-query-bar/src/stores/query-bar-store.spec.ts @@ -0,0 +1,74 @@ +import sinon from 'sinon'; +import { activatePlugin } from './query-bar-store'; +import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; +import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; +import { AppRegistry } from 'hadron-app-registry'; +import type { PreferencesAccess } from 'compass-preferences-model'; +import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; +import { expect } from 'chai'; +import { waitFor } from '@testing-library/react'; +describe('createQueryWithHistoryAutocompleter', function () { + let preferences: PreferencesAccess; + let loadAllStub: sinon.SinonStub; + beforeEach(async function () { + loadAllStub = sinon.stub(); + preferences = await createSandboxFromDefaultPreferences(); + }); + afterEach(function () { + sinon.restore(); + }); + it('calls fetchSavedQueries when activatePlugin is called', async function () { + const mockService = { + getQueryFromUserInput: sinon + .stub() + .resolves({ content: { query: { filter: '{_id: 1}' } } }), + }; + const mockDataService = { + sample: sinon.stub().resolves([{ _id: 42 }]), + getConnectionString: sinon.stub().returns({ + hosts: ['localhost:27017'], + }), + }; + activatePlugin( + { + namespace: 'test.coll', + isReadonly: true, + serverVersion: '6.0.0', + isSearchIndexesSupported: true, + isTimeSeries: false, + isClustered: false, + isFLE: false, + isDataLake: false, + isAtlas: false, + }, + { + localAppRegistry: new AppRegistry(), + globalAppRegistry: new AppRegistry(), + dataService: mockDataService, + recentQueryStorageAccess: { + getStorage: () => ({ + loadAll: loadAllStub, + }), + }, + favoriteQueryStorageAccess: { + getStorage: () => ({ + loadAll: loadAllStub, + }), + }, + atlasAuthService: { on: sinon.stub() }, + atlasAiService: mockService, + preferences, + logger: createNoopLogger(), + track: createNoopTrack(), + instance: { isWritable: true, on: sinon.stub() }, + } as any, + { + on: () => {}, + cleanup: () => {}, + } as any + ); + await waitFor(() => { + expect(loadAllStub).to.have.been.calledTwice; + }); + }); +}); diff --git a/packages/compass-query-bar/src/stores/query-bar-store.ts b/packages/compass-query-bar/src/stores/query-bar-store.ts index a3fd82c2f96..70a1dbcf532 100644 --- a/packages/compass-query-bar/src/stores/query-bar-store.ts +++ b/packages/compass-query-bar/src/stores/query-bar-store.ts @@ -7,13 +7,17 @@ import { import thunk from 'redux-thunk'; import type { AnyAction } from 'redux'; import type { ThunkAction, ThunkDispatch } from 'redux-thunk'; -import type { DataService } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionInfoAccess, + DataService, +} from '@mongodb-js/compass-connections/provider'; import { DEFAULT_FIELD_VALUES } from '../constants/query-bar-store'; import { mapQueryToFormFields } from '../utils/query'; import { queryBarReducer, INITIAL_STATE as INITIAL_QUERY_BAR_STATE, QueryBarActions, + fetchSavedQueries, } from './query-bar-reducer'; import { aiQueryReducer } from './ai-query-reducer'; import { getQueryAttributes } from '../utils'; @@ -44,6 +48,7 @@ type QueryBarServices = { preferences: PreferencesAccess; logger: Logger; track: TrackFunction; + connectionInfoAccess: ConnectionInfoAccess; atlasAuthService: AtlasAuthService; atlasAiService: AtlasAiService; favoriteQueryStorageAccess?: FavoriteQueryStorageAccess; @@ -77,6 +82,7 @@ export type QueryBarExtraArgs = { recentQueryStorage?: RecentQueryStorage; logger: Logger; track: TrackFunction; + connectionInfoAccess: ConnectionInfoAccess; atlasAiService: AtlasAiService; }; @@ -119,6 +125,7 @@ export function activatePlugin( preferences, logger, track, + connectionInfoAccess, atlasAuthService, atlasAiService, favoriteQueryStorageAccess, @@ -153,6 +160,7 @@ export function activatePlugin( preferences, logger, track, + connectionInfoAccess, atlasAiService, } ); @@ -164,5 +172,7 @@ export function activatePlugin( }); }); + store.dispatch(fetchSavedQueries()); + return { store, deactivate: cleanup, context: QueryBarStoreContext }; } diff --git a/packages/compass-saved-aggregations-queries/package.json b/packages/compass-saved-aggregations-queries/package.json index 5f114ef1e2a..728e1820944 100644 --- a/packages/compass-saved-aggregations-queries/package.json +++ b/packages/compass-saved-aggregations-queries/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.33.0", + "version": "1.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,19 +48,19 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/my-queries-storage": "^0.13.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "fuse.js": "^6.5.3", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -68,8 +68,8 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-saved-aggregations-queries/src/index.ts b/packages/compass-saved-aggregations-queries/src/index.ts index bdcf6573577..c977c816dbd 100644 --- a/packages/compass-saved-aggregations-queries/src/index.ts +++ b/packages/compass-saved-aggregations-queries/src/index.ts @@ -2,7 +2,7 @@ import { registerHadronPlugin } from 'hadron-app-registry'; import { connectionsManagerLocator } from '@mongodb-js/compass-connections/provider'; import { mongoDBInstancesManagerLocator } from '@mongodb-js/compass-app-stores/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { activatePlugin } from './stores'; import AggregationsQueriesList from './components/aggregations-queries-list'; import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; @@ -18,7 +18,7 @@ const serviceLocators = { instancesManager: mongoDBInstancesManagerLocator, preferencesAccess: preferencesLocator, logger: createLoggerLocator('COMPASS-MY-QUERIES-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, workspaces: workspacesServiceLocator, pipelineStorage: pipelineStorageLocator, favoriteQueryStorageAccess: favoriteQueryStorageAccessLocator, diff --git a/packages/compass-schema-validation/package.json b/packages/compass-schema-validation/package.json index 397f0b369f1..2d55fa0eda0 100644 --- a/packages/compass-schema-validation/package.json +++ b/packages/compass-schema-validation/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "6.33.0", + "version": "6.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,41 +48,41 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "chai": "^4.2.0", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-mocha": "^12.2.0", "enzyme": "^3.11.0", "eslint": "^7.25.0", - "hadron-ipc": "^3.2.16", + "hadron-ipc": "^3.2.18", "mocha": "^10.2.0", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "nyc": "^15.1.0", "react-dom": "^17.0.2", "sinon": "^8.1.1", "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "javascript-stringify": "^2.0.1", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "prop-types": "^15.7.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/compass-schema-validation/src/components/validation-editor/validation-editor.tsx b/packages/compass-schema-validation/src/components/validation-editor/validation-editor.tsx index 56f77310703..016e91481ed 100644 --- a/packages/compass-schema-validation/src/components/validation-editor/validation-editor.tsx +++ b/packages/compass-schema-validation/src/components/validation-editor/validation-editor.tsx @@ -28,6 +28,10 @@ import type { } from '../../modules/validation'; import { checkValidator } from '../../modules/validation'; import { ActionSelector, LevelSelector } from '../validation-selectors'; +import { + type ConnectionInfoAccess, + withConnectionInfoAccess, +} from '@mongodb-js/compass-connections/provider'; const validationEditorStyles = css({ padding: spacing[3], @@ -117,6 +121,7 @@ export type ValidationEditorProps = { isEditable: boolean; darkMode?: boolean; track: TrackFunction; + connectionInfoAccess: ConnectionInfoAccess; }; /** @@ -178,7 +183,11 @@ class ValidationEditor extends Component { typeof checkedValidator.validator === 'object' && !!checkedValidator.validator?.$jsonSchema, }; - this.props.track('Schema Validation Edited', trackEvent); + this.props.track( + 'Schema Validation Edited', + trackEvent, + this.props.connectionInfoAccess.getCurrentConnectionInfo() + ); } /** @@ -313,5 +322,7 @@ class ValidationEditor extends Component { } export default withTelemetry( - withDarkMode(ValidationEditor) + withConnectionInfoAccess( + withDarkMode(ValidationEditor) + ) ); diff --git a/packages/compass-schema-validation/src/index.ts b/packages/compass-schema-validation/src/index.ts index 3cd3f8f8c3b..ec4da917a16 100644 --- a/packages/compass-schema-validation/src/index.ts +++ b/packages/compass-schema-validation/src/index.ts @@ -2,13 +2,14 @@ import { onActivated } from './stores'; import CompassSchemaValidation from './components/compass-schema-validation'; import { registerHadronPlugin } from 'hadron-app-registry'; import { + connectionInfoAccessLocator, dataServiceLocator, type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; import { mongoDBInstanceLocator } from '@mongodb-js/compass-app-stores/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; export const CompassSchemaValidationHadronPlugin = registerHadronPlugin( { @@ -20,10 +21,11 @@ export const CompassSchemaValidationHadronPlugin = registerHadronPlugin( dataService: dataServiceLocator as DataServiceLocator< 'aggregate' | 'collectionInfo' | 'updateCollection' >, + connectionInfoAccess: connectionInfoAccessLocator, instance: mongoDBInstanceLocator, preferences: preferencesLocator, logger: createLoggerLocator('COMPASS-SCHEMA-VALIDATION-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, } ); export const CompassSchemaValidationPlugin = { diff --git a/packages/compass-schema-validation/src/modules/index.ts b/packages/compass-schema-validation/src/modules/index.ts index 8c3376bb51a..f0592fd6cbd 100644 --- a/packages/compass-schema-validation/src/modules/index.ts +++ b/packages/compass-schema-validation/src/modules/index.ts @@ -23,7 +23,10 @@ import type { EditModeAction, EditModeState } from './edit-mode'; import editMode, { INITIAL_STATE as EDIT_MODE_STATE } from './edit-mode'; import type { ThunkAction } from 'redux-thunk'; import type { PreferencesAccess } from 'compass-preferences-model'; -import type { DataService } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionInfoAccess, + DataService, +} from '@mongodb-js/compass-connections/provider'; import type AppRegistry from 'hadron-app-registry'; import type { Logger } from '@mongodb-js/compass-logging/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; @@ -61,6 +64,7 @@ export type SchemaValidationExtraArgs = { DataService, 'aggregate' | 'collectionInfo' | 'updateCollection' >; + connectionInfoAccess: ConnectionInfoAccess; preferences: PreferencesAccess; globalAppRegistry: AppRegistry; logger: Logger; diff --git a/packages/compass-schema-validation/src/modules/validation.ts b/packages/compass-schema-validation/src/modules/validation.ts index 0cdb01d56dd..a98c34f5541 100644 --- a/packages/compass-schema-validation/src/modules/validation.ts +++ b/packages/compass-schema-validation/src/modules/validation.ts @@ -456,7 +456,11 @@ export function validationFromCollection( export const saveValidation = ( validation: Validation ): SchemaValidationThunkAction> => { - return async (dispatch, getState, { dataService, track }) => { + return async ( + dispatch, + getState, + { dataService, track, connectionInfoAccess } + ) => { const state = getState(); const namespace = state.namespace; const checkedValidator = checkValidator(validation.validator); @@ -471,7 +475,11 @@ export const saveValidation = ( validation_action: validation.validationAction, validation_level: validation.validationLevel, }; - track('Schema Validation Updated', trackEvent); + track( + 'Schema Validation Updated', + trackEvent, + connectionInfoAccess.getCurrentConnectionInfo() + ); try { await dataService.updateCollection( `${namespace.database}.${namespace.collection}`, diff --git a/packages/compass-schema-validation/src/modules/zero-state.ts b/packages/compass-schema-validation/src/modules/zero-state.ts index 22d2b70b09d..fcb98f5f5b1 100644 --- a/packages/compass-schema-validation/src/modules/zero-state.ts +++ b/packages/compass-schema-validation/src/modules/zero-state.ts @@ -48,9 +48,13 @@ export const zeroStateChanged = ( export const changeZeroState = ( isZeroState: boolean ): SchemaValidationThunkAction => { - return (dispatch, _getState, { track }) => { + return (dispatch, _getState, { track, connectionInfoAccess }) => { if (isZeroState === false) { - track('Schema Validation Added'); + track( + 'Schema Validation Added', + {}, + connectionInfoAccess.getCurrentConnectionInfo() + ); } return dispatch(zeroStateChanged(isZeroState)); }; diff --git a/packages/compass-schema-validation/src/stores/store.spec.ts b/packages/compass-schema-validation/src/stores/store.spec.ts index 116f12ba577..bdc8f0f9b70 100644 --- a/packages/compass-schema-validation/src/stores/store.spec.ts +++ b/packages/compass-schema-validation/src/stores/store.spec.ts @@ -20,6 +20,7 @@ import { onActivated } from './store'; import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const topologyDescription = { type: 'Unknown', @@ -45,6 +46,9 @@ describe('Schema Validation Store', function () { let store: Store; let deactivate: null | (() => void) = null; const globalAppRegistry = new AppRegistry(); + const connectionInfoAccess = { + getCurrentConnectionInfo: () => {}, + } as ConnectionInfoAccess; beforeEach(async function () { const activateResult = onActivated( @@ -56,6 +60,7 @@ describe('Schema Validation Store', function () { preferences: await createSandboxFromDefaultPreferences(), logger: createNoopLogger(), track: createNoopTrack(), + connectionInfoAccess, }, createActivateHelpers() ); diff --git a/packages/compass-schema-validation/src/stores/store.ts b/packages/compass-schema-validation/src/stores/store.ts index bb30e1bfea3..38510cf10cf 100644 --- a/packages/compass-schema-validation/src/stores/store.ts +++ b/packages/compass-schema-validation/src/stores/store.ts @@ -8,7 +8,10 @@ import { editModeChanged } from '../modules/edit-mode'; import semver from 'semver'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; import type { ActivateHelpers, AppRegistry } from 'hadron-app-registry'; -import type { DataService } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionInfoAccess, + DataService, +} from '@mongodb-js/compass-connections/provider'; import type { MongoDBInstance } from '@mongodb-js/compass-app-stores/provider'; import type { PreferencesAccess } from 'compass-preferences-model'; import type { Logger } from '@mongodb-js/compass-logging/provider'; @@ -25,6 +28,7 @@ type SchemaValidationServices = { DataService, 'aggregate' | 'collectionInfo' | 'updateCollection' >; + connectionInfoAccess: ConnectionInfoAccess; preferences: PreferencesAccess; instance: MongoDBInstance; logger: Logger; @@ -36,7 +40,12 @@ export function configureStore( state: Partial, services: Pick< SchemaValidationServices, - 'globalAppRegistry' | 'dataService' | 'preferences' | 'logger' | 'track' + | 'globalAppRegistry' + | 'dataService' + | 'preferences' + | 'logger' + | 'track' + | 'connectionInfoAccess' > ) { return createStore( @@ -57,6 +66,7 @@ export function onActivated( { globalAppRegistry, dataService, + connectionInfoAccess, preferences, instance, logger, @@ -77,6 +87,7 @@ export function onActivated( }, { dataService, + connectionInfoAccess, preferences, globalAppRegistry, logger, diff --git a/packages/compass-schema/package.json b/packages/compass-schema/package.json index 83bfdcb2fc4..19df073b66e 100644 --- a/packages/compass-schema/package.json +++ b/packages/compass-schema/package.json @@ -6,7 +6,7 @@ "email": "compass@mongodb.com" }, "private": true, - "version": "6.34.0", + "version": "6.37.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,9 +48,9 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", @@ -73,26 +73,26 @@ "xvfb-maybe": "^0.2.1" }, "dependencies": { - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/connection-storage": "^0.14.1", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/connection-storage": "^0.16.0", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "d3": "^3.5.17", - "hadron-app-registry": "^9.1.12", - "hadron-document": "^8.5.4", + "hadron-app-registry": "^9.2.1", + "hadron-document": "^8.5.5", "leaflet": "^1.5.1", "leaflet-defaulticon-compatibility": "^0.1.1", "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", "moment": "^2.29.4", "mongodb": "^6.7.0", - "mongodb-query-util": "^2.2.3", + "mongodb-query-util": "^2.2.4", "mongodb-schema": "^12.2.0", "numeral": "^1.5.6", "prop-types": "^15.7.2", @@ -100,7 +100,7 @@ "react-leaflet": "^2.4.0", "react-leaflet-draw": "^0.19.0", "reflux": "^0.4.1", - "@mongodb-js/reflux-state-mixin": "^1.0.2" + "@mongodb-js/reflux-state-mixin": "^1.0.3" }, "is_compass_plugin": true } diff --git a/packages/compass-schema/src/components/compass-schema.tsx b/packages/compass-schema/src/components/compass-schema.tsx index 231c85f8b07..6b4d47ff6b1 100644 --- a/packages/compass-schema/src/components/compass-schema.tsx +++ b/packages/compass-schema/src/components/compass-schema.tsx @@ -337,7 +337,7 @@ const FieldList: React.FunctionComponent<{ const nbsp = '\u00a0'; const title = 'Atlas’ Performance Advisor.'; const PerformanceAdvisorBanner = () => { - const { atlasMetadata } = useConnectionInfo(); + const connectionInfo = useConnectionInfo(); const track = useTelemetry(); return ( @@ -348,10 +348,12 @@ const PerformanceAdvisorBanner = () => { Insight {nbsp}or{nbsp} - {atlasMetadata ? ( + {connectionInfo.atlasMetadata ? ( track('Performance Advisor Clicked')} + href={getAtlasPerformanceAdvisorLink(connectionInfo.atlasMetadata)} + onClick={() => + track('Performance Advisor Clicked', {}, connectionInfo) + } hideExternalIcon > {title} diff --git a/packages/compass-schema/src/index.ts b/packages/compass-schema/src/index.ts index 0701e840424..201098d8abd 100644 --- a/packages/compass-schema/src/index.ts +++ b/packages/compass-schema/src/index.ts @@ -1,4 +1,5 @@ import { + connectionInfoAccessLocator, dataServiceLocator, type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; @@ -7,7 +8,7 @@ import CompassSchema from './components/compass-schema'; import { registerHadronPlugin } from 'hadron-app-registry'; import { activateSchemaPlugin } from './stores/store'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { preferencesLocator } from 'compass-preferences-model/provider'; import { fieldStoreServiceLocator } from '@mongodb-js/compass-field-store'; import { queryBarServiceLocator } from '@mongodb-js/compass-query-bar'; @@ -23,10 +24,11 @@ export const CompassSchemaHadronPlugin = registerHadronPlugin( 'sample' | 'isCancelError' >, logger: createLoggerLocator('COMPASS-SCHEMA-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, preferences: preferencesLocator, fieldStoreService: fieldStoreServiceLocator, queryBar: queryBarServiceLocator, + connectionInfoAccess: connectionInfoAccessLocator, } ); export const CompassSchemaPlugin = { diff --git a/packages/compass-schema/src/stores/store.spec.ts b/packages/compass-schema/src/stores/store.spec.ts index 096ed700631..f08d4617d25 100644 --- a/packages/compass-schema/src/stores/store.spec.ts +++ b/packages/compass-schema/src/stores/store.spec.ts @@ -8,6 +8,7 @@ import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; import type { FieldStoreService } from '@mongodb-js/compass-field-store'; import { createNoopTrack } from '@mongodb-js/compass-telemetry/provider'; +import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const dummyLogger = createNoopLogger('TEST'); const dummyTrack = createNoopTrack(); @@ -31,6 +32,9 @@ describe('Schema Store', function () { const globalAppRegistry = new AppRegistry(); const dataService = 'test'; const namespace = 'db.coll'; + const connectionInfoAccess = { + getCurrentConnectionInfo: () => {}, + } as ConnectionInfoAccess; beforeEach(async function () { const plugin = activateSchemaPlugin( @@ -46,6 +50,7 @@ describe('Schema Store', function () { preferences: await createSandboxFromDefaultPreferences(), fieldStoreService: mockFieldStoreService, queryBar: mockQueryBar as any, + connectionInfoAccess, }, createActivateHelpers() ); diff --git a/packages/compass-schema/src/stores/store.ts b/packages/compass-schema/src/stores/store.ts index 1debaaf7b54..9485a1250e9 100644 --- a/packages/compass-schema/src/stores/store.ts +++ b/packages/compass-schema/src/stores/store.ts @@ -20,7 +20,10 @@ import { import { capMaxTimeMSAtPreferenceLimit } from 'compass-preferences-model/provider'; import { openToast } from '@mongodb-js/compass-components'; import type { CollectionTabPluginMetadata } from '@mongodb-js/compass-collection'; -import type { DataService as OriginalDataService } from '@mongodb-js/compass-connections/provider'; +import type { + ConnectionInfoAccess, + DataService as OriginalDataService, +} from '@mongodb-js/compass-connections/provider'; import type { ActivateHelpers } from 'hadron-app-registry'; import type AppRegistry from 'hadron-app-registry'; import { configureActions } from '../actions'; @@ -57,6 +60,7 @@ function resultId(): number { export type DataService = Pick; export type SchemaPluginServices = { dataService: DataService; + connectionInfoAccess: ConnectionInfoAccess; localAppRegistry: Pick; globalAppRegistry: Pick; logger: Logger; @@ -127,6 +131,7 @@ export function activateSchemaPlugin( preferences, fieldStoreService, queryBar, + connectionInfoAccess, }: SchemaPluginServices, { on, cleanup }: ActivateHelpers ) { @@ -261,7 +266,11 @@ export function activateSchemaPlugin( geo_data: schema ? schemaContainsGeoData(schema) : false, analysis_time_ms: analysisTimeMS, }); - track('Schema Analyzed', trackEvent); + track( + 'Schema Analyzed', + trackEvent, + connectionInfoAccess.getCurrentConnectionInfo() + ); }, startAnalysis: async function (this: SchemaStore) { diff --git a/packages/compass-serverstats/package.json b/packages/compass-serverstats/package.json index 30f834356f3..9ec09b697e4 100644 --- a/packages/compass-serverstats/package.json +++ b/packages/compass-serverstats/package.json @@ -2,7 +2,7 @@ "name": "@mongodb-js/compass-serverstats", "description": "Compass Real Time", "private": true, - "version": "16.32.0", + "version": "16.35.0", "main": "dist/index.js", "compass:main": "src/index.ts", "exports": { @@ -30,15 +30,15 @@ }, "license": "SSPL", "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", "d3": "^3.5.17", "d3-timer": "^1.0.3", "debug": "^4.3.4", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb-ns": "^2.4.2", "prop-types": "^15.7.2", @@ -46,7 +46,7 @@ "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-serverstats/src/components/current-op-component.jsx b/packages/compass-serverstats/src/components/current-op-component.jsx index 5d0fd30e278..a17af94ee28 100644 --- a/packages/compass-serverstats/src/components/current-op-component.jsx +++ b/packages/compass-serverstats/src/components/current-op-component.jsx @@ -4,6 +4,9 @@ const PropTypes = require('prop-types'); const Actions = require('../actions'); const DBErrorStore = require('../stores/dberror-store'); const { withTelemetry } = require('@mongodb-js/compass-telemetry/provider'); +const { + withConnectionInfoAccess, +} = require('@mongodb-js/compass-connections/provider'); // const debug = require('debug')('mongodb-compass:server-stats:current-op-component'); @@ -97,7 +100,11 @@ class CurrentOpComponent extends React.Component { * @param {Object} data - The row data. */ showOperationDetails(data) { - this.props.track('CurrentOp showOperationDetails'); + this.props.track( + 'CurrentOp showOperationDetails', + {}, + this.props.connectionInfoAccess.getCurrentConnectionInfo() + ); Actions.showOperationDetails(data); } @@ -186,9 +193,10 @@ class CurrentOpComponent extends React.Component { CurrentOpComponent.propTypes = { store: PropTypes.any.isRequired, interval: PropTypes.number.isRequired, - track: PropTypes.any, + track: PropTypes.any.isRequired, + connectionInfoAccess: PropTypes.any.isRequired, }; CurrentOpComponent.displayName = 'CurrentOpComponent'; -module.exports = withTelemetry(CurrentOpComponent); +module.exports = withTelemetry(withConnectionInfoAccess(CurrentOpComponent)); diff --git a/packages/compass-serverstats/src/components/detailview-component.jsx b/packages/compass-serverstats/src/components/detailview-component.jsx deleted file mode 100644 index 8b2a5b1f891..00000000000 --- a/packages/compass-serverstats/src/components/detailview-component.jsx +++ /dev/null @@ -1,165 +0,0 @@ -const React = require('react'); -const Actions = require('../actions'); -const { Button, Icon } = require('@mongodb-js/compass-components'); -const PropTypes = require('prop-types'); -const { withTelemetry } = require('@mongodb-js/compass-telemetry/provider'); - -class DetailViewComponent extends React.Component { - constructor(props) { - super(props); - this.state = { error: null, data: {}, display: 'none' }; - } - - componentDidMount() { - this.unsubscribeShowOperationDetails = Actions.showOperationDetails.listen( - this.show.bind(this) - ); - this.unsubscribeHideOperationDetails = Actions.hideOperationDetails.listen( - this.hide.bind(this) - ); - } - - componentWillUnmount() { - this.unsubscribeShowOperationDetails(); - this.unsubscribeHideOperationDetails(); - } - - /** - * Set the component to visible. - * - * @param {Object} data - The operation data. - */ - show(data) { - this.setState({ data: data, display: 'block' }); - } - - /** - * Set the component to hidden. - */ - hide() { - this.setState({ data: {}, display: 'none' }); - } - - killOp() { - this.props.logger.track('DetailView killOp'); - Actions.killOp(this.state.data.opid); - this.hideOperationDetails(); - } - - /** - * Fire the show operation detail action with the row data. - */ - hideOperationDetails() { - this.props.logger.track('DetailView hideOperationDetails'); - Actions.hideOperationDetails(); - } - - removeMs(key, value) { - if (key === 'ms_running') { - return undefined; - } - return value; - } - - renderError() { - return ( -
- this.state.error.message -
- ); - } - - renderZero() { - return
; - } - - renderGraph() { - return ( -
-
-

operation details

-
- -
-
-
-
-
{this.state.data.op}
-
- {this.state.data.ns} -
-
- {this.state.data.ms_running + ' ms'} -
-
-
    -
  • -
    opid
    -
    - {this.state.data.opid} -
    -
  • -
  • -
    client s
    -
    - {this.state.data.client} -
    -
  • -
  • -
    active
    -
    - {this.state.data.active} -
    -
  • -
  • -
    wait lock
    -
    - {this.state.data.waitingForLock} -
    -
  • -
  • -
    - -
    -
  • -
-
- {JSON.stringify(this.state.data, this.removeMs, 4)} -
-
-
- ); - } - - render() { - if (this.state.error) { - return this.renderError(); - } - if (this.state.data.length === 0) { - return this.renderZero(); - } - return this.renderGraph(); - } - - static propTypes = { - logger: PropTypes.any.isRequired, - }; -} - -DetailViewComponent.displayName = 'DetailViewComponent'; - -module.exports = withTelemetry(DetailViewComponent); diff --git a/packages/compass-serverstats/src/components/detailview-component.tsx b/packages/compass-serverstats/src/components/detailview-component.tsx new file mode 100644 index 00000000000..87a4b2e3f3e --- /dev/null +++ b/packages/compass-serverstats/src/components/detailview-component.tsx @@ -0,0 +1,131 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { Button, Icon } from '@mongodb-js/compass-components'; +import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; + +import Actions from '../actions'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; + +function removeMS(key: string, value: any) { + if (key === 'ms_running') { + return undefined; + } + return value; +} + +type CurrentOpData = { + op: string; + ns: string; + ms_running: number; + opid: number; + client: string; + active: boolean; + waitingForLock: boolean; +}; + +export function DetailViewComponent() { + const [data, setData] = useState(null); + + const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); + + useEffect(() => { + const unsubscribeShowOperationDetails = Actions.showOperationDetails.listen( + (newDataToShow: CurrentOpData) => { + setData(newDataToShow); + } + ); + const unsubscribeHideOperationDetails = Actions.hideOperationDetails.listen( + () => { + setData(null); + } + ); + + return () => { + unsubscribeShowOperationDetails(); + unsubscribeHideOperationDetails(); + }; + }, []); + + const hideOperationDetails = useCallback(() => { + track( + 'DetailView hideOperationDetails', + {}, + connectionInfoAccess.getCurrentConnectionInfo() + ); + Actions.hideOperationDetails(); + }, [track, connectionInfoAccess]); + + const onKillOp = useCallback(() => { + track( + 'DetailView killOp', + {}, + connectionInfoAccess.getCurrentConnectionInfo() + ); + if (data?.opid !== undefined) Actions.killOp(data.opid); + hideOperationDetails(); + }, [data, track, hideOperationDetails, connectionInfoAccess]); + + if (!data) { + return null; + } + + return ( +
+
+

operation details

+
+ +
+
+
+
+
{data.op}
+
{data.ns}
+
{`${data.ms_running} ms`}
+
+
    +
  • +
    opid
    +
    {data.opid}
    +
  • +
  • +
    client s
    +
    {data.client}
    +
  • +
  • +
    active
    +
    {data.active}
    +
  • +
  • +
    wait lock
    +
    + {data.waitingForLock} +
    +
  • +
  • +
    + +
    +
  • +
+
+ {JSON.stringify(data, removeMS, 4)} +
+
+
+ ); +} diff --git a/packages/compass-serverstats/src/components/index.tsx b/packages/compass-serverstats/src/components/index.tsx index 87f9e5e4679..a6757433c2c 100644 --- a/packages/compass-serverstats/src/components/index.tsx +++ b/packages/compass-serverstats/src/components/index.tsx @@ -25,6 +25,7 @@ import { useTrackOnChange, type TrackFunction, } from '@mongodb-js/compass-telemetry/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const REFRESH_STATS_INTERVAL_MS = 1000; @@ -118,10 +119,18 @@ function PerformancePanelMsgs() { */ function PerformanceComponent() { const eventDispatcher = useRef(realTimeDispatcher()); - - useTrackOnChange((track: TrackFunction) => { - track('Screen', { name: 'performance' }); - }, []); + const connectionInfoAccess = useConnectionInfoAccess(); + + useTrackOnChange( + (track: TrackFunction) => { + track( + 'Screen', + { name: 'performance' }, + connectionInfoAccess.getCurrentConnectionInfo() + ); + }, + [connectionInfoAccess] + ); useEffect(() => { return () => { diff --git a/packages/compass-serverstats/src/components/server-stats-lists-component.jsx b/packages/compass-serverstats/src/components/server-stats-lists-component.jsx index efdc59a8904..e688f217ddf 100644 --- a/packages/compass-serverstats/src/components/server-stats-lists-component.jsx +++ b/packages/compass-serverstats/src/components/server-stats-lists-component.jsx @@ -1,6 +1,6 @@ const React = require('react'); const PropTypes = require('prop-types'); -const DetailViewComponent = require('./detailview-component'); +const { DetailViewComponent } = require('./detailview-component'); const CurrentOpComponent = require('./current-op-component'); const TopComponent = require('./top-component'); const CurrentOpStore = require('../stores/current-op-store'); diff --git a/packages/compass-serverstats/src/components/server-stats-toolbar.tsx b/packages/compass-serverstats/src/components/server-stats-toolbar.tsx index 24dd265e705..8ea26d269fa 100644 --- a/packages/compass-serverstats/src/components/server-stats-toolbar.tsx +++ b/packages/compass-serverstats/src/components/server-stats-toolbar.tsx @@ -13,6 +13,7 @@ import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; import Actions from '../actions'; import ServerStatsStore from '../stores/server-stats-graphs-store'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; const serverStatsToolbarStyles = css({ display: 'flex', @@ -57,6 +58,7 @@ type ServerStatsToolbarProps = { function ServerStatsToolbar({ eventDispatcher }: ServerStatsToolbarProps) { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const darkMode = useDarkMode(); const [time, setTime] = useState('00:00:00'); @@ -71,14 +73,15 @@ function ServerStatsToolbar({ eventDispatcher }: ServerStatsToolbarProps) { }, [eventDispatcher]); const onPlayPauseClicked = useCallback(() => { + const connectionInfo = connectionInfoAccess.getCurrentConnectionInfo(); if (isPaused) { - track('Performance Resumed'); + track('Performance Resumed', {}, connectionInfo); } else { - track('Performance Paused'); + track('Performance Paused', {}, connectionInfo); } setPaused(!isPaused); Actions.pause(); - }, [isPaused, track]); + }, [isPaused, track, connectionInfoAccess]); return (
undefined} runtime={fakeRuntime} - emitShellPluginOpened={emitShellOpenedSpy} enableShell /> ); @@ -49,23 +47,19 @@ describe('CompassShell', function () { getComputedStyle(shellDomNode).getPropertyValue('display'); expect(shellDisplayStyle).to.equal('none'); }); - - context('when is it expanded', function () { - it('calls the function prop emitShellPluginOpened', function () { - expect(emitShellOpenedSpy.calledOnce).to.equal(false); - - wrapper.setState({ height: 300 }); - wrapper.update(); - - expect(emitShellOpenedSpy.calledOnce).to.equal(true); - }); - }); }); context('when rendered expanded', function () { context('when runtime property is not present', function () { it('does not render a shell if runtime is null', function () { - const wrapper = mount(); + const wrapper = mount( + undefined} + runtime={null} + enableShell + /> + ); try { wrapper.setState({ height: 300 }); wrapper.update(); @@ -82,8 +76,9 @@ describe('CompassShell', function () { beforeEach(function () { wrapper = mount( undefined} runtime={fakeRuntime} - emitShellPluginOpened={() => {}} enableShell /> ); @@ -128,8 +123,9 @@ describe('CompassShell', function () { it('renders the inital output', function () { const wrapper = mount( undefined} runtime={fakeRuntime} - emitShellPluginOpened={() => {}} shellOutput={[ { type: 'output', @@ -159,7 +155,12 @@ describe('CompassShell', function () { context('when historyStorage is not present', function () { it('passes an empty history to the Shell', function () { const wrapper = shallow( - + undefined} + runtime={fakeRuntime} + enableShell + /> ); expect(wrapper.find(Shell).prop('initialHistory')).to.deep.equal([]); @@ -174,8 +175,9 @@ describe('CompassShell', function () { beforeEach(function () { wrapper = mount( undefined} runtime={fakeRuntime} - emitShellPluginOpened={() => {}} enableShell /> ); @@ -221,22 +223,14 @@ describe('CompassShell', function () { }); context('when historyStorage is present', function () { - let fakeStorage; - - beforeEach(function () { - fakeStorage = { - load: sinon.spy(() => Promise.resolve([])), - save: sinon.spy(() => Promise.resolve()), - }; - }); + const history = ['line1']; it('passes the loaded history as initialHistory to Shell', async function () { - fakeStorage.load = sinon.spy(() => Promise.resolve(['line1'])); - const wrapper = shallow( undefined} enableShell /> ); @@ -251,10 +245,13 @@ describe('CompassShell', function () { }); it('saves the history when history changes', async function () { + const changeSpy = sinon.spy(); + const wrapper = shallow( ); @@ -264,7 +261,7 @@ describe('CompassShell', function () { const onHistoryChanged = wrapper.find(Shell).prop('onHistoryChanged'); onHistoryChanged(['line1']); - expect(fakeStorage.save.calledWith(['line1'])).to.equal(true); + expect(changeSpy).to.have.been.calledOnceWith(['line1']); wrapper.unmount(); }); @@ -291,22 +288,20 @@ describe('CompassShell', function () { }); context('resize actions', function () { - let onOpenShellSpy; let wrapper; beforeEach(function () { - onOpenShellSpy = sinon.spy(); wrapper = mount( undefined} runtime={fakeRuntime} - emitShellPluginOpened={onOpenShellSpy} enableShell /> ); }); afterEach(function () { wrapper.unmount(); - onOpenShellSpy = null; wrapper = null; }); @@ -379,10 +374,6 @@ describe('CompassShell', function () { expect(shellDisplayStyle).to.equal('none'); }); - it('does not calls the function prop emitShellPluginOpened', function () { - expect(onOpenShellSpy.called).to.equal(false); - }); - context('when it hits the resize threshold', function () { beforeEach(function () { wrapper.setState({ height: 151 }); @@ -395,10 +386,6 @@ describe('CompassShell', function () { ).to.equal(151); expect(wrapper.state('height')).to.equal(151); }); - - it('calls the function prop emitShellPluginOpened', function () { - expect(onOpenShellSpy.calledOnce).to.equal(true); - }); }); }); }); diff --git a/packages/compass-shell/src/components/compass-shell/compass-shell.tsx b/packages/compass-shell/src/components/compass-shell/compass-shell.tsx index 5037f9bfa5d..faac5612b9e 100644 --- a/packages/compass-shell/src/components/compass-shell/compass-shell.tsx +++ b/packages/compass-shell/src/components/compass-shell/compass-shell.tsx @@ -1,13 +1,7 @@ import React, { Component, Fragment } from 'react'; -import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { withPreferences } from 'compass-preferences-model/provider'; -import type { Shell as ShellType } from '@mongosh/browser-repl'; - -// The browser-repl package.json defines exports['.'].require but not .module, hence require() instead of import -const { Shell } = - // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/consistent-type-imports - require('@mongosh/browser-repl') as typeof import('@mongosh/browser-repl'); +import { Shell } from '@mongosh/browser-repl'; import { ResizeHandle, ResizeDirection, @@ -16,12 +10,11 @@ import { getScrollbarStyles, palette, } from '@mongodb-js/compass-components'; - import ShellInfoModal from '../shell-info-modal'; import ShellHeader from '../shell-header'; import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread'; -import type { HistoryStorage } from '../../modules/history-storage'; -import type { RootState } from '../../modules'; +import type { RootState } from '../../stores/store'; +import { saveHistory, selectRuntimeById } from '../../stores/store'; const compassShellStyles = css( { @@ -63,42 +56,34 @@ function boundShellHeight(attemptedHeight: number): number { } export interface CompassShellProps { - emitShellPluginOpened?: () => void; runtime: WorkerRuntime | null; shellOutput?: ShellOutputEntry[]; - historyStorage?: HistoryStorage; enableShell: boolean; + initialHistory: string[] | null; + onHistoryChange: (history: string[]) => void; } interface CompassShellState { height: number; prevHeight: number; - initialHistory: string[] | null; isOperationInProgress: boolean; showInfoModal: boolean; } -type ShellOutputEntry = ShellType['state']['output'][number]; +type ShellProps = React.ComponentProps; + +type ShellRef = Extract['ref'], { current: any }>; + +type ShellOutputEntry = Required['initialOutput'][number]; export class CompassShell extends Component< CompassShellProps, CompassShellState > { - static propTypes = { - emitShellPluginOpened: PropTypes.func, - runtime: PropTypes.object, - shellOutput: PropTypes.array, - historyStorage: PropTypes.object, - enableShell: PropTypes.bool, - }; - - shellRef = React.createRef(); + shellRef: ShellRef = React.createRef(); shellOutput: readonly ShellOutputEntry[]; static defaultProps = { - emitShellPluginOpened: () => { - /* ignore */ - }, runtime: null, }; constructor(props: CompassShellProps) { @@ -109,34 +94,11 @@ export class CompassShell extends Component< this.state = { height: shellHeightClosed, prevHeight: defaultShellHeightOpened, - initialHistory: this.props.historyStorage ? null : [], isOperationInProgress: false, showInfoModal: false, }; } - componentDidMount() { - void this.loadHistory(); - window.addEventListener('beforeunload', this.terminateRuntime); - } - - componentDidUpdate( - prevProps: CompassShellProps, - prevState: CompassShellState - ) { - const { height } = this.state; - if ( - prevState.height < shellMinHeightOpened && - height > shellMinHeightOpened - ) { - this.props.emitShellPluginOpened?.(); - } - } - - componentWillUnmount() { - window.removeEventListener('beforeunload', this.terminateRuntime); - } - onShellOutputChanged = (output: readonly ShellOutputEntry[]) => { this.shellOutput = output; }; @@ -159,40 +121,6 @@ export class CompassShell extends Component< } }; - saveHistory = (history: readonly string[]) => { - void (async () => { - if (!this.props.historyStorage) { - return; - } - - try { - await this.props.historyStorage.save([...history]); - } catch (error) { - // eslint-disable-next-line no-console - console.error(error); - } - })(); - }; - - loadHistory = async () => { - if (!this.props.historyStorage) { - return; - } - - try { - const history = await this.props.historyStorage.load(); - this.setState({ - initialHistory: history, - }); - } catch (error) { - // eslint-disable-next-line no-console - console.error(error); - this.setState({ - initialHistory: [], - }); - } - }; - updateHeight(height: number) { if (height > shellMinHeightOpened) { this.setState({ @@ -214,16 +142,10 @@ export class CompassShell extends Component< focusEditor() { if (this.shellRef.current && window.getSelection()?.type !== 'Range') { - (this.shellRef.current as any) /* private ... */ - .focusEditor(); + this.shellRef.current.focusEditor(); } } - /** - * Render CompassShell component. - * - * @returns {React.Component} The rendered component. - */ render() { const { height, prevHeight, isOperationInProgress, showInfoModal } = this.state; @@ -231,7 +153,7 @@ export class CompassShell extends Component< if ( !this.props.enableShell || !this.props.runtime || - !this.state.initialHistory + !this.props.initialHistory ) { return
; } @@ -288,9 +210,11 @@ export class CompassShell extends Component< { + this.props.onHistoryChange([...history]); + }} onOutputChanged={this.onShellOutputChanged} onOperationStarted={this.onOperationStarted} onOperationEnd={this.onOperationEnd} @@ -302,9 +226,12 @@ export class CompassShell extends Component< } } -export default connect((state: RootState) => ({ - emitShellPluginOpened: () => { - state.runtime.appRegistry?.emit('compass:compass-shell:opened'); +export default connect( + (state: RootState) => { + return { + runtime: selectRuntimeById(state), + initialHistory: state.history, + }; }, - runtime: state.runtime ? state.runtime.runtime : null, -}))(withPreferences(CompassShell, ['enableShell'])); + { onHistoryChange: saveHistory } +)(withPreferences(CompassShell, ['enableShell'])); diff --git a/packages/compass-shell/src/components/compass-shell/tab-compass-shell.tsx b/packages/compass-shell/src/components/compass-shell/tab-compass-shell.tsx index 47688bf22bf..04f0d9463f0 100644 --- a/packages/compass-shell/src/components/compass-shell/tab-compass-shell.tsx +++ b/packages/compass-shell/src/components/compass-shell/tab-compass-shell.tsx @@ -1,28 +1,25 @@ import { connect } from 'react-redux'; import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { useTabState } from '@mongodb-js/compass-workspaces/provider'; +import { + useOnTabReplace, + useTabState, +} from '@mongodb-js/compass-workspaces/provider'; import { Banner, Link, css, getScrollbarStyles, palette, + rafraf, spacing, } from '@mongodb-js/compass-components'; -import type { MapStateToProps } from 'react-redux'; -import type { Shell as ShellType } from '@mongosh/browser-repl'; import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread'; - import ShellInfoModal from '../shell-info-modal'; import ShellHeader from '../shell-header/shell-header'; -import type { HistoryStorage } from '../../modules/history-storage'; -import type { RootState } from '../../modules'; import { usePreference } from 'compass-preferences-model/provider'; - -// The browser-repl package.json defines exports['.'].require but not .module, hence require() instead of import -const { Shell } = - // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/consistent-type-imports - require('@mongosh/browser-repl') as typeof import('@mongosh/browser-repl'); +import { Shell as _Shell } from '@mongosh/browser-repl'; +import type { RootState } from '../../stores/store'; +import { selectRuntimeById, saveHistory } from '../../stores/store'; const compassShellStyles = css( { @@ -47,54 +44,88 @@ const compassShellContainerStyles = css({ borderTop: `1px solid ${palette.gray.dark2}`, }); -type ShellOutputEntry = ShellType['state']['output'][number]; +type ShellProps = React.ComponentProps; + +type ShellRef = Extract['ref'], { current: any }>; + +type ShellType = ShellRef['current']; + +type ShellOutputEntry = Required['initialOutput'][number]; type CompassShellProps = { runtime: WorkerRuntime | null; - historyStorage?: HistoryStorage; - emitShellPluginOpened?(): void; + initialHistory: string[] | null; + onHistoryChange: (history: string[]) => void; + initialEvaluate?: string | string[]; + initialInput?: string; }; +function useInitialEval(initialEvaluate?: string | string[]) { + const [initialEvalApplied, setInitialEvalApplied] = useTabState( + 'initialEvalApplied', + false + ); + useEffect(() => { + setInitialEvalApplied(true); + }, [setInitialEvalApplied]); + return initialEvalApplied ? undefined : initialEvaluate; +} + +const Shell = React.forwardRef(function Shell( + { initialEvaluate: _initialEvaluate, ...props }, + ref +) { + const shellRef = useRef(null); + const initialEvaluate = useInitialEval(_initialEvaluate); + const mergeRef = useCallback( + (shell: ShellType | null) => { + shellRef.current = shell; + if (typeof ref === 'function') { + ref(shell); + } else if (ref) { + ref.current = shell; + } + }, + [ref] + ); + useEffect(() => { + return rafraf(() => { + shellRef.current?.focusEditor(); + }); + }, []); + return ( + <_Shell + ref={mergeRef} + initialEvaluate={initialEvaluate} + {...props} + > + ); +}); + const CompassShell: React.FC = ({ runtime, - historyStorage, - emitShellPluginOpened, + initialHistory, + onHistoryChange, + initialEvaluate, + initialInput, }) => { const enableShell = usePreference('enableShell'); - const shellRef = useRef(null); - const emitShellPluginOpenedRef = useRef(emitShellPluginOpened); - emitShellPluginOpenedRef.current = - emitShellPluginOpened ?? - (() => { - // noop - }); - const historyStorageRef = useRef(historyStorage); - historyStorageRef.current = historyStorage; - + const shellRef: ShellRef = useRef(null); const [infoModalVisible, setInfoModalVisible] = useState(false); const [isOperationInProgress, setIsOperationInProgress] = useState(false); - const [initialHistory, setInitialHistory] = useState(null); const [shellOutput, setShellOutput] = useTabState< readonly ShellOutputEntry[] >('shellOutput', []); - useEffect(() => { - async function loadHistory(historyStorage: HistoryStorage) { - try { - const history = await historyStorage.load(); - setInitialHistory(history); - } catch (error) { - // eslint-disable-next-line no-console - console.error(error); - setInitialHistory([]); - } - } - - emitShellPluginOpenedRef.current?.(); + const [shellInput, setShellInput] = useTabState( + 'shellInput', + initialInput ?? '' + ); - if (historyStorageRef.current) { - void loadHistory(historyStorageRef.current); - } - }, []); + useOnTabReplace(() => { + // Never allow to replace the shell tab to avoid destroying the runtime + // unnecessarily + return false; + }); const showInfoModal = useCallback(() => { setInfoModalVisible(true); @@ -106,23 +137,8 @@ const CompassShell: React.FC = ({ const focusEditor = useCallback(() => { if (shellRef.current && window.getSelection()?.type !== 'Range') { - shellRef.current['focusEditor'](); + shellRef.current.focusEditor(); } - }, [shellRef]); - - const saveHistory = useCallback((history: readonly string[]) => { - void (async (historyStorage: HistoryStorage | undefined) => { - if (!historyStorage) { - return; - } - - try { - await historyStorage.save([...history]); - } catch (error) { - // eslint-disable-next-line no-console - console.error(error); - } - })(historyStorageRef.current); }, []); const updateShellOutput = useCallback( @@ -140,6 +156,8 @@ const CompassShell: React.FC = ({ setIsOperationInProgress(false); }, []); + const canRenderShell = enableShell && initialHistory && runtime; + if (!enableShell) { return (
@@ -155,7 +173,7 @@ const CompassShell: React.FC = ({ ); } - if (!runtime || !initialHistory) { + if (!canRenderShell) { return
; } @@ -185,12 +203,19 @@ const CompassShell: React.FC = ({ { + onHistoryChange([...history]); + }} onOperationStarted={notifyOperationStarted} onOperationEnd={notifyOperationEnd} + maxOutputLength={1000} + maxHistoryLength={1000} />
@@ -198,15 +223,12 @@ const CompassShell: React.FC = ({ ); }; -const mapState: MapStateToProps< - Pick, - Pick, - RootState -> = (state) => ({ - emitShellPluginOpened() { - state.runtime.appRegistry?.emit('compass:compass-shell:opened'); +export default connect( + (state: RootState) => { + return { + runtime: selectRuntimeById(state), + initialHistory: state.history, + }; }, - runtime: state.runtime ? state.runtime.runtime : null, -}); - -export default connect(mapState)(CompassShell); + { onHistoryChange: saveHistory } +)(CompassShell); diff --git a/packages/compass-shell/src/components/shell-header/shell-header.tsx b/packages/compass-shell/src/components/shell-header/shell-header.tsx index 3ad687c5f4a..dc1855db0f0 100644 --- a/packages/compass-shell/src/components/shell-header/shell-header.tsx +++ b/packages/compass-shell/src/components/shell-header/shell-header.tsx @@ -10,7 +10,6 @@ import { useHotkeys, } from '@mongodb-js/compass-components'; import React from 'react'; -import PropTypes from 'prop-types'; const shellHeaderStyles = css({ height: spacing[5], @@ -157,14 +156,6 @@ export const ShellHeader = ({ ); }; -ShellHeader.propTypes = { - darkMode: PropTypes.bool, - isExpanded: PropTypes.bool.isRequired, - isOperationInProgress: PropTypes.bool.isRequired, - onShellToggleClicked: PropTypes.func.isRequired, - showInfoModal: PropTypes.func.isRequired, -}; - export default withDarkMode( ShellHeader ) as React.FunctionComponent; diff --git a/packages/compass-shell/src/components/shell-info-modal/shell-info-modal.tsx b/packages/compass-shell/src/components/shell-info-modal/shell-info-modal.tsx index 399eb3e154a..e0d00802cc6 100644 --- a/packages/compass-shell/src/components/shell-info-modal/shell-info-modal.tsx +++ b/packages/compass-shell/src/components/shell-info-modal/shell-info-modal.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React, { useCallback } from 'react'; import { css, @@ -77,9 +76,4 @@ function ShellInfoModal({ ); } -ShellInfoModal.propTypes = { - hideInfoModal: PropTypes.func.isRequired, - show: PropTypes.bool.isRequired, -}; - export default ShellInfoModal; diff --git a/packages/compass-shell/src/index.ts b/packages/compass-shell/src/index.ts index 87353600fbf..dd0d732b248 100644 --- a/packages/compass-shell/src/index.ts +++ b/packages/compass-shell/src/index.ts @@ -1,28 +1,17 @@ -import type { Logger } from '@mongodb-js/compass-logging/provider'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { ShellPlugin, onActivated } from './plugin'; import { registerHadronPlugin } from 'hadron-app-registry'; +import { preferencesLocator } from 'compass-preferences-model/provider'; +import { type WorkspaceComponent } from '@mongodb-js/compass-workspaces'; import { dataServiceLocator, type DataService, + connectionInfoAccessLocator, + type DataServiceLocator, } from '@mongodb-js/compass-connections/provider'; -import { - preferencesLocator, - type PreferencesAccess, -} from 'compass-preferences-model/provider'; -import { type WorkspaceComponent } from '@mongodb-js/compass-workspaces'; -import type { TrackFunction } from '@mongodb-js/compass-telemetry'; -export const CompassShellPlugin = registerHadronPlugin< - unknown, - { - logger: () => Logger; - track: () => TrackFunction; - dataService: () => DataService; - preferences: () => PreferencesAccess; - } ->( +export const CompassShellPlugin = registerHadronPlugin( { name: 'CompassShell', component: ShellPlugin, @@ -30,8 +19,9 @@ export const CompassShellPlugin = registerHadronPlugin< }, { logger: createLoggerLocator('COMPASS-SHELL'), - track: createTelemetryLocator(), - dataService: dataServiceLocator, + track: telemetryLocator, + dataService: dataServiceLocator as DataServiceLocator, + connectionInfo: connectionInfoAccessLocator, preferences: preferencesLocator, } ); diff --git a/packages/compass-shell/src/modules/index.ts b/packages/compass-shell/src/modules/index.ts deleted file mode 100644 index ee9ea4560d2..00000000000 --- a/packages/compass-shell/src/modules/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { combineReducers } from 'redux'; -import type { RuntimeAction, RuntimeState } from './runtime'; -import runtime from './runtime'; - -export interface RootState { - runtime: RuntimeState; -} - -export type RootAction = RuntimeAction; - -const reducer = combineReducers({ - runtime, -}); - -export default reducer; diff --git a/packages/compass-shell/src/modules/runtime.ts b/packages/compass-shell/src/modules/runtime.ts deleted file mode 100644 index fa52137965c..00000000000 --- a/packages/compass-shell/src/modules/runtime.ts +++ /dev/null @@ -1,164 +0,0 @@ -import type { DataService } from '@mongodb-js/compass-connections/provider'; -import { WorkerRuntime } from './worker-runtime'; -import type AppRegistry from 'hadron-app-registry'; -import type { RootAction } from '.'; - -/** - * The prefix. - */ -const PREFIX = 'shell/runtime' as const; - -/** - * Data service connected. - */ -export const SETUP_RUNTIME = `${PREFIX}/SETUP_RUNTIME` as const; -type SetupRuntimeAction = { - type: typeof SETUP_RUNTIME; - error: Error | null; - dataService: DataService | null; - appRegistry: AppRegistry | null; -}; - -/** - * enableShell preference changed. - */ -export const CHANGE_ENABLE_SHELL = `${PREFIX}/CHANGE_ENABLE_SHELL` as const; -type ChangeEnableShellAction = { - type: typeof CHANGE_ENABLE_SHELL; - enableShell: boolean; -}; -export type RuntimeAction = SetupRuntimeAction | ChangeEnableShellAction; - -/** - * The initial state. - */ -export const INITIAL_STATE: RuntimeState = { - error: null, - dataService: null, - runtime: null, - appRegistry: null, - enableShell: false, -}; - -export interface RuntimeState { - error: null | Error; - dataService: null | DataService; - runtime: null | typeof WorkerRuntime['prototype']; - appRegistry: null | AppRegistry; - enableShell: boolean; -} - -/** - * Reducer function for handling data service connected actions. - * - * @param {Object} state - The data service state. - * @param {Object} action - The action. - * - * @returns {String} The new state. - */ -export default function reducer( - state: RuntimeState = INITIAL_STATE, - action: RootAction -): RuntimeState { - if (action.type === SETUP_RUNTIME) { - return reduceSetupRuntime(state, action); - } - - if (action.type === CHANGE_ENABLE_SHELL) { - return reduceChangeEnableShell(state, action); - } - - return state; -} - -function createOrDestroyRuntimeForState(state: RuntimeState): RuntimeState { - if (!state.runtime && state.dataService && state.enableShell) { - return { - ...state, - runtime: createWorkerRuntime(state.dataService, state.appRegistry!), - }; - } else if (state.runtime && (!state.dataService || !state.enableShell)) { - void state.runtime.terminate(); - return { - ...state, - runtime: null, - }; - } - return { ...state }; -} - -function reduceSetupRuntime( - state: RuntimeState, - action: SetupRuntimeAction -): RuntimeState { - return createOrDestroyRuntimeForState({ - ...state, - error: action.error, - dataService: action.error ? null : action.dataService, - appRegistry: action.error ? null : action.appRegistry, - }); -} - -function reduceChangeEnableShell( - state: RuntimeState, - action: ChangeEnableShellAction -): RuntimeState { - return createOrDestroyRuntimeForState({ - ...state, - enableShell: action.enableShell, - }); -} - -/** - * Setup the shell runtime with the supplied dataService instance. - * - * @param {Error} error - The connection error. - * @param {DataService} dataService - The data service. - * @param {EventEmitter} appRegistry - A message bus for runtime events. - * - * @returns {Object} The data service connected action. - */ -export const setupRuntime = ( - error: Error | null, - dataService: DataService | null, - appRegistry: AppRegistry | null -) => ({ - type: SETUP_RUNTIME, - error, - dataService, - appRegistry, -}); - -export const changeEnableShell = ( - enableShell: boolean -): ChangeEnableShellAction => ({ - type: CHANGE_ENABLE_SHELL, - enableShell, -}); - -function createWorkerRuntime( - dataService: DataService, - appRegistry: AppRegistry -): typeof WorkerRuntime['prototype'] { - const { - url: driverUrl, - options: driverOptions, - // Not really provided by dataService, used only for testing purposes - cliOptions, - } = { - cliOptions: {}, - url: '', - ...dataService.getMongoClientConnectionOptions(), - }; - - return new WorkerRuntime( - driverUrl, - driverOptions, - cliOptions ?? {}, - { - env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' }, - serialization: 'advanced', - }, - appRegistry - ); -} diff --git a/packages/compass-shell/src/modules/worker-runtime.ts b/packages/compass-shell/src/modules/worker-runtime.ts index 93eefc2cd4b..ec875d90358 100644 --- a/packages/compass-shell/src/modules/worker-runtime.ts +++ b/packages/compass-shell/src/modules/worker-runtime.ts @@ -1,3 +1,12 @@ +import type { + ConnectionInfoAccess, + DataService, +} from '@mongodb-js/compass-connections/provider'; +import type { MongoLogWriter } from '@mongodb-js/compass-logging/provider'; +import type { TrackFunction } from '@mongodb-js/compass-telemetry/provider'; +import { setupLoggerAndTelemetry } from '@mongosh/logging'; +import { EventEmitter } from 'events'; + declare const __webpack_require__: typeof require; declare const __non_webpack_require__: typeof require; @@ -34,3 +43,69 @@ const { WorkerRuntime } = (() => { })() as typeof import('@mongosh/node-runtime-worker-thread'); export { WorkerRuntime }; + +export function createWorkerRuntime( + dataService: DataService, + log: MongoLogWriter, + track: TrackFunction, + connectionInfo: ConnectionInfoAccess +): typeof WorkerRuntime['prototype'] { + const emitter = new EventEmitter(); + + setupLoggerAndTelemetry( + emitter, + log, + { + identify: () => { + /* not needed */ + }, + // Prefix Segment events with `Shell ` to avoid event name collisions. + // We always enable telemetry here, since the track call will + // already check whether Compass telemetry is enabled or not. + track: ({ event, properties }) => { + return track( + `Shell ${event}`, + properties, + connectionInfo.getCurrentConnectionInfo() + ); + }, + flush: () => { + return Promise.resolve(); // not needed + }, + }, + { + platform: process.platform, + arch: process.arch, + }, + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-var-requires + require('../../package.json').version + ); + + // We also don't need to pass a proper user id, since that is + // handled by the Compass tracking code. + emitter.emit('mongosh:new-user', ''); + + const { + url: driverUrl, + options: driverOptions, + // Not really provided by dataService, used only for testing purposes + cliOptions, + } = { + cliOptions: {}, + url: '', + ...dataService.getMongoClientConnectionOptions(), + }; + + const runtime = new WorkerRuntime( + driverUrl, + driverOptions, + cliOptions ?? {}, + { + env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' }, + serialization: 'advanced', + }, + emitter + ); + + return runtime; +} diff --git a/packages/compass-shell/src/plugin.spec.tsx b/packages/compass-shell/src/plugin.spec.tsx index e1c9841af59..a4e98309ad7 100644 --- a/packages/compass-shell/src/plugin.spec.tsx +++ b/packages/compass-shell/src/plugin.spec.tsx @@ -6,7 +6,7 @@ import { expect } from 'chai'; import { CompassShell } from './components/compass-shell'; import { CompassShellPlugin } from './index'; -import { AppRegistryProvider, globalAppRegistry } from 'hadron-app-registry'; +import { AppRegistryProvider } from 'hadron-app-registry'; import { ConnectionsManager, ConnectionsManagerProvider, @@ -51,6 +51,7 @@ describe('CompassShellPlugin', function () { const connectionsManager = new ConnectionsManager({ logger: createNoopLogger().log.unbound, }); + sinon.replace(connectionsManager, 'getDataServiceForConnection', () => { return fakeDataService; }); @@ -61,8 +62,9 @@ describe('CompassShellPlugin', function () { wrapper?.unmount(); wrapper = null; }); + it('returns a renderable plugin', async function () { - (connectionsManager as any).connectionStatuses.set('1', 'connected'); + connectionsManager['connectionStatuses'].set('1', 'connected'); wrapper = mount( {/* global */} @@ -85,40 +87,4 @@ describe('CompassShellPlugin', function () { expect(component?.exists()).to.equal(true); }); - - it('emits an event on the app registry when it is expanded', async function () { - let eventOccured = false; - globalAppRegistry.on('compass:compass-shell:opened', () => { - eventOccured = true; - }); - (connectionsManager as any).connectionStatuses.set('1', 'connected'); - - wrapper = mount( - - {/* global */} - - {/* local */} - - - - - - - - - - ); - - const shellComponentWrapper = await waitForAsyncComponent( - wrapper, - CompassShell - ); - - const { emitShellPluginOpened } = shellComponentWrapper?.props() ?? {}; - emitShellPluginOpened?.(); - - expect(eventOccured).to.equal(true); - }); }); diff --git a/packages/compass-shell/src/plugin.tsx b/packages/compass-shell/src/plugin.tsx index dde2755e21d..24400fe298b 100644 --- a/packages/compass-shell/src/plugin.tsx +++ b/packages/compass-shell/src/plugin.tsx @@ -1,91 +1,106 @@ -import React, { useState, useRef, useEffect } from 'react'; -import CompassShellStore from './stores'; +import React from 'react'; +import thunk from 'redux-thunk'; import { HistoryStorage } from './modules/history-storage'; -import type CompassShellComponentType from './components/compass-shell'; -import type AppRegistry from 'hadron-app-registry'; -import { - createLoggerLocator, - type Logger, -} from '@mongodb-js/compass-logging/provider'; -import type { DataService } from '@mongodb-js/compass-connections/provider'; +import { type Logger } from '@mongodb-js/compass-logging/provider'; +import type { + ConnectionInfoAccess, + DataService, +} from '@mongodb-js/compass-connections/provider'; import type { PreferencesAccess } from 'compass-preferences-model'; import { usePreference } from 'compass-preferences-model/provider'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import TabShell from './components/compass-shell/tab-compass-shell'; +import Shell from './components/compass-shell/compass-shell'; +import { applyMiddleware, createStore } from 'redux'; +import reducer, { + createAndStoreRuntime, + createRuntime, + destroyCurrentRuntime, + loadHistory, +} from './stores/store'; +import type { ActivateHelpers } from 'hadron-app-registry'; +import { Theme, ThemeProvider } from '@mongodb-js/compass-components'; -export function ShellPlugin() { +const SHELL_THEME = { theme: Theme.Dark, enabled: true }; + +type ShellPluginProps = { + initialEvaluate?: string | string[]; + initialInput?: string; +}; + +export function ShellPlugin(props: ShellPluginProps) { const multiConnectionsEnabled = usePreference( 'enableNewMultipleConnectionSystem' ); - const [ShellComponent, setShellComponent] = useState< - typeof CompassShellComponentType | null - >(null); - const historyStorage = useRef(null); + const ShellComponent = multiConnectionsEnabled ? TabShell : Shell; + return ( + + + + ); +} - if (!historyStorage.current) { - historyStorage.current = new HistoryStorage(); - } +export type ShellPluginServices = { + logger: Logger; + track: TrackFunction; + dataService: DataService; + preferences: PreferencesAccess; + connectionInfo: ConnectionInfoAccess; +}; - useEffect(() => { - let mounted = true; - async function importShellComponent() { - let component: typeof CompassShellComponentType | null = null; - try { - if (multiConnectionsEnabled) { - component = ( - await import('./components/compass-shell/tab-compass-shell') - ).default; - } else { - component = (await import('./components/compass-shell/compass-shell')) - .default; - } - } finally { - if (mounted) { - setShellComponent(component); - } - } - } +export type ShellPluginExtraArgs = ShellPluginServices & { + historyStorage: HistoryStorage; +}; - void importShellComponent(); +export function onActivated( + _initialProps: ShellPluginProps, + services: ShellPluginServices, + { addCleanup, cleanup }: ActivateHelpers +) { + const { preferences, dataService, logger, track, connectionInfo } = services; - return () => { - mounted = false; - }; - }, [multiConnectionsEnabled]); + const store = createStore( + reducer, + { + runtimeId: preferences.getPreferences().enableShell + ? createAndStoreRuntime(dataService, logger, track, connectionInfo).id + : null, + history: null, + }, + applyMiddleware( + thunk.withExtraArgument({ + ...services, + historyStorage: new HistoryStorage(), + }) + ) + ); - if (ShellComponent) { - return ; - } + setTimeout(() => { + void store.dispatch(loadHistory()); + }); - return null; -} + addCleanup( + preferences.onPreferenceValueChanged('enableShell', (enabled) => { + if (enabled) { + store.dispatch(createRuntime()); + } else { + store.dispatch(destroyCurrentRuntime()); + } + }) + ); -export function onActivated( - _: unknown, - { - globalAppRegistry, - logger, - track, - dataService, - preferences, - }: { - globalAppRegistry: AppRegistry; - logger: Logger; - track: TrackFunction; - dataService: DataService; - preferences: PreferencesAccess; + function destroyRuntime() { + store.dispatch(destroyCurrentRuntime()); } -) { - const store = new CompassShellStore(); - const deactivate = store.onActivated({ - globalAppRegistry, - logger, - track, - dataService, - preferences, + + addCleanup(destroyRuntime); + + // Trigger terminate when page unloads to kill the spawned child process + window.addEventListener('beforeunload', destroyRuntime); + + addCleanup(() => { + window.removeEventListener('beforeunload', destroyRuntime); }); - return { - store: store.reduxStore, - deactivate, - logger: createLoggerLocator('COMPASS-SHELL'), - }; + + return { store, deactivate: cleanup }; } diff --git a/packages/compass-shell/src/stores/index.ts b/packages/compass-shell/src/stores/index.ts deleted file mode 100644 index f44c9f34f50..00000000000 --- a/packages/compass-shell/src/stores/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import CompassShellStore from './store'; - -export default CompassShellStore; -export { CompassShellStore }; diff --git a/packages/compass-shell/src/stores/store.spec.ts b/packages/compass-shell/src/stores/store.spec.ts deleted file mode 100644 index 4966df1d300..00000000000 --- a/packages/compass-shell/src/stores/store.spec.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { EventEmitter } from 'events'; -import { expect } from 'chai'; - -import { WorkerRuntime } from '../modules/worker-runtime'; -import CompassShellStore from './'; -import { createNoopLogger } from '@mongodb-js/compass-logging/provider'; -import { createSandboxFromDefaultPreferences } from 'compass-preferences-model'; - -function createMockDataService() { - return { - getMongoClientConnectionOptions() { - return { - url: 'mongodb://nodb/', - options: {}, - cliOptions: { nodb: true }, - }; - }, - }; -} - -describe('CompassShellStore [Store]', function () { - let store: CompassShellStore; - let appRegistry: EventEmitter; - let deactivate: () => void; - - const getRuntimeState = () => store.reduxStore.getState().runtime; - - beforeEach(async function () { - store = new CompassShellStore(); - appRegistry = new EventEmitter(); - deactivate = store.onActivated({ - globalAppRegistry: appRegistry, - logger: createNoopLogger('COMPASS-SHELL'), - dataService: createMockDataService(), - preferences: await createSandboxFromDefaultPreferences(), - } as any); - }); - - afterEach(async function () { - const { runtime } = getRuntimeState(); - - await runtime?.terminate(); - }); - - describe('appRegistry', function () { - it('sets the global appRegistry', function () { - expect(store.reduxStore.getState().runtime.appRegistry).to.not.equal( - null - ); - expect(store.reduxStore.getState().runtime.appRegistry).to.be.instanceOf( - EventEmitter - ); - }); - }); - - describe('runtime', function () { - it('sets runtime on data-service-connected', function () { - let runtimeState = getRuntimeState(); - - expect(runtimeState.error).to.equal(null); - expect(runtimeState.runtime).to.be.instanceOf(WorkerRuntime); - - store.onEnableShellChanged(false); - runtimeState = getRuntimeState(); - - expect(runtimeState.error).to.equal(null); - expect(runtimeState.runtime).to.equal(null); - }); - - it('emits mongosh events to the appRegistry', async function () { - store.onEnableShellChanged(true); - let eventReceived = false; - appRegistry.on('mongosh:setCtx', () => { - eventReceived = true; - }); - - const runtimeState = getRuntimeState(); - - // Any command will do, just making sure we waited for the runtime to - // become available - await runtimeState.runtime?.evaluate('help'); - - expect(eventReceived).to.equal(true); - }); - - it('does not change state if dataService is the same', function () { - const fakeDataService = createMockDataService(); - - appRegistry.emit('data-service-connected', null, fakeDataService); - const runtimeState1 = getRuntimeState(); - - appRegistry.emit('data-service-connected', null, fakeDataService); - const runtimeState2 = getRuntimeState(); - - expect(runtimeState1).to.deep.equal(runtimeState2); - }); - - it('resets the runtime on deactivate', function () { - deactivate(); - const runtimeState = getRuntimeState(); - - expect(runtimeState.runtime).to.equal(null); - }); - }); -}); diff --git a/packages/compass-shell/src/stores/store.ts b/packages/compass-shell/src/stores/store.ts index a1166ffbe0a..f4c60a52abd 100644 --- a/packages/compass-shell/src/stores/store.ts +++ b/packages/compass-shell/src/stores/store.ts @@ -1,87 +1,164 @@ -import type { Store } from 'redux'; -import { createStore } from 'redux'; -import type { RootAction, RootState } from '../modules'; -import reducer from '../modules'; -import { changeEnableShell, setupRuntime } from '../modules/runtime'; -import { setupLoggerAndTelemetry } from '@mongosh/logging'; -import type { Logger } from '@mongodb-js/compass-logging/provider'; -import type { PreferencesAccess } from 'compass-preferences-model'; -import type AppRegistry from 'hadron-app-registry'; -import type { DataService } from '@mongodb-js/compass-connections/provider'; -import type { TrackFunction } from '@mongodb-js/compass-telemetry'; - -export default class CompassShellStore { - reduxStore: Store; - - constructor() { - this.reduxStore = createStore(reducer); - } +import type { Reducer } from 'redux'; +import type { AnyAction } from 'redux'; +import type { ThunkAction } from 'redux-thunk'; +import type { WorkerRuntime } from '@mongosh/node-runtime-worker-thread'; +import { ObjectId } from 'bson'; +import { createWorkerRuntime } from '../modules/worker-runtime'; +import type { ShellPluginExtraArgs } from '../plugin'; - globalAppRegistry: AppRegistry | null = null; - preferences: PreferencesAccess | null = null; +const RuntimeMap = new Map(); - onActivated({ - globalAppRegistry, - logger: { log, debug }, - track, - dataService, - preferences, - }: { - globalAppRegistry: AppRegistry; - logger: Logger; - track: TrackFunction; - dataService: DataService; - preferences: PreferencesAccess; - }): () => void { - debug('activated'); - - this.globalAppRegistry = globalAppRegistry; - this.preferences = preferences; - - const unsubscribePreference = preferences.onPreferenceValueChanged( - 'enableShell', - this.onEnableShellChanged - ); - this.onEnableShellChanged(preferences.getPreferences().enableShell); - - setupLoggerAndTelemetry( - globalAppRegistry, - log.unbound, - { - identify: () => { - /* not needed */ - }, - // Prefix Segment events with `Shell ` to avoid event name collisions. - // We always enable telemetry here, since the track call will - // already check whether Compass telemetry is enabled or not. - track: ({ event, properties }) => track(`Shell ${event}`, properties), - flush: () => { - return Promise.resolve(); // not needed - }, - }, - { - platform: process.platform, - arch: process.arch, - }, - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-var-requires - require('../../package.json').version - ); - // We also don't need to pass a proper user id, since that is - // handled by the Compass tracking code. - globalAppRegistry.emit('mongosh:new-user', ''); +type State = { + // Reference to the shell runtime stored by id + runtimeId: string | null; + history: string[] | null; +}; - // Set the global app registry in the store. - this.reduxStore.dispatch( - setupRuntime(null, dataService, this.globalAppRegistry) - ); +type ShellPluginThunkAction = ThunkAction< + R, + State, + ShellPluginExtraArgs, + A +>; + +enum ActionTypes { + RuntimeCreated = 'compass-shell/RuntimeCreated', + RuntimeDestroyed = 'compass-shell/RuntimeDestroyed', + HistoryLoaded = 'compass-shell/HistoryLoaded', + HistorySaved = 'compass-shell/HistorySaved', +} + +type RuntimeCreatedAction = { type: ActionTypes.RuntimeCreated; id: string }; + +type RuntimeDestroyedAction = { type: ActionTypes.RuntimeDestroyed }; - return () => { - unsubscribePreference(); - this.reduxStore.dispatch(setupRuntime(null, null, null)); +type HistoryLoadedAction = { + type: ActionTypes.HistoryLoaded; + history: string[]; +}; + +type HistorySavedAction = { + type: ActionTypes.HistorySaved; + history: string[]; +}; + +export function isAction
( + action: AnyAction, + type: A['type'] +): action is A { + return action.type === type; +} + +const reducer: Reducer = ( + state = { runtimeId: null, history: null }, + action +) => { + if (isAction(action, ActionTypes.RuntimeCreated)) { + return { + ...state, + runtimeId: action.id, }; } + if (isAction(action, ActionTypes.RuntimeDestroyed)) { + return { + ...state, + runtimeId: null, + }; + } + if (isAction(action, ActionTypes.HistoryLoaded)) { + return { + ...state, + history: action.history, + }; + } + if (isAction(action, ActionTypes.HistorySaved)) { + return { + ...state, + history: action.history, + }; + } + return state; +}; + +export function createAndStoreRuntime( + dataService: ShellPluginExtraArgs['dataService'], + { log }: ShellPluginExtraArgs['logger'], + track: ShellPluginExtraArgs['track'], + connectionInfo: ShellPluginExtraArgs['connectionInfo'] +) { + const id = new ObjectId().toString(); + const runtime = createWorkerRuntime( + dataService, + log.unbound, + track, + connectionInfo + ); + RuntimeMap.set(id, runtime); + return { id, runtime }; +} + +export function createRuntime(): ShellPluginThunkAction< + void, + RuntimeCreatedAction +> { + return ( + dispatch, + getState, + { dataService, logger, track, connectionInfo } + ) => { + // Do not allow to re-create runtime multiple times if it already exists + if (RuntimeMap.get(getState().runtimeId ?? '')) { + return; + } + const { id } = createAndStoreRuntime( + dataService, + logger, + track, + connectionInfo + ); + dispatch({ type: ActionTypes.RuntimeCreated, id }); + }; +} - onEnableShellChanged = (value: boolean) => { - this.reduxStore.dispatch(changeEnableShell(value)); +export function destroyCurrentRuntime(): ShellPluginThunkAction< + void, + RuntimeDestroyedAction +> { + return (dispatch, getState) => { + const id = getState().runtimeId ?? ''; + const runtime = RuntimeMap.get(id); + runtime?.['eventEmitter'].removeAllListeners(); + void runtime?.terminate(); + RuntimeMap.delete(id); + dispatch({ type: ActionTypes.RuntimeDestroyed }); }; } + +export function loadHistory(): ShellPluginThunkAction< + Promise, + HistoryLoadedAction +> { + return async (dispatch, _getState, { historyStorage }) => { + const history = await historyStorage.load(); + dispatch({ type: ActionTypes.HistoryLoaded, history }); + }; +} + +export function saveHistory( + newHistory: string[] +): ShellPluginThunkAction { + return (dispatch, _getState, { historyStorage }) => { + void historyStorage.save(newHistory).catch(() => { + // ignore saving errors + }); + dispatch({ type: ActionTypes.HistorySaved, history: newHistory }); + }; +} + +export const selectRuntimeById = (state: State) => { + return RuntimeMap.get(state.runtimeId ?? '') ?? null; +}; + +export type RootState = State; + +export default reducer; diff --git a/packages/compass-sidebar/package.json b/packages/compass-sidebar/package.json index 85a4ec784f8..529f974a273 100644 --- a/packages/compass-sidebar/package.json +++ b/packages/compass-sidebar/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "5.33.0", + "version": "5.36.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,23 +48,23 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connection-import-export": "^0.29.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-connections-navigation": "^1.32.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-maybe-protect-connection-string": "^0.21.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-form": "^1.31.0", - "@mongodb-js/connection-info": "^0.4.1", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connection-import-export": "^0.32.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-connections-navigation": "^1.35.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-maybe-protect-connection-string": "^0.23.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-form": "^1.34.0", + "@mongodb-js/connection-info": "^0.5.1", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", - "mongodb-instance-model": "^12.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -72,8 +72,8 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -91,7 +91,7 @@ "electron-mocha": "^12.2.0", "eslint": "^7.25.0", "mocha": "^10.2.0", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "prettier": "^2.7.1", "react-dom": "^17.0.2", diff --git a/packages/compass-sidebar/src/components/legacy/sidebar-databases-navigation.tsx b/packages/compass-sidebar/src/components/legacy/sidebar-databases-navigation.tsx index 71599f848f0..1746cea22ad 100644 --- a/packages/compass-sidebar/src/components/legacy/sidebar-databases-navigation.tsx +++ b/packages/compass-sidebar/src/components/legacy/sidebar-databases-navigation.tsx @@ -52,7 +52,8 @@ const filterDatabases = ( results.push({ ...db, isMatch, - collections: childMatches.length ? childMatches : db.collections, + collections: + !isMatch && childMatches.length ? childMatches : db.collections, }); } } @@ -115,7 +116,7 @@ type MapStateProps = { }; type MapDispatchProps = { - fetchAllCollections(): void; + fetchAllCollections(connectionId: string): void; onNamespaceAction( connectionId: string, namespace: string, @@ -219,7 +220,7 @@ function SidebarDatabasesNavigation({ // When filtering, emit an event so that we can fetch all collections. This // is required as a workaround for the synchronous nature of the current // filtering feature - _fetchAllCollections(); + _fetchAllCollections(connectionId); const results = filterDatabases( databasesButOnlyIfFilterIsActive, @@ -229,6 +230,7 @@ function SidebarDatabasesNavigation({ temporarilyExpand(results); } }, [ + connectionId, filterRegex, databasesButOnlyIfFilterIsActive, setFilteredDatabases, diff --git a/packages/compass-sidebar/src/components/legacy/sidebar.tsx b/packages/compass-sidebar/src/components/legacy/sidebar.tsx index eba38f4e10c..4a1179c047a 100644 --- a/packages/compass-sidebar/src/components/legacy/sidebar.tsx +++ b/packages/compass-sidebar/src/components/legacy/sidebar.tsx @@ -150,6 +150,13 @@ export function Sidebar({ return; } + if (action === 'refresh-databases') { + onSidebarAction(action, ...rest, { + connectionId: initialConnectionInfo.id, + }); + return; + } + onSidebarAction(action, ...rest); }, [ diff --git a/packages/compass-sidebar/src/components/multiple-connections/connections-navigation.tsx b/packages/compass-sidebar/src/components/multiple-connections/connections-navigation.tsx index f599bf4a9a1..69c81896a3c 100644 --- a/packages/compass-sidebar/src/components/multiple-connections/connections-navigation.tsx +++ b/packages/compass-sidebar/src/components/multiple-connections/connections-navigation.tsx @@ -131,6 +131,7 @@ type MapStateProps = { type MapDispatchProps = { fetchAllCollections(): void; onDatabaseExpand(connectionId: string, dbId: string): void; + onRefreshDatabases(connectionId: string): void; onNamespaceAction( connectionId: string, namespace: string, @@ -164,6 +165,7 @@ const ConnectionsNavigation: React.FC = ({ onDisconnect, onDatabaseExpand, fetchAllCollections, + onRefreshDatabases: _onRefreshDatabases, onNamespaceAction: _onNamespaceAction, }) => { const { @@ -281,6 +283,9 @@ const ConnectionsNavigation: React.FC = ({ case 'select-connection': openDatabasesWorkspace(item.connectionInfo.id); return; + case 'refresh-databases': + _onRefreshDatabases(item.connectionInfo.id); + return; case 'create-database': _onNamespaceAction(item.connectionInfo.id, '', action); return; @@ -326,6 +331,7 @@ const ConnectionsNavigation: React.FC = ({ } }, [ + _onRefreshDatabases, _onNamespaceAction, openShellWorkspace, openDatabasesWorkspace, @@ -497,6 +503,12 @@ const ConnectionsNavigation: React.FC = ({ ); }; +const onRefreshDatabases = (connectionId: string): SidebarThunkAction => { + return (_dispatch, getState, { globalAppRegistry }) => { + globalAppRegistry.emit('refresh-databases', { connectionId }); + }; +}; + const onNamespaceAction = ( connectionId: string, namespace: string, @@ -567,6 +579,7 @@ const mapDispatchToProps: MapDispatchToProps< MapDispatchProps, ConnectionsNavigationComponentProps > = { + onRefreshDatabases, onNamespaceAction, onDatabaseExpand, fetchAllCollections, diff --git a/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx b/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx index 04eb4f19759..22149507052 100644 --- a/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx +++ b/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx @@ -63,7 +63,7 @@ function andSucceed(): PromiseFunction { const savedFavoriteConnection: ConnectionInfo = { id: '12345', connectionOptions: { - connectionString: 'mongodb://localhost:27017', + connectionString: 'mongodb://localhost:12345/', }, favorite: { name: 'localhost', @@ -75,7 +75,7 @@ const savedFavoriteConnection: ConnectionInfo = { const savedRecentConnection: ConnectionInfo = { id: '54321', connectionOptions: { - connectionString: 'mongodb://localhost:27020', + connectionString: 'mongodb://localhost:27020/', }, }; @@ -619,6 +619,18 @@ describe('Multiple Connections Sidebar Component', function () { expect(disconnectSpy).to.be.calledWith(savedFavoriteConnection.id); }); + it('should connect when the user tries to expand an inactive connection', async function () { + const connectSpy = sinon.spy(connectionsManager, 'connect'); + await renderWithConnections(); + const connectionItem = screen.getByTestId(savedRecentConnection.id); + + userEvent.click( + within(connectionItem).getByLabelText('Caret Right Icon') + ); + + expect(connectSpy).to.be.calledWith(savedRecentConnection); + }); + it('should open edit connection modal when clicked on edit connection action', function () { // note that we only click on non-connected item because for // connected item we cannot edit connection @@ -681,7 +693,7 @@ describe('Multiple Connections Sidebar Component', function () { }); }); - it('should duplicate connection when clicked on duplicate action', async function () { + it('should open a connection form when clicked on duplicate action', async function () { const saveSpy = sinon.spy(connectionStorage, 'save'); const connectionItem = screen.getByTestId( @@ -697,16 +709,18 @@ describe('Multiple Connections Sidebar Component', function () { userEvent.click(screen.getByText('Duplicate')); + // Does not save the duplicate yet await waitFor(() => { - expect(saveSpy).to.have.been.called; + expect(saveSpy).not.to.have.been.called; }); - await waitFor(() => { - // 3 connections and one database from the connected one - return expect(screen.getAllByRole('treeitem')).to.have.lengthOf( - 4 - ); - }); + // We see the connect button in the form modal + expect(screen.getByTestId('connect-button')).to.be.visible; + + // Connection string is pre-filled with a duplicate + expect(screen.getByTestId('connectionString')).to.have.value( + savedFavoriteConnection.connectionOptions.connectionString + ); }); it('should disconnect and remove the connection when clicked on remove action', async function () { diff --git a/packages/compass-sidebar/src/components/multiple-connections/sidebar.tsx b/packages/compass-sidebar/src/components/multiple-connections/sidebar.tsx index 7372ce31466..882c02063e8 100644 --- a/packages/compass-sidebar/src/components/multiple-connections/sidebar.tsx +++ b/packages/compass-sidebar/src/components/multiple-connections/sidebar.tsx @@ -28,7 +28,6 @@ import { import { getGenuineMongoDB } from 'mongodb-build-info'; import { SidebarHeader } from './header/sidebar-header'; import { ConnectionFormModal } from '@mongodb-js/connection-form'; -import { cloneDeep } from 'lodash'; import { usePreference } from 'compass-preferences-model/provider'; import { type RootState, type SidebarThunkAction } from '../../modules'; import { Navigation } from './navigation/navigation'; @@ -103,7 +102,7 @@ function ConnectionErrorToastBody({ }: ConnectionErrorToastBodyProps): React.ReactElement { return ( - + There was a problem connecting{' '} {info ? `to ${getConnectionTitle(info)}` : ''} @@ -112,6 +111,7 @@ function ConnectionErrorToastBody({ className={connectionErrorToastActionMessageStyles} hideExternalIcon={true} onClick={onReview} + data-testid="connection-error-review" > REVIEW @@ -207,8 +207,8 @@ export function MultipleConnectionSidebar({ cancelConnectionAttempt, removeConnection, saveConnection, - duplicateConnection, createNewConnection, + createDuplicateConnection, state: { activeConnectionId, activeConnectionInfo, connectionErrorMessage }, } = useConnections(); @@ -312,8 +312,8 @@ export function MultipleConnectionSidebar({ [openToast] ); - const onConnect = useCallback( - (info: ConnectionInfo) => { + const _onConnect = useCallback( + async (info: ConnectionInfo): Promise => { if (activeConnections.length >= maxConcurrentConnections) { onMaxConcurrentConnectionsLimitReached( activeConnections.length, @@ -324,7 +324,7 @@ export function MultipleConnectionSidebar({ } setActiveConnectionById(info.id); onConnectionAttemptStarted(info); - void connect(info).then( + await connect(info).then( () => { onConnected(info); }, @@ -345,6 +345,13 @@ export function MultipleConnectionSidebar({ ] ); + const onConnect = useCallback( + (info: ConnectionInfo) => { + void _onConnect(info); + }, + [_onConnect] + ); + const onNewConnectionOpen = useCallback(() => { createNewConnection(); setIsConnectionFormOpen(true); @@ -362,11 +369,11 @@ export function MultipleConnectionSidebar({ const onNewConnectionConnect = useCallback( (connectionInfo: ConnectionInfo) => { - void connect({ - ...cloneDeep(connectionInfo), - }).then(() => setIsConnectionFormOpen(false)); + void _onConnect(connectionInfo).then(() => { + setIsConnectionFormOpen(false); + }); }, - [connect] + [_onConnect] ); const onSaveNewConnection = useCallback( @@ -394,10 +401,10 @@ export function MultipleConnectionSidebar({ const onDuplicateConnection = useCallback( (info: ConnectionInfo) => { - duplicateConnection(info); + createDuplicateConnection(info); setIsConnectionFormOpen(true); }, - [duplicateConnection, setIsConnectionFormOpen] + [setIsConnectionFormOpen, createDuplicateConnection] ); const onToggleFavoriteConnectionInfo = useCallback( diff --git a/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts b/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts index 5bd7935b390..ff02247291d 100644 --- a/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts +++ b/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts @@ -104,6 +104,13 @@ const sidebarConnections: SidebarConnection[] = [ sourceName: '', pipeline: [], }, + { + _id: 'coll_ready_2_2', + name: 'coll_ready_2_2', + type: 'collection', + sourceName: '', + pipeline: [], + }, ], collectionsLength: 1, collectionsStatus: 'ready', @@ -499,6 +506,40 @@ describe('useFilteredConnections', function () { }); }); + it('should not filter the database items if the parent is also a match', async function () { + const { result } = renderHookWithContext(useFilteredConnections, { + initialProps: { + connections: [ + { + ...mockSidebarConnections[0], + name: 'Matching connection', + databases: [ + { + ...(mockSidebarConnections[0] as SidebarConnectedConnection) + .databases[0], + name: 'Matching database', + }, + { + ...(mockSidebarConnections[0] as SidebarConnectedConnection) + .databases[1], + name: 'Another database', + }, + ], + } as SidebarConnectedConnection, + ], + filterRegex: new RegExp('Matching', 'i'), // this matches connection as well as database + fetchAllCollections: fetchAllCollectionsStub, + onDatabaseExpand: onDatabaseExpandStub, + }, + }); + + await waitFor(() => { + expect( + (result.current.filtered?.[0] as SidebarConnectedConnection).databases + ).to.have.length(2); // both databases are included + }); + }); + it('should match the collection items', async function () { const { result } = renderHookWithContext(useFilteredConnections, { initialProps: { @@ -516,17 +557,40 @@ describe('useFilteredConnections', function () { { ...matchedItem, // will only match the second database's collection - databases: [matchedItem.databases[0]], + databases: [ + { + ...matchedItem.databases[0], + collections: [matchedItem.databases[0].collections[0]], + }, + ], }, ]); }); }); + it('should not filter the collection items if the parent is also a match', async function () { + const { result } = renderHookWithContext(useFilteredConnections, { + initialProps: { + connections: mockSidebarConnections, + filterRegex: new RegExp('ready_2_1', 'i'), // this matches 1 database and 1 collection + fetchAllCollections: fetchAllCollectionsStub, + onDatabaseExpand: onDatabaseExpandStub, + }, + }); + + await waitFor(() => { + expect( + (result.current.filtered?.[0] as SidebarConnectedConnection) + .databases[0].collections + ).to.have.length(2); // the result has 2 collections + }); + }); + it('as expanded, it should return an object containing an expanded object for the matching items', async function () { const { result } = renderHookWithContext(useFilteredConnections, { initialProps: { connections: mockSidebarConnections, - filterRegex: new RegExp('_1_1', 'i'), + filterRegex: new RegExp('coll_ready_1_1', 'i'), fetchAllCollections: fetchAllCollectionsStub, onDatabaseExpand: onDatabaseExpandStub, }, @@ -568,7 +632,7 @@ describe('useFilteredConnections', function () { rerender({ connections: mockSidebarConnections, - filterRegex: new RegExp('_1_1', 'i'), + filterRegex: new RegExp('coll_ready_1_1', 'i'), fetchAllCollections: fetchAllCollectionsStub, onDatabaseExpand: onDatabaseExpandStub, }); @@ -591,7 +655,7 @@ describe('useFilteredConnections', function () { { initialProps: { connections: mockSidebarConnections, - filterRegex: new RegExp('_1_1', 'i'), + filterRegex: new RegExp('coll_ready_1_1', 'i'), fetchAllCollections: fetchAllCollectionsStub, onDatabaseExpand: onDatabaseExpandStub, }, @@ -630,7 +694,7 @@ describe('useFilteredConnections', function () { const { result } = renderHookWithContext(useFilteredConnections, { initialProps: { connections: mockSidebarConnections, - filterRegex: new RegExp('_1_1', 'i'), + filterRegex: new RegExp('coll_ready_1_1', 'i'), fetchAllCollections: fetchAllCollectionsStub, onDatabaseExpand: onDatabaseExpandStub, }, @@ -662,7 +726,7 @@ describe('useFilteredConnections', function () { const { result } = renderHookWithContext(useFilteredConnections, { initialProps: { connections: mockSidebarConnections, - filterRegex: new RegExp('_1_1', 'i'), + filterRegex: new RegExp('coll_ready_1_1', 'i'), fetchAllCollections: fetchAllCollectionsStub, onDatabaseExpand: onDatabaseExpandStub, }, @@ -700,7 +764,7 @@ describe('useFilteredConnections', function () { const { result } = renderHookWithContext(useFilteredConnections, { initialProps: { connections: mockSidebarConnections, - filterRegex: new RegExp('_1_1', 'i'), + filterRegex: new RegExp('coll_ready_1_1', 'i'), fetchAllCollections: fetchAllCollectionsStub, onDatabaseExpand: onDatabaseExpandStub, }, diff --git a/packages/compass-sidebar/src/components/use-filtered-connections.ts b/packages/compass-sidebar/src/components/use-filtered-connections.ts index 05dc466d7c4..dd583de519a 100644 --- a/packages/compass-sidebar/src/components/use-filtered-connections.ts +++ b/packages/compass-sidebar/src/components/use-filtered-connections.ts @@ -59,9 +59,10 @@ const filterConnections = ( isMatch, ...(connection.connectionStatus === ConnectionStatus.Connected ? { - databases: childMatches.length - ? childMatches - : connection.databases, + databases: + !isMatch && childMatches.length + ? childMatches + : connection.databases, } : {}), }); @@ -80,10 +81,21 @@ const filterDatabases = ( const childMatches = filterCollections(db.collections, regex); if (isMatch || childMatches.length) { + // If the db doesn't match, we want to use just the matching collections. + // if the db does match we include all the collections but we still record + // if they match because if something does match then we want to expand + // the database in temporarilyExpand below. + const collections = + !isMatch && childMatches.length + ? childMatches + : db.collections.map((collection) => ({ + ...collection, + isMatch: regex.test(collection.name), + })); results.push({ ...db, isMatch, - collections: childMatches.length ? childMatches : db.collections, + collections, }); } } @@ -127,7 +139,7 @@ const temporarilyExpand = ( } databases.forEach(({ _id: databaseId, collections }) => { const childrenCollsAreMatch = - collections.length && collections[0].isMatch; + collections.length && collections.some((col) => col.isMatch); if (childrenCollsAreMatch && collections.length) { if (newExpanded[connectionId].state === 'collapsed') { newExpanded[connectionId].state = 'tempExpanded'; diff --git a/packages/compass-sidebar/src/modules/databases.ts b/packages/compass-sidebar/src/modules/databases.ts index 8a05e0d6219..aafb967676b 100644 --- a/packages/compass-sidebar/src/modules/databases.ts +++ b/packages/compass-sidebar/src/modules/databases.ts @@ -118,10 +118,12 @@ export const changeDatabases = ( databases, }); +// Receives connectionId only to support filtering for single connections +// navigation tree export const fetchAllCollections = - (): SidebarThunkAction => + (connectionId?: string): SidebarThunkAction => (dispatch, getState, { globalAppRegistry }) => { - globalAppRegistry.emit('sidebar-filter-navigation-list'); + globalAppRegistry.emit('sidebar-filter-navigation-list', { connectionId }); dispatch({ type: FETCH_ALL_COLLECTIONS }); }; @@ -131,6 +133,8 @@ export const onDatabaseExpand = databaseId: string ): SidebarThunkAction => (dispatch, getState, { globalAppRegistry }) => { - globalAppRegistry.emit('sidebar-expand-database', connectionId, databaseId); + globalAppRegistry.emit('sidebar-expand-database', databaseId, { + connectionId, + }); dispatch({ type: EXPAND_DATABASE, connectionId, databaseId }); }; diff --git a/packages/compass-telemetry/package.json b/packages/compass-telemetry/package.json index 26e27439b8d..1ce537a1b16 100644 --- a/packages/compass-telemetry/package.json +++ b/packages/compass-telemetry/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.0.1", + "version": "1.1.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -52,13 +52,13 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "@mongodb-js/compass-logging": "^1.4.1", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-telemetry/src/generic-track.ts b/packages/compass-telemetry/src/generic-track.ts index 104206914e4..12ad1f7be3c 100644 --- a/packages/compass-telemetry/src/generic-track.ts +++ b/packages/compass-telemetry/src/generic-track.ts @@ -1,16 +1,17 @@ import { type Logger, mongoLogId } from '@mongodb-js/compass-logging/provider'; - -export type TrackProps = Record | (() => Record); -export type TrackFunction = (event: string, properties?: TrackProps) => void; +import type { TrackFunction, AsyncTrackFunction } from './types'; export interface TelemetryPreferences { getPreferences(): { trackUsageStatistics: boolean }; } +export type TelemetryConnectionInfoHook = () => { id: string }; + export interface TelemetryServiceOptions { - sendTrack: (event: string, properties: Record) => void; + sendTrack: TrackFunction; logger?: Logger; preferences?: TelemetryPreferences; + useConnectionInfo?: TelemetryConnectionInfoHook; } export const createTrack = ({ @@ -18,10 +19,11 @@ export const createTrack = ({ logger: { log, debug }, preferences, }: TelemetryServiceOptions & { logger: Logger }) => { - const trackAsync = async ( - event: string, - properties: TrackProps = {} - ): Promise => { + const trackAsync: AsyncTrackFunction = async ( + event, + parameters, + connectionInfo + ) => { // Note that this preferences check is mainly a performance optimization, // since the main process telemetry code also checks this preference value, // so it is safe to fall back to 'true'. @@ -31,9 +33,9 @@ export const createTrack = ({ return; } - if (typeof properties === 'function') { + if (typeof parameters === 'function') { try { - properties = await properties(); + parameters = await parameters(); } catch (error) { // When an error arises during the fetching of properties, // for instance if we can't fetch host information, @@ -55,10 +57,16 @@ export const createTrack = ({ return; } } - sendTrack(event, properties); + + if (typeof parameters === 'object' && connectionInfo) { + parameters.connection_id = connectionInfo.id; + } + + debug('sendTrack()', event, parameters); + sendTrack(event, parameters || {}); }; - const track = (...args: [string, TrackProps?]) => { + const track: TrackFunction = (...args) => { void Promise.resolve() .then(() => trackAsync(...args)) .catch((error) => debug('track failed', error)); diff --git a/packages/compass-telemetry/src/index.ts b/packages/compass-telemetry/src/index.ts index fd8acfc1230..36309c16853 100644 --- a/packages/compass-telemetry/src/index.ts +++ b/packages/compass-telemetry/src/index.ts @@ -1,2 +1,3 @@ export { createIpcTrack, createIpcSendTrack } from './ipc-track'; -export type { TrackFunction, TelemetryServiceOptions } from './generic-track'; +export type { TelemetryServiceOptions } from './generic-track'; +export type { TrackFunction, TrackParameters } from './types'; diff --git a/packages/compass-telemetry/src/ipc-track.ts b/packages/compass-telemetry/src/ipc-track.ts index 9cd530bf847..1165c7baa5d 100644 --- a/packages/compass-telemetry/src/ipc-track.ts +++ b/packages/compass-telemetry/src/ipc-track.ts @@ -1,11 +1,7 @@ import { type HadronIpcRenderer } from 'hadron-ipc'; -import { - type TelemetryPreferences, - type TrackFunction, - type TrackProps, - createTrack, -} from './generic-track'; +import { type TelemetryPreferences, createTrack } from './generic-track'; import { createLogger, type Logger } from '@mongodb-js/compass-logging'; +import type { TrackFunction } from './types'; function emit( ipc: HadronIpcRenderer | null | undefined, @@ -37,7 +33,7 @@ export function createIpcSendTrack() { // eslint-disable-next-line @typescript-eslint/no-var-requires require('hadron-ipc').ipcRenderer; - const sendTrack = (event: string, properties: TrackProps) => + const sendTrack: TrackFunction = (event, properties) => emit(ipc, 'compass:track', { event, properties }); return sendTrack; diff --git a/packages/compass-telemetry/src/provider.tsx b/packages/compass-telemetry/src/provider.tsx index 814beaf18ff..56905338cb8 100644 --- a/packages/compass-telemetry/src/provider.tsx +++ b/packages/compass-telemetry/src/provider.tsx @@ -1,11 +1,8 @@ import React, { useRef } from 'react'; import { createServiceLocator } from 'hadron-app-registry'; -import { - createTrack, - type TelemetryServiceOptions, - type TrackFunction, -} from './generic-track'; +import { createTrack, type TelemetryServiceOptions } from './generic-track'; import { useLogger } from '@mongodb-js/compass-logging/provider'; +import type { TrackFunction, TrackParameters } from './types'; const noop = () => { // noop @@ -36,12 +33,10 @@ export const TelemetryProvider: React.FC<{ ); }; -export function createTelemetryLocator() { - return createServiceLocator( - useTelemetry.bind(null), - 'createTelemetryLocator' - ); -} +export const telemetryLocator = createServiceLocator( + useTelemetry.bind(null), + 'telemetryLocator' +); export function useTelemetry(): TrackFunction { const track = React.useContext(TelemetryContext); @@ -57,7 +52,7 @@ type FirstArgument = F extends (...args: [infer A, ...any]) => any ? A : never; -export function withTelemetry< +function withTelemetry< T extends ((...args: any[]) => any) | { new (...args: any[]): any } >(ReactComponent: T): React.FunctionComponent, 'track'>> { const WithTelemetry = ( @@ -69,6 +64,8 @@ export function withTelemetry< return WithTelemetry; } +export { withTelemetry }; + /** * Hook that allows to track telemetry events as a side effect of dependencies changing. * @@ -79,7 +76,7 @@ export function withTelemetry< * * @example * useTrackOnChange((track) => { - * if (isShellOpen) { track('Shell Opened') } + * if (isShellOpen) { track('Shell Opened', {}, { id: 'connection123' }) } * }, [isShellOpen], { skipOnMount: true }); */ export function useTrackOnChange( @@ -100,4 +97,4 @@ export function useTrackOnChange( }, [...dependencies, track, options.skipOnMount]); } -export type { TrackFunction }; +export type { TrackFunction, TrackParameters }; diff --git a/packages/compass-telemetry/src/types.ts b/packages/compass-telemetry/src/types.ts new file mode 100644 index 00000000000..bfa97b7c370 --- /dev/null +++ b/packages/compass-telemetry/src/types.ts @@ -0,0 +1,22 @@ +export type EventsPayload = Record; + +export type TelemetryConnectionInfo = { + id: string; +}; + +export type TrackParameters = + | EventsPayload + | (() => Promise) + | (() => EventsPayload); + +export type TrackFunction = ( + event: string, + parameters?: TrackParameters, + connectionInfo?: TelemetryConnectionInfo +) => void; + +export type AsyncTrackFunction = ( + event: string, + parameters?: TrackParameters, + connectionInfo?: TelemetryConnectionInfo +) => Promise; diff --git a/packages/compass-test-server/package.json b/packages/compass-test-server/package.json index 3d962569400..f8b3005744a 100644 --- a/packages/compass-test-server/package.json +++ b/packages/compass-test-server/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.1.17", + "version": "0.1.18", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -53,7 +53,7 @@ "mongodb-runner": "^5.6.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-user-data/package.json b/packages/compass-user-data/package.json index a1b9dc3f8f2..b7a5a6b698b 100644 --- a/packages/compass-user-data/package.json +++ b/packages/compass-user-data/package.json @@ -12,7 +12,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.2.1", + "version": "0.3.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,13 +49,13 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-utils": "^0.6.7", "write-file-atomic": "^5.0.1", "zod": "^3.22.3" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-utils/package.json b/packages/compass-utils/package.json index 81ed35d986d..7a0a10a23da 100644 --- a/packages/compass-utils/package.json +++ b/packages/compass-utils/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.6.5", + "version": "0.6.7", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,7 +50,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -69,6 +69,6 @@ }, "dependencies": { "@electron/remote": "^2.1.2", - "electron": "^29.4.3" + "electron": "^29.4.5" } } diff --git a/packages/compass-web/package.json b/packages/compass-web/package.json index de139861d7e..09f73cc4129 100644 --- a/packages/compass-web/package.json +++ b/packages/compass-web/package.json @@ -14,7 +14,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.5.1", + "version": "0.5.5", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -62,32 +62,32 @@ "react-dom": "^17.0.2" }, "devDependencies": { - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-aggregations": "^9.35.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-databases-collections": "^1.32.0", - "@mongodb-js/compass-explain-plan": "^6.33.0", - "@mongodb-js/compass-export-to-language": "^9.9.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-indexes": "^5.32.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-schema": "^6.34.0", - "@mongodb-js/compass-schema-validation": "^6.33.0", - "@mongodb-js/compass-sidebar": "^5.33.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-aggregations": "^9.38.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-databases-collections": "^1.35.0", + "@mongodb-js/compass-explain-plan": "^6.36.0", + "@mongodb-js/compass-export-to-language": "^9.12.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-indexes": "^5.35.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-schema": "^6.37.0", + "@mongodb-js/compass-schema-validation": "^6.36.0", + "@mongodb-js/compass-sidebar": "^5.36.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/webpack-config-compass": "^1.3.11", + "@mongodb-js/webpack-config-compass": "^1.3.13", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", "@testing-library/user-event": "^13.5.0", @@ -102,23 +102,23 @@ "bson": "^6.2.0", "buffer": "^6.0.3", "chai": "^4.3.6", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "crypto-browserify": "^3.12.0", "debug": "^4.3.4", "depcheck": "^1.4.1", "dns-query": "^0.11.2", - "electron": "^29.4.3", + "electron": "^29.4.5", "eslint": "^7.25.0", "events": "^3.3.0", "express": "^4.19.2", "express-http-proxy": "^2.0.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "is-ip": "^5.0.1", "lodash": "^4.17.21", "mocha": "^10.2.0", "mongodb": "^6.7.0", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", + "mongodb-data-service": "^22.22.1", "nyc": "^15.1.0", "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", diff --git a/packages/compass-welcome/package.json b/packages/compass-welcome/package.json index 66a1f4d880d..bebc6248858 100644 --- a/packages/compass-welcome/package.json +++ b/packages/compass-welcome/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.31.0", + "version": "0.34.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,18 +49,18 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "react": "^17.0.2", "redux": "^4.2.1", "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-welcome/src/index.ts b/packages/compass-welcome/src/index.ts index 177ad6df9f0..0bbc98e3e57 100644 --- a/packages/compass-welcome/src/index.ts +++ b/packages/compass-welcome/src/index.ts @@ -4,11 +4,11 @@ import { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provide import type { WorkspaceComponent } from '@mongodb-js/compass-workspaces'; import { WelcomeModal, WelcomeTab } from './components'; import { activatePlugin } from './stores'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; const serviceLocators = { logger: createLoggerLocator('COMPASS-MY-QUERIES-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, workspaces: workspacesServiceLocator, }; diff --git a/packages/compass-workspaces/package.json b/packages/compass-workspaces/package.json index 3e8c3801f7f..b990d5bc9cb 100644 --- a/packages/compass-workspaces/package.json +++ b/packages/compass-workspaces/package.json @@ -11,7 +11,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.14.0", + "version": "0.17.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,15 +51,15 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-logging": "^1.4.1", "bson": "^6.7.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", "mongodb-ns": "^2.4.2", "react": "^17.0.2", "react-redux": "^8.1.3", @@ -67,7 +67,7 @@ "redux-thunk": "^2.4.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/compass-workspaces/src/components/workspaces.tsx b/packages/compass-workspaces/src/components/workspaces.tsx index c8d7ba259d6..435746eb5e3 100644 --- a/packages/compass-workspaces/src/components/workspaces.tsx +++ b/packages/compass-workspaces/src/components/workspaces.tsx @@ -161,18 +161,22 @@ const CompassWorkspaces: React.FunctionComponent = ({ case 'Welcome': return { id: tab.id, + type: tab.type, title: tab.type, iconGlyph: 'Logo', } as const; case 'My Queries': return { id: tab.id, + type: tab.type, title: tab.type, iconGlyph: 'CurlyBraces', } as const; case 'Shell': return { id: tab.id, + connectionName: getConnectionTitleById(tab.connectionId), + type: tab.type, title: getConnectionTitleById(tab.connectionId) ?? 'MongoDB Shell', iconGlyph: 'Shell', tabTheme: getThemeOf(tab.connectionId), @@ -180,6 +184,8 @@ const CompassWorkspaces: React.FunctionComponent = ({ case 'Databases': return { id: tab.id, + connectionName: getConnectionTitleById(tab.connectionId), + type: tab.type, title: tab.type, iconGlyph: 'Database', tabTheme: getThemeOf(tab.connectionId), @@ -187,6 +193,8 @@ const CompassWorkspaces: React.FunctionComponent = ({ case 'Performance': return { id: tab.id, + connectionName: getConnectionTitleById(tab.connectionId), + type: tab.type, title: tab.type, iconGlyph: 'Gauge', tabTheme: getThemeOf(tab.connectionId), @@ -194,6 +202,8 @@ const CompassWorkspaces: React.FunctionComponent = ({ case 'Collections': return { id: tab.id, + connectionName: getConnectionTitleById(tab.connectionId), + type: tab.type, title: tab.namespace, iconGlyph: 'Database', 'data-namespace': tab.namespace, @@ -218,6 +228,8 @@ const CompassWorkspaces: React.FunctionComponent = ({ : `${database} > ${collection}`; return { id: tab.id, + connectionName: getConnectionTitleById(tab.connectionId), + type: tab.type, title: collection, subtitle, iconGlyph: @@ -243,8 +255,17 @@ const CompassWorkspaces: React.FunctionComponent = ({ const Component = getWorkspacePluginByName(activeTab.type); return ; } - - case 'Shell': + case 'Shell': { + const Component = getWorkspacePluginByName(activeTab.type); + return ( + + + + ); + } case 'Performance': case 'Databases': { const Component = getWorkspacePluginByName(activeTab.type); diff --git a/packages/compass-workspaces/src/provider.tsx b/packages/compass-workspaces/src/provider.tsx index fa60a6ddfc8..463841f3497 100644 --- a/packages/compass-workspaces/src/provider.tsx +++ b/packages/compass-workspaces/src/provider.tsx @@ -48,7 +48,11 @@ export type WorkspacesService = { openShellWorkspace( this: void, connectionId: string, - tabOptions?: TabOptions + options?: TabOptions & + Pick< + Extract, + 'initialInput' | 'initialEvaluate' + > ): void; /** * Open "Databases" workspace showing list of all databases in the cluster @@ -237,9 +241,13 @@ export const WorkspacesServiceProvider: React.FunctionComponent<{ openWorkspaceAction({ type: 'My Queries' }, tabOptions) ); }, - openShellWorkspace(connectionId, tabOptions) { + openShellWorkspace(connectionId, options = {}) { + const { newTab, ...workspaceOptions } = options; return void store.dispatch( - openWorkspaceAction({ type: 'Shell', connectionId }, tabOptions) + openWorkspaceAction( + { type: 'Shell', connectionId, ...workspaceOptions }, + { newTab } + ) ); }, openDatabasesWorkspace: (connectionId, tabOptions) => { diff --git a/packages/compass-workspaces/src/stores/workspaces.ts b/packages/compass-workspaces/src/stores/workspaces.ts index ab48db3438c..2c6209cb277 100644 --- a/packages/compass-workspaces/src/stores/workspaces.ts +++ b/packages/compass-workspaces/src/stores/workspaces.ts @@ -599,7 +599,10 @@ export const getActiveTab = (state: WorkspacesState): WorkspaceTab | null => { export type OpenWorkspaceOptions = | Pick, 'type'> | Pick, 'type'> - | Pick, 'type' | 'connectionId'> + | Pick< + Workspace<'Shell'>, + 'type' | 'connectionId' | 'initialEvaluate' | 'initialInput' + > | Pick, 'type' | 'connectionId'> | Pick, 'type' | 'connectionId'> | Pick, 'type' | 'connectionId' | 'namespace'> diff --git a/packages/compass-workspaces/src/types.ts b/packages/compass-workspaces/src/types.ts index 82d710c06cc..c489c713b28 100644 --- a/packages/compass-workspaces/src/types.ts +++ b/packages/compass-workspaces/src/types.ts @@ -16,6 +16,8 @@ export type MyQueriesWorkspace = { export type ShellWorkspace = { type: 'Shell'; connectionId: string; + initialEvaluate?: string | string[]; + initialInput?: string; }; export type ServerStatsWorkspace = { diff --git a/packages/compass/package.json b/packages/compass/package.json index 97348d0de4e..438413bdc89 100644 --- a/packages/compass/package.json +++ b/packages/compass/package.json @@ -155,8 +155,10 @@ "generate-3rd-party-notices": "mongodb-sbom-tools generate-3rd-party-notices --product='Mongodb Compass' --dependencies=../../.sbom/dependencies.json > THIRD-PARTY-NOTICES.md", "postgenerate-3rd-party-notices": "prettier --write THIRD-PARTY-NOTICES.md", "run-compiled": "electron .", - "package-compass": "hadron-build release", - "package-compass-debug": "DEBUG='*' HADRON_SKIP_INSTALLER=true NO_ASAR=true hadron-build release", + "package-compass-nocompile": "hadron-build release", + "prepackage-compass": "npm run compile", + "package-compass": "npm run package-compass-nocompile", + "package-compass-debug": "DEBUG='*' HADRON_SKIP_INSTALLER=true NO_ASAR=true npm run package-compass", "upload": "hadron-build upload", "download": "hadron-build download", "evergreen-expansions": "hadron-build info --format=yaml --flatten > expansions.yml", @@ -179,58 +181,58 @@ "email": "compass@mongodb.com" }, "dependencies": { - "@mongosh/node-runtime-worker-thread": "^2.2.10", + "@mongosh/node-runtime-worker-thread": "^2.2.12", "clipboard": "^2.0.6", "kerberos": "^2.1.0", "keytar": "^7.9.0", "mongodb-client-encryption": "^6.0.0", "os-dns-native": "^1.2.1", - "system-ca": "^1.0.3" + "system-ca": "^2.0.0" }, "devDependencies": { "@electron/rebuild": "^3.6.0", "@electron/remote": "^2.1.2", - "@mongodb-js/atlas-service": "^0.22.0", - "@mongodb-js/compass-aggregations": "^9.35.0", - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-collection": "^4.32.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-connection-import-export": "^0.29.0", - "@mongodb-js/compass-crud": "^13.33.0", - "@mongodb-js/compass-databases-collections": "^1.32.0", - "@mongodb-js/compass-explain-plan": "^6.33.0", - "@mongodb-js/compass-export-to-language": "^9.9.0", - "@mongodb-js/compass-field-store": "^9.8.0", - "@mongodb-js/compass-find-in-page": "^4.26.0", - "@mongodb-js/compass-generative-ai": "^0.16.0", - "@mongodb-js/compass-import-export": "^7.32.0", - "@mongodb-js/compass-indexes": "^5.32.0", - "@mongodb-js/compass-intercom": "^0.7.1", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-query-bar": "^8.34.0", - "@mongodb-js/compass-saved-aggregations-queries": "^1.33.0", - "@mongodb-js/compass-schema": "^6.34.0", - "@mongodb-js/compass-schema-validation": "^6.33.0", - "@mongodb-js/compass-serverstats": "^16.32.0", - "@mongodb-js/compass-settings": "^0.34.0", - "@mongodb-js/compass-shell": "^3.32.0", - "@mongodb-js/compass-sidebar": "^5.33.0", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/compass-welcome": "^0.31.0", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/connection-storage": "^0.14.1", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/atlas-service": "^0.25.0", + "@mongodb-js/compass-aggregations": "^9.38.0", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-collection": "^4.35.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-connection-import-export": "^0.32.0", + "@mongodb-js/compass-crud": "^13.36.0", + "@mongodb-js/compass-databases-collections": "^1.35.0", + "@mongodb-js/compass-explain-plan": "^6.36.0", + "@mongodb-js/compass-export-to-language": "^9.12.0", + "@mongodb-js/compass-field-store": "^9.11.0", + "@mongodb-js/compass-find-in-page": "^4.29.0", + "@mongodb-js/compass-generative-ai": "^0.19.0", + "@mongodb-js/compass-import-export": "^7.35.0", + "@mongodb-js/compass-indexes": "^5.35.0", + "@mongodb-js/compass-intercom": "^0.9.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-query-bar": "^8.37.0", + "@mongodb-js/compass-saved-aggregations-queries": "^1.36.0", + "@mongodb-js/compass-schema": "^6.37.0", + "@mongodb-js/compass-schema-validation": "^6.36.0", + "@mongodb-js/compass-serverstats": "^16.35.0", + "@mongodb-js/compass-settings": "^0.37.0", + "@mongodb-js/compass-shell": "^3.35.0", + "@mongodb-js/compass-sidebar": "^5.36.0", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/compass-welcome": "^0.34.0", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/connection-storage": "^0.16.0", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/get-os-info": "^0.3.24", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/mongodb-downloader": "^0.3.0", - "@mongodb-js/my-queries-storage": "^0.10.0", + "@mongodb-js/my-queries-storage": "^0.13.0", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/sbom-tools": "^0.7.0", "@mongodb-js/tsconfig-compass": "^1.0.4", - "@mongodb-js/webpack-config-compass": "^1.3.11", + "@mongodb-js/webpack-config-compass": "^1.3.13", "@segment/analytics-node": "^1.1.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -238,19 +240,19 @@ "chai": "^4.3.4", "chalk": "^4.1.2", "clean-stack": "^2.0.0", - "compass-preferences-model": "^2.23.1", + "compass-preferences-model": "^2.25.0", "debug": "^4.3.4", "depcheck": "^1.4.1", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-devtools-installer": "^3.2.0", "electron-dl": "^3.5.0", "electron-mocha": "^12.2.0", "electron-squirrel-startup": "^1.0.1", "ensure-error": "^3.0.1", "eslint": "^7.25.0", - "hadron-app-registry": "^9.1.12", - "hadron-build": "^25.5.3", - "hadron-ipc": "^3.2.16", + "hadron-app-registry": "^9.2.1", + "hadron-build": "^25.5.5", + "hadron-ipc": "^3.2.18", "local-links": "^1.4.0", "make-fetch-happen": "^8.0.14", "marky": "^1.2.1", @@ -258,8 +260,8 @@ "mongodb-build-info": "^1.7.2", "mongodb-cloud-info": "^2.1.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-log-writer": "^1.4.2", "mongodb-ns": "^2.4.2", "node-fetch": "^2.7.0", @@ -275,6 +277,6 @@ }, "optionalDependencies": { "macos-export-certificate-and-key": "^1.1.2", - "win-export-certificate-and-key": "^1.1.2" + "win-export-certificate-and-key": "^2.0.1" } } diff --git a/packages/compass/src/app/components/entrypoint.tsx b/packages/compass/src/app/components/entrypoint.tsx index 100977886e4..c263e42c6a9 100644 --- a/packages/compass/src/app/components/entrypoint.tsx +++ b/packages/compass/src/app/components/entrypoint.tsx @@ -25,8 +25,10 @@ import { LoggerProvider } from '@mongodb-js/compass-logging/provider'; import { TelemetryProvider } from '@mongodb-js/compass-telemetry/provider'; import { getAppName, getAppVersion } from '@mongodb-js/compass-utils'; import Home, { type HomeProps } from './home'; -import { createIpcSendTrack } from '@mongodb-js/compass-telemetry'; -import type { TelemetryServiceOptions } from '@mongodb-js/compass-telemetry/dist/generic-track'; +import { + type TelemetryServiceOptions, + createIpcSendTrack, +} from '@mongodb-js/compass-telemetry'; const WithPreferencesAndLoggerProviders: React.FC = ({ children }) => { const loggerProviderValue = useRef({ diff --git a/packages/compass/src/app/utils/telemetry.spec.ts b/packages/compass/src/app/utils/telemetry.spec.ts index f46f86eec60..0bf9b63aa68 100644 --- a/packages/compass/src/app/utils/telemetry.spec.ts +++ b/packages/compass/src/app/utils/telemetry.spec.ts @@ -35,6 +35,13 @@ const dataService: Pick = { getCurrentTopologyType: () => 'Unknown', }; +const connectionInfo: ConnectionInfo = { + id: 'TEST', + connectionOptions: { + connectionString: 'mongodb://localhost:27017', + }, +}; + describe('connection tracking', function () { let trackUsageStatistics: boolean; const logger = createLogger('TEST-CONNECTION'); @@ -57,6 +64,7 @@ describe('connection tracking', function () { const trackEvent = once(process, 'compass:track'); trackConnectionAttemptEvent( { + ...connectionInfo, favorite: { name: 'example' }, lastUsed: undefined, }, @@ -69,13 +77,14 @@ describe('connection tracking', function () { is_favorite: true, is_recent: false, is_new: true, + connection_id: 'TEST', }); }); it('tracks a new connection attempt event - recent', async function () { const trackEvent = once(process, 'compass:track'); trackConnectionAttemptEvent( - { favorite: undefined, lastUsed: new Date() }, + { ...connectionInfo, favorite: undefined, lastUsed: new Date() }, logger, track ); @@ -84,13 +93,14 @@ describe('connection tracking', function () { is_favorite: false, is_recent: true, is_new: false, + connection_id: 'TEST', }); }); it('tracks a new connection attempt event - new', async function () { const trackEvent = once(process, 'compass:track'); trackConnectionAttemptEvent( - { favorite: undefined, lastUsed: undefined }, + { ...connectionInfo, favorite: undefined, lastUsed: undefined }, logger, track ); @@ -99,6 +109,7 @@ describe('connection tracking', function () { is_favorite: false, is_recent: false, is_new: true, + connection_id: 'TEST', }); }); @@ -106,6 +117,7 @@ describe('connection tracking', function () { const trackEvent = once(process, 'compass:track'); trackConnectionAttemptEvent( { + ...connectionInfo, favorite: { name: 'example' }, lastUsed: new Date(), }, @@ -117,18 +129,20 @@ describe('connection tracking', function () { is_favorite: true, is_recent: false, is_new: false, + connection_id: 'TEST', }); }); it('tracks a new connection event - localhost', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://localhost:27017', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { is_localhost: true, @@ -155,6 +169,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -162,13 +177,14 @@ describe('connection tracking', function () { it('tracks a new connection event - digital ocean', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://example.mongo.ondigitalocean.com:27017', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -196,6 +212,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -216,13 +233,14 @@ describe('connection tracking', function () { ]) { it(`tracks a new connection event - ${title}`, async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: url, }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -251,6 +269,7 @@ describe('connection tracking', function () { has_kms_azure: false, is_public_cloud: true, public_cloud_name: 'AWS', + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -287,13 +306,14 @@ describe('connection tracking', function () { getCurrentTopologyType: () => 'Unknown', }; - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://localhost:27017/', }, }; - trackNewConnectionEvent(connectionInfo, mockDataService, logger, track); + trackNewConnectionEvent(connection, mockDataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -321,6 +341,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -328,13 +349,14 @@ describe('connection tracking', function () { it('tracks a new connection event - public cloud', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://13.248.118.1', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -363,6 +385,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -370,13 +393,14 @@ describe('connection tracking', function () { it('tracks a new connection event - public ip but not aws/gcp/azure', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://google.com', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -404,6 +428,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -411,13 +436,14 @@ describe('connection tracking', function () { it('tracks a new connection event - nonexistent', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://nonexistent', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -444,6 +470,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -451,13 +478,14 @@ describe('connection tracking', function () { it('tracks a new connection event - nonexistent SRV', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb+srv://nonexistent', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -484,6 +512,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -496,12 +525,13 @@ describe('connection tracking', function () { authMechanism || 'DEFAULT' } auth`, async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: `mongodb://root:pwd@127.0.0.1?authMechanism=${authMechanism}`, }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.auth_type).to.equal(authMechanism || 'DEFAULT'); }); @@ -510,31 +540,34 @@ describe('connection tracking', function () { it('tracks a new connection event - no auth', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://127.0.0.1?authMechanism=', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.auth_type).to.equal('NONE'); }); it('tracks a new connection event - no tunnel', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://127.0.0.1?authMechanism=', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.tunnel).to.equal('none'); }); it('tracks a new connection event - ssh tunnel', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://127.0.0.1?authMechanism=', sshTunnel: { @@ -544,19 +577,20 @@ describe('connection tracking', function () { }, }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.tunnel).to.equal('ssh'); }); it('tracks a new connection event - SRV', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb+srv://127.0.0.1', }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.is_srv).to.equal(true); }); @@ -592,12 +626,13 @@ describe('connection tracking', function () { getCurrentTopologyType: () => 'Unknown', }; const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://127.0.0.1', }, }; - trackNewConnectionEvent(connectionInfo, mockDataService, logger, track); + trackNewConnectionEvent(connection, mockDataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.is_atlas).to.equal(true); @@ -642,12 +677,13 @@ describe('connection tracking', function () { getCurrentTopologyType: () => 'Sharded', }; const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://127.0.0.1', }, }; - trackNewConnectionEvent(connectionInfo, mockDataService, logger, track); + trackNewConnectionEvent(connection, mockDataService, logger, track); const [{ properties }] = await trackEvent; expect(properties.is_atlas).to.equal(false); @@ -664,7 +700,8 @@ describe('connection tracking', function () { it('tracks connection error event', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://localhost:27017', }, @@ -672,7 +709,7 @@ describe('connection tracking', function () { const connectionError = new Error(); - trackConnectionFailedEvent(connectionInfo, connectionError, logger, track); + trackConnectionFailedEvent(connection, connectionError, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -692,6 +729,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); @@ -699,7 +737,8 @@ describe('connection tracking', function () { it('tracks a new connection event - csfle on', async function () { const trackEvent = once(process, 'compass:track'); - const connectionInfo: Pick = { + const connection: ConnectionInfo = { + ...connectionInfo, connectionOptions: { connectionString: 'mongodb://127.128.0.0', fleOptions: { @@ -717,7 +756,7 @@ describe('connection tracking', function () { }, }; - trackNewConnectionEvent(connectionInfo, dataService, logger, track); + trackNewConnectionEvent(connection, dataService, logger, track); const [{ properties }] = await trackEvent; const expected = { @@ -745,6 +784,7 @@ describe('connection tracking', function () { has_kms_gcp: false, has_kms_kmip: false, has_kms_azure: false, + connection_id: 'TEST', }; expect(properties).to.deep.equal(expected); diff --git a/packages/compass/src/app/utils/telemetry.ts b/packages/compass/src/app/utils/telemetry.ts index 96172df3cc9..75760b364b8 100644 --- a/packages/compass/src/app/utils/telemetry.ts +++ b/packages/compass/src/app/utils/telemetry.ts @@ -151,24 +151,25 @@ async function getConnectionData({ } export function trackConnectionAttemptEvent( - { favorite, lastUsed }: Pick, + connectionInfo: ConnectionInfo, { debug }: Logger, track: TrackFunction ): void { try { + const { favorite, lastUsed } = connectionInfo; const trackEvent = { is_favorite: Boolean(favorite), is_recent: Boolean(lastUsed && !favorite), is_new: !lastUsed, }; - track('Connection Attempt', trackEvent); + track('Connection Attempt', trackEvent, connectionInfo); } catch (error) { debug('trackConnectionAttemptEvent failed', error); } } export function trackNewConnectionEvent( - connectionInfo: Pick, + connectionInfo: ConnectionInfo, dataService: Pick, { debug }: Logger, track: TrackFunction @@ -193,14 +194,14 @@ export function trackNewConnectionEvent( }; return trackEvent; }; - track('New Connection', callback); + track('New Connection', callback, connectionInfo); } catch (error) { debug('trackNewConnectionEvent failed', error); } } export function trackConnectionFailedEvent( - connectionInfo: Pick | null, + connectionInfo: ConnectionInfo | null, connectionError: Error & Partial>, { debug }: Logger, track: TrackFunction @@ -216,7 +217,7 @@ export function trackConnectionFailedEvent( }; return trackEvent; }; - track('Connection Failed', callback); + track('Connection Failed', callback, connectionInfo ?? undefined); } catch (error) { debug('trackConnectionFailedEvent failed', error); } diff --git a/packages/connection-form/package.json b/packages/connection-form/package.json index af1e72e2a81..ae25ea705bf 100644 --- a/packages/connection-form/package.json +++ b/packages/connection-form/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.31.0", + "version": "1.34.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -47,21 +47,21 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/connection-info": "^0.4.1", - "compass-preferences-model": "^2.23.1", - "ejson-shell-parser": "^2.0.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/connection-info": "^0.5.1", + "@mongodb-js/shell-bson-parser": "^1.1.0", + "compass-preferences-model": "^2.25.0", "lodash": "^4.17.21", "mongodb": "^6.7.0", "mongodb-build-info": "^1.7.2", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1", - "mongodb-query-parser": "^4.1.2", + "mongodb-data-service": "^22.22.1", + "mongodb-query-parser": "^4.2.0", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/connection-form/src/utils/csfle-handler.ts b/packages/connection-form/src/utils/csfle-handler.ts index 27605d7cf9a..8afc3b71eac 100644 --- a/packages/connection-form/src/utils/csfle-handler.ts +++ b/packages/connection-form/src/utils/csfle-handler.ts @@ -8,7 +8,9 @@ import type { } from 'mongodb'; import type { KMSProviderName } from './csfle-kms-fields'; import { toJSString } from 'mongodb-query-parser'; -import parseShellStringToEJSON, { ParseMode } from 'ejson-shell-parser'; +import parseShellStringToEJSON, { + ParseMode, +} from '@mongodb-js/shell-bson-parser'; const DEFAULT_FLE_OPTIONS: NonNullable = { storeCredentials: false, diff --git a/packages/connection-info/package.json b/packages/connection-info/package.json index e98a6170588..b6cec10a409 100644 --- a/packages/connection-info/package.json +++ b/packages/connection-info/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.4.1", + "version": "0.5.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -53,10 +53,10 @@ "lodash": "^4.17.21", "mongodb": "^6.7.0", "mongodb-connection-string-url": "^3.0.1", - "mongodb-data-service": "^22.21.1" + "mongodb-data-service": "^22.22.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/connection-storage/package.json b/packages/connection-storage/package.json index dc50b16af1d..5c19bcfeca6 100644 --- a/packages/connection-storage/package.json +++ b/packages/connection-storage/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.14.1", + "version": "0.16.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -56,23 +56,23 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-user-data": "^0.2.1", - "@mongodb-js/compass-utils": "^0.6.5", - "@mongodb-js/connection-info": "^0.4.1", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-user-data": "^0.3.1", + "@mongodb-js/compass-utils": "^0.6.7", + "@mongodb-js/connection-info": "^0.5.1", "bson": "^6.7.0", - "compass-preferences-model": "^2.23.1", - "electron": "^29.4.3", - "hadron-app-registry": "^9.1.12", - "hadron-ipc": "^3.2.16", + "compass-preferences-model": "^2.25.0", + "electron": "^29.4.5", + "hadron-app-registry": "^9.2.1", + "hadron-ipc": "^3.2.18", "keytar": "^7.9.0", "lodash": "^4.17.21", "mongodb-connection-string-url": "^3.0.1", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/data-service/package.json b/packages/data-service/package.json index 41152cdb7c5..542843b5487 100644 --- a/packages/data-service/package.json +++ b/packages/data-service/package.json @@ -7,7 +7,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "22.21.1", + "version": "22.22.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -51,10 +51,10 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-utils": "^0.6.5", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-utils": "^0.6.7", "@mongodb-js/devtools-connect": "^3.0.1", - "@mongodb-js/ssh-tunnel": "^2.2.1", + "@mongodb-js/ssh-tunnel": "^2.3.1", "bson": "^6.7.0", "lodash": "^4.17.21", "mongodb": "^6.7.0", @@ -63,9 +63,9 @@ "mongodb-ns": "^2.4.2" }, "devDependencies": { - "@mongodb-js/compass-test-server": "^0.1.17", + "@mongodb-js/compass-test-server": "^0.1.18", "@mongodb-js/devtools-docker-test-envs": "^1.3.2", - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/oidc-plugin": "^1.0.0", "@mongodb-js/prettier-config-compass": "^1.0.2", diff --git a/packages/database-model/package.json b/packages/database-model/package.json index 652820dda3b..67672d8710c 100644 --- a/packages/database-model/package.json +++ b/packages/database-model/package.json @@ -2,7 +2,7 @@ "name": "mongodb-database-model", "description": "MongoDB database model", "author": "Lucas Hrabovsky ", - "version": "2.21.1", + "version": "2.22.1", "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" @@ -30,11 +30,11 @@ "dependencies": { "ampersand-collection": "^2.0.2", "ampersand-model": "^8.0.1", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1" + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "depcheck": "^1.4.1", "eslint": "^7.25.0", diff --git a/packages/databases-collections-list/package.json b/packages/databases-collections-list/package.json index b7fdae15cc1..f5497e236ab 100644 --- a/packages/databases-collections-list/package.json +++ b/packages/databases-collections-list/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.30.0", + "version": "1.33.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -48,13 +48,17 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "dependencies": { - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-telemetry": "^1.0.1", - "compass-preferences-model": "^2.23.1", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/connection-info": "^0.5.1", + "compass-preferences-model": "^2.25.0", + "mongodb-ns": "^2.4.2", "react": "^17.0.2" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/databases-collections-list/src/collections.tsx b/packages/databases-collections-list/src/collections.tsx index 6baa14c908a..792ec96bd75 100644 --- a/packages/databases-collections-list/src/collections.tsx +++ b/packages/databases-collections-list/src/collections.tsx @@ -1,11 +1,5 @@ -/* eslint-disable react/prop-types */ -import React, { useMemo } from 'react'; -import { - type BreadcrumbItem, - Breadcrumbs, - css, - spacing, -} from '@mongodb-js/compass-components'; +import React from 'react'; +import { css, spacing } from '@mongodb-js/compass-components'; import { compactBytes, compactNumber } from './format'; import type { BadgeProp } from './namespace-card'; import { NamespaceItemCard } from './namespace-card'; @@ -86,47 +80,25 @@ const pageContainerStyles = css({ flexDirection: 'column', }); -const breadcrumbStyles = css({ - paddingLeft: spacing[3], - paddingTop: spacing[3], - paddingBottom: spacing[2], -}); - const CollectionsList: React.FunctionComponent<{ - connectionTitle: string; - databaseName: string; + namespace: string; collections: Collection[]; onCollectionClick(id: string): void; - onClickConnectionBreadcrumb(): void; onDeleteCollectionClick?: (id: string) => void; onCreateCollectionClick?: () => void; onRefreshClick?: () => void; }> = ({ - connectionTitle, - databaseName, + namespace, collections, - onClickConnectionBreadcrumb, onCollectionClick, onCreateCollectionClick, onDeleteCollectionClick, onRefreshClick, }) => { - const breadcrumbItems = useMemo(() => { - return [ - { - name: connectionTitle, - onClick: () => onClickConnectionBreadcrumb(), - }, - { - name: databaseName, - }, - ] as BreadcrumbItem[]; - }, [connectionTitle, databaseName, onClickConnectionBreadcrumb]); - return (
- void; onCreateDatabaseClick?: () => void; onRefreshClick?: () => void; + renderLoadSampleDataBanner?: () => React.ReactNode; }> = ({ databases, onDatabaseClick, onCreateDatabaseClick, onDeleteDatabaseClick, onRefreshClick, + renderLoadSampleDataBanner, }) => { return ( ); }} + renderLoadSampleDataBanner={renderLoadSampleDataBanner} > ); }; diff --git a/packages/databases-collections-list/src/index.spec.tsx b/packages/databases-collections-list/src/index.spec.tsx index fb61b66d3ee..7d6cccfb37e 100644 --- a/packages/databases-collections-list/src/index.spec.tsx +++ b/packages/databases-collections-list/src/index.spec.tsx @@ -101,11 +101,9 @@ describe('databases and collections list', function () { render( {}} > ); @@ -122,32 +120,11 @@ describe('databases and collections list', function () { expect(clickSpy).to.be.calledWith('bar.bar'); }); - it('should notify when the connection name is clicked', function () { - const clickSpy = Sinon.spy(); - const connectionClickSpy = Sinon.spy(); - - render( - - ); - - userEvent.click(screen.getByText('My Connection')); - - expect(connectionClickSpy).to.be.called; - }); - it('should not display statistics (except storage size) on timeseries collection card', function () { render( {}} onCollectionClick={() => {}} > ); diff --git a/packages/databases-collections-list/src/items-grid.tsx b/packages/databases-collections-list/src/items-grid.tsx index 6cbb0a39597..c2bb0e2dc0c 100644 --- a/packages/databases-collections-list/src/items-grid.tsx +++ b/packages/databases-collections-list/src/items-grid.tsx @@ -1,5 +1,4 @@ -/* eslint-disable react/prop-types */ -import React, { useContext, useCallback } from 'react'; +import React, { useCallback, useMemo } from 'react'; import { css, cx, @@ -7,26 +6,34 @@ import { VirtualGrid, useSortControls, useSortedItems, + WorkspaceContainer, + Button, + Icon, + Breadcrumbs, } from '@mongodb-js/compass-components'; import { useTelemetry } from '@mongodb-js/compass-telemetry/provider'; import type { NamespaceItemCardProps } from './namespace-card'; import { useViewTypeControls } from './use-view-type'; import type { ViewType } from './use-view-type'; -import { useCreateControls } from './use-create'; -import { useRefreshControls } from './use-refresh'; +import { useConnectionInfo } from '@mongodb-js/compass-connections/provider'; +import toNS from 'mongodb-ns'; +import { getConnectionTitle } from '@mongodb-js/connection-info'; +import { useOpenWorkspace } from '@mongodb-js/compass-workspaces/provider'; +import { useConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; +import { usePreferences } from 'compass-preferences-model/provider'; type Item = { _id: string } & Record; -const row = css({ +const rowStyles = css({ paddingLeft: spacing[3], paddingRight: spacing[3], paddingBottom: spacing[2], columnGap: spacing[2], }); -const container = css({ +const containerStyles = css({ width: '100%', - flex: 1, + height: '100%', overflow: 'hidden', display: 'grid', gridTemplateRows: 'auto 1fr', @@ -37,21 +44,10 @@ const container = css({ outline: 'none', }); -const controls = css({ - display: 'flex', - padding: spacing[3], - gap: spacing[2], - flex: 'none', -}); - -export const createButton = css({ +export const createButtonStyles = css({ whiteSpace: 'nowrap', }); -const control = css({ - flex: 'none', -}); - type CallbackProps = { onItemClick(id: string): void; onCreateItemClick?: () => void; @@ -72,6 +68,7 @@ interface RenderItem { } type ItemsGridProps = { + namespace?: string; itemType: 'collection' | 'database'; itemGridWidth: number; itemGridHeight: number; @@ -84,54 +81,212 @@ type ItemsGridProps = { onCreateItemClick?: () => void; onRefreshClick?: () => void; renderItem: RenderItem; + renderLoadSampleDataBanner?: () => React.ReactNode; }; -const CONTROLS_HEIGHT = (spacing[5] as number) + 36; +const controlsContainerStyles = css({ + paddingTop: spacing[200], + paddingRight: spacing[400], + paddingBottom: spacing[400], + paddingLeft: spacing[400], + + display: 'grid', + gridTemplate: '1fr / 100%', + gap: spacing[200], +}); + +const controlRowStyles = css({ + display: 'flex', + alignItems: 'center', + gap: spacing[200], +}); + +const controlStyles = css({ + flex: 'none', +}); -const pushRight = css({ +const breadcrumbContainerStyles = css({ + display: 'flex', + minWidth: 0, + paddingTop: spacing[200], + paddingBottom: spacing[200], +}); + +const pushRightStyles = css({ marginLeft: 'auto', }); -// We use this context to pass components that are aware of outer state of the -// v-list to the list header. This is needed so that we can define this outer -// component outside of the list component scope and avoid constant re-mounts -// when component constructor is re-created. We do this so that controls can be -// part of the list header and scroll up when the list is scrolled -const ControlsContext = React.createContext<{ - createControls: React.ReactElement | null; - refreshControls: React.ReactElement | null; - viewTypeControls: React.ReactElement | null; - sortControls: React.ReactElement | null; -}>({ - createControls: null, - refreshControls: null, - viewTypeControls: null, - sortControls: null, +const bannerRowStyles = css({ + paddingTop: spacing[200], }); -const GridControls = () => { - const { createControls, refreshControls, viewTypeControls, sortControls } = - useContext(ControlsContext); +function buildChartsUrl( + groupId: string, + clusterName: string, + namespace?: string +) { + const { database } = toNS(namespace ?? ''); + const url = new URL(`/charts/${groupId}`, window.location.origin); + url.searchParams.set('sourceType', 'cluster'); + url.searchParams.set('instanceName', clusterName); + if (database) { + url.searchParams.set('database', database); + } + return url.toString(); +} + +const GridControls: React.FunctionComponent<{ + namespace?: string; + itemType: string; + sortControls?: React.ReactNode; + viewTypeControls?: React.ReactNode; + onCreateItemClick?: () => void; + onRefreshClick?: () => void; + renderLoadSampleDataBanner?: () => React.ReactNode; +}> = ({ + namespace, + itemType, + sortControls, + viewTypeControls, + onCreateItemClick, + onRefreshClick, + renderLoadSampleDataBanner, +}) => { + const connectionInfo = useConnectionInfo(); + const connectionTitle = getConnectionTitle(connectionInfo); + const { + openDatabasesWorkspace, + openCollectionsWorkspace, + openShellWorkspace, + } = useOpenWorkspace(); + const { enableShell, enableNewMultipleConnectionSystem } = usePreferences([ + 'enableShell', + 'enableNewMultipleConnectionSystem', + ]); + + const showOpenShellButton = enableShell && enableNewMultipleConnectionSystem; + + const breadcrumbs = useMemo(() => { + const { database } = toNS(namespace ?? ''); + const items = [ + { + name: connectionTitle, + onClick: () => { + openDatabasesWorkspace(connectionInfo.id); + }, + }, + ]; + + if (database) { + items.push({ + name: database, + onClick: () => { + openCollectionsWorkspace(connectionInfo.id, database); + }, + }); + } + + return items; + }, [ + connectionInfo.id, + connectionTitle, + namespace, + openCollectionsWorkspace, + openDatabasesWorkspace, + ]); + + const banner = renderLoadSampleDataBanner?.(); return ( - <> - {createControls && ( -
- {createControls} +
+
+
+
- )} - {refreshControls && ( -
- {refreshControls} + +
+ {showOpenShellButton && ( + + )} + + {connectionInfo.atlasMetadata && ( + + )} + + {onCreateItemClick && ( +
+ +
+ )} + + {onRefreshClick && ( +
+ +
+ )} +
+
+ {sortControls && viewTypeControls && ( +
+
{sortControls}
+
+ {viewTypeControls} +
)} -
{viewTypeControls}
-
{sortControls}
- + {banner &&
{banner}
} +
); }; +const itemsGridContainerStyles = css({ + width: '100%', + height: '100%', +}); + export const ItemsGrid = ({ + namespace, itemType, itemGridWidth, itemGridHeight, @@ -144,16 +299,21 @@ export const ItemsGrid = ({ onCreateItemClick, onRefreshClick, renderItem: _renderItem, + renderLoadSampleDataBanner, }: ItemsGridProps): React.ReactElement => { const track = useTelemetry(); + const connectionInfoAccess = useConnectionInfoAccess(); const onViewTypeChange = useCallback( (newType) => { - track('Switch View Type', { view_type: newType, item_type: itemType }); + track( + 'Switch View Type', + { view_type: newType, item_type: itemType }, + connectionInfoAccess.getCurrentConnectionInfo() + ); }, - [itemType, track] + [itemType, track, connectionInfoAccess] ); - const createControls = useCreateControls(itemType, onCreateItemClick); - const refreshControls = useRefreshControls(onRefreshClick); + const [sortControls, sortState] = useSortControls(sortBy); const [viewTypeControls, viewType] = useViewTypeControls({ onChange: onViewTypeChange, @@ -181,31 +341,40 @@ export const ItemsGrid = ({ ); return ( - - sortedItems[index]._id} - headerHeight={CONTROLS_HEIGHT} - renderHeader={GridControls} - classNames={{ - container, - header: controls, - row: row, +
+ + } + > + {(scrollTriggerRef) => { + return ( + { + return
; + }} + headerHeight={0} + itemKey={(index: number) => sortedItems[index]._id} + classNames={{ container: containerStyles, row: rowStyles }} + resetActiveItemOnBlur={false} + data-testid={`${itemType}-grid`} + >
+ ); }} - resetActiveItemOnBlur={false} - data-testid={`${itemType}-grid`} - > - +
+
); }; diff --git a/packages/databases-collections-list/src/namespace-card.tsx b/packages/databases-collections-list/src/namespace-card.tsx index 50b2852b039..9ef2a8b760d 100644 --- a/packages/databases-collections-list/src/namespace-card.tsx +++ b/packages/databases-collections-list/src/namespace-card.tsx @@ -25,7 +25,6 @@ import type { SignalPopover, } from '@mongodb-js/compass-components'; import { NamespaceParam } from './namespace-param'; -import type { ItemType } from './use-create'; import type { ViewType } from './use-view-type'; import { usePreference } from 'compass-preferences-model/provider'; @@ -162,7 +161,7 @@ export type DataProp = { export type NamespaceItemCardProps = { id: string; - type: ItemType; + type: 'database' | 'collection'; viewType: ViewType; name: string; status: 'initial' | 'fetching' | 'refreshing' | 'ready' | 'error'; diff --git a/packages/databases-collections-list/src/use-create.tsx b/packages/databases-collections-list/src/use-create.tsx deleted file mode 100644 index 308f492dcb5..00000000000 --- a/packages/databases-collections-list/src/use-create.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { Button, Icon } from '@mongodb-js/compass-components'; -import { createButton } from './items-grid'; - -export type ItemType = 'database' | 'collection'; - -export function useCreateControls( - itemType: ItemType, - onCreateClick?: () => void -): React.ReactElement | null { - if (!onCreateClick) { - return null; - } - - return ( - - ); -} diff --git a/packages/databases-collections-list/src/use-refresh.tsx b/packages/databases-collections-list/src/use-refresh.tsx deleted file mode 100644 index 6d52f018551..00000000000 --- a/packages/databases-collections-list/src/use-refresh.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { Button, Icon } from '@mongodb-js/compass-components'; - -export function useRefreshControls( - onRefreshClick?: () => void -): React.ReactElement | null { - if (!onRefreshClick) { - return null; - } - - return ( - - ); -} diff --git a/packages/databases-collections/package.json b/packages/databases-collections/package.json index 1b51f769e32..3f17cc64fa2 100644 --- a/packages/databases-collections/package.json +++ b/packages/databases-collections/package.json @@ -2,7 +2,7 @@ "name": "@mongodb-js/compass-databases-collections", "description": "Plugin for viewing the list of, creating, and dropping databases and collections", "private": true, - "version": "1.32.0", + "version": "1.35.0", "license": "SSPL", "homepage": "https://github.com/mongodb-js/compass", "bugs": { @@ -42,7 +42,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -60,24 +60,23 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-app-stores": "^7.19.0", - "@mongodb-js/compass-components": "^1.26.0", - "@mongodb-js/compass-connections": "^1.33.0", - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/connection-info": "^0.4.1", - "@mongodb-js/compass-logging": "^1.3.1", - "@mongodb-js/compass-telemetry": "^1.0.1", - "@mongodb-js/compass-workspaces": "^0.14.0", - "@mongodb-js/databases-collections-list": "^1.30.0", - "@mongodb-js/my-queries-storage": "^0.10.0", - "compass-preferences-model": "^2.23.1", - "hadron-app-registry": "^9.1.12", + "@mongodb-js/compass-app-stores": "^7.22.0", + "@mongodb-js/compass-components": "^1.28.0", + "@mongodb-js/compass-connections": "^1.36.0", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-logging": "^1.4.1", + "@mongodb-js/compass-telemetry": "^1.1.1", + "@mongodb-js/compass-workspaces": "^0.17.0", + "@mongodb-js/databases-collections-list": "^1.33.0", + "@mongodb-js/my-queries-storage": "^0.13.0", + "compass-preferences-model": "^2.25.0", + "hadron-app-registry": "^9.2.1", "lodash": "^4.17.21", - "mongodb-collection-model": "^5.21.1", - "mongodb-database-model": "^2.21.1", - "mongodb-instance-model": "^12.22.1", + "mongodb-collection-model": "^5.22.1", + "mongodb-database-model": "^2.22.1", + "mongodb-instance-model": "^12.23.1", "mongodb-ns": "^2.4.2", - "mongodb-query-parser": "^4.1.2", + "mongodb-query-parser": "^4.2.0", "prop-types": "^15.7.2", "react": "^17.0.2", "react-redux": "^8.1.3", diff --git a/packages/databases-collections/src/components/collections.tsx b/packages/databases-collections/src/components/collections.tsx index 89c5224164f..7a6b202a33a 100644 --- a/packages/databases-collections/src/components/collections.tsx +++ b/packages/databases-collections/src/components/collections.tsx @@ -17,7 +17,6 @@ import type Collection from 'mongodb-collection-model'; import toNS from 'mongodb-ns'; import { useOpenWorkspace } from '@mongodb-js/compass-workspaces/provider'; import { useConnectionInfo } from '@mongodb-js/compass-connections/provider'; -import { getConnectionTitle } from '@mongodb-js/connection-info'; import { usePreference } from 'compass-preferences-model/provider'; import { useTrackOnChange, @@ -57,14 +56,14 @@ const Collections: React.FunctionComponent = ({ }, [isCompassInWritableMode, isInstanceWritable]); const connectionInfo = useConnectionInfo(); const { id: connectionId } = connectionInfo; - const { openDatabasesWorkspace, openCollectionWorkspace } = - useOpenWorkspace(); + const { openCollectionWorkspace } = useOpenWorkspace(); - const parsedNS = toNS(namespace); - - useTrackOnChange((track: TrackFunction) => { - track('Screen', { name: 'collections' }); - }, []); + useTrackOnChange( + (track: TrackFunction) => { + track('Screen', { name: 'collections' }, connectionInfo); + }, + [connectionInfo] + ); const onCollectionClick = useCallback( (ns: string) => { @@ -84,10 +83,6 @@ const Collections: React.FunctionComponent = ({ [connectionId, _onDeleteCollectionClick] ); - const onClickConnectionBreadcrumb = useCallback(() => { - openDatabasesWorkspace(connectionId); - }, [connectionId, openDatabasesWorkspace]); - if (collectionsLoadingStatus === 'error') { return (
@@ -101,10 +96,7 @@ const Collections: React.FunctionComponent = ({ } const actions = Object.assign( - { - onCollectionClick, - onRefreshClick, - }, + { onCollectionClick, onRefreshClick }, isEditable ? { onCreateCollectionClick, @@ -115,10 +107,8 @@ const Collections: React.FunctionComponent = ({ return ( ); diff --git a/packages/databases-collections/src/components/databases.tsx b/packages/databases-collections/src/components/databases.tsx index 3372e77e8ad..cc64f157588 100644 --- a/packages/databases-collections/src/components/databases.tsx +++ b/packages/databases-collections/src/components/databases.tsx @@ -23,9 +23,14 @@ import { useTrackOnChange, type TrackFunction, } from '@mongodb-js/compass-telemetry/provider'; +import toNS from 'mongodb-ns'; +import { + LoadSampleDataZeroBanner, + LoadSampleDataZeroState, +} from './load-sample-data'; const errorContainerStyles = css({ - padding: spacing[3], + padding: spacing[400], }); const nonGenuineErrorContainerStyles = css({ @@ -70,7 +75,7 @@ type DatabasesProps = { isDataLake: boolean; onDeleteDatabaseClick(connectionId: string, ns: string): void; onCreateDatabaseClick(connectionId: string): void; - onRefreshClick(): void; + onRefreshClick(connectionId: string): void; }; const Databases: React.FunctionComponent = ({ @@ -82,9 +87,10 @@ const Databases: React.FunctionComponent = ({ isGenuineMongoDB, onDeleteDatabaseClick: _onDeleteDatabaseClick, onCreateDatabaseClick: _onCreateDatabaseClick, - onRefreshClick, + onRefreshClick: _onRefreshClick, }) => { - const { id: connectionId } = useConnectionInfo(); + const connectionInfo = useConnectionInfo(); + const { id: connectionId, atlasMetadata } = connectionInfo; const isPreferencesReadOnly = usePreference('readOnly'); const { openCollectionsWorkspace } = useOpenWorkspace(); @@ -106,9 +112,40 @@ const Databases: React.FunctionComponent = ({ _onCreateDatabaseClick(connectionId); }, [connectionId, _onCreateDatabaseClick]); - useTrackOnChange((track: TrackFunction) => { - track('Screen', { name: 'databases' }); - }, []); + const onRefreshClick = useCallback(() => { + _onRefreshClick(connectionId); + }, [connectionId, _onRefreshClick]); + + useTrackOnChange( + (track: TrackFunction) => { + track('Screen', { name: 'databases' }, connectionInfo); + }, + [connectionInfo] + ); + + const renderLoadSampleDataBanner = useCallback(() => { + if ( + !atlasMetadata || + databases.some((db) => { + return !toNS(db.name).specialish; + }) + ) { + return null; + } + + return ( + + ); + }, [databases, atlasMetadata]); + + const editable = isWritable && !isPreferencesReadOnly; + + if (databasesLoadingStatus === 'fetching') { + return null; + } if (databasesLoadingStatus === 'error') { return ( @@ -126,7 +163,17 @@ const Databases: React.FunctionComponent = ({ return ; } - const editable = isWritable && !isPreferencesReadOnly; + if (atlasMetadata && databases.length === 0) { + return ( + + ); + } + const actions = Object.assign( { onDatabaseClick, @@ -140,7 +187,13 @@ const Databases: React.FunctionComponent = ({ : {} ); - return ; + return ( + + ); }; const mapStateToProps = (state: DatabasesState) => { diff --git a/packages/databases-collections/src/components/load-sample-data.tsx b/packages/databases-collections/src/components/load-sample-data.tsx new file mode 100644 index 00000000000..12b48eb8433 --- /dev/null +++ b/packages/databases-collections/src/components/load-sample-data.tsx @@ -0,0 +1,132 @@ +import React from 'react'; +import { + Banner, + Button, + EmptyContent, + css, + spacing, + Icon, +} from '@mongodb-js/compass-components'; +import { LoadSampleDataZeroGraphic } from './zero-graphic'; + +function buildAddDataUrl(projectId: string, clusterName: string) { + const url = new URL( + `/v2/${projectId}#/addData/${encodeURIComponent(clusterName)}/load`, + window.location.origin + ); + return url.toString(); +} + +const addDataContainerStyles = css({ + width: '100%', + padding: spacing[400], +}); + +const loadSampleDataActionsStyles = css({ + display: 'flex', + gap: spacing[300], +}); + +export function LoadSampleDataZeroState({ + projectId, + clusterName, + canCreateDatabase, + onCreateDatabase, +}: { + projectId: string; + clusterName: string; + canCreateDatabase: boolean; + onCreateDatabase: () => void; +}) { + return ( +
+ + Create database or load sample data to your cluster to quickly get + started experimenting with data in MongoDB. + + ) : ( + <> + You can load sample data to quickly get started experimenting with + data in MongoDB. + + ) + } + callToActionLink={ +
+ {canCreateDatabase && ( + + )} + +
+ } + /> +
+ ); +} + +const addDataBannerContent = css({ + display: 'flex', + alignItems: 'center', + gap: spacing[200], +}); + +const addDataBannerButtonStyles = css({ + marginLeft: 'auto', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', +}); + +const EmptyElement = () => null; + +export function LoadSampleDataZeroBanner({ + projectId, + clusterName, +}: { + projectId: string; + clusterName: string; +}) { + return ( + }> +
+ + Working with MongoDB is easy, but first you’ll need some data to get + started. Sample data is available for loading. + +
+ +
+
+
+ ); +} diff --git a/packages/databases-collections/src/components/zero-graphic.tsx b/packages/databases-collections/src/components/zero-graphic.tsx index 1fee09d0745..fda96d6886d 100644 --- a/packages/databases-collections/src/components/zero-graphic.tsx +++ b/packages/databases-collections/src/components/zero-graphic.tsx @@ -36,4 +36,38 @@ const ZeroGraphic = () => { ); }; -export { ZeroGraphic }; +function LoadSampleDataZeroGraphic( + props: React.SVGProps & { size?: number } +) { + const size = props.size ?? 60; + return ( + + + + + + + + + ); +} + +export { ZeroGraphic, LoadSampleDataZeroGraphic }; diff --git a/packages/databases-collections/src/index.ts b/packages/databases-collections/src/index.ts index 48a7ec84091..7d4aaab7ba9 100644 --- a/packages/databases-collections/src/index.ts +++ b/packages/databases-collections/src/index.ts @@ -1,6 +1,6 @@ import { registerHadronPlugin } from 'hadron-app-registry'; import { createLoggerLocator } from '@mongodb-js/compass-logging/provider'; -import { createTelemetryLocator } from '@mongodb-js/compass-telemetry/provider'; +import { telemetryLocator } from '@mongodb-js/compass-telemetry/provider'; import { connectionsManagerLocator } from '@mongodb-js/compass-connections/provider'; import { mongoDBInstancesManagerLocator } from '@mongodb-js/compass-app-stores/provider'; import { CollectionsPlugin } from './collections-plugin'; @@ -19,6 +19,7 @@ import { favoriteQueryStorageAccessLocator, pipelineStorageLocator, } from '@mongodb-js/my-queries-storage/provider'; +import { connectionRepositoryAccessLocator } from '@mongodb-js/compass-connections/provider'; export const CollectionsWorkspaceTab: WorkspaceComponent<'Collections'> = { name: 'Collections' as const, @@ -38,8 +39,9 @@ export const CreateNamespacePlugin = registerHadronPlugin( }, { logger: createLoggerLocator('COMPASS-CREATE-NAMESPACE-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, connectionsManager: connectionsManagerLocator, + connectionRepository: connectionRepositoryAccessLocator, instancesManager: mongoDBInstancesManagerLocator, workspaces: workspacesServiceLocator, } @@ -53,7 +55,8 @@ export const DropNamespacePlugin = registerHadronPlugin( }, { logger: createLoggerLocator('COMPASS-DROP-NAMESPACE-UI'), - track: createTelemetryLocator(), + track: telemetryLocator, + connectionRepository: connectionRepositoryAccessLocator, connectionsManager: connectionsManagerLocator, } ); diff --git a/packages/databases-collections/src/modules/create-namespace.spec.ts b/packages/databases-collections/src/modules/create-namespace.spec.ts index d8e1ebb3bd5..163ef3fe032 100644 --- a/packages/databases-collections/src/modules/create-namespace.spec.ts +++ b/packages/databases-collections/src/modules/create-namespace.spec.ts @@ -32,7 +32,12 @@ describe('create collection module', function () { storeAction = action; }, () => INITIAL_STATE, - { track: createNoopTrack() } as any + { + track: createNoopTrack(), + connectionRepository: { + getConnectionInfoById: () => ({ id: 'TEST' }), + }, + } as any ); const state = reducer(undefined, storeAction); expect(state).to.deep.equal({ @@ -54,7 +59,12 @@ describe('create collection module', function () { storeAction = action; }, () => INITIAL_STATE, - { track: createNoopTrack() } as any + { + track: createNoopTrack(), + connectionRepository: { + getConnectionInfoById: () => ({ id: 'TEST' }), + }, + } as any ); const state = reducer(undefined, storeAction); expect(state).to.deep.equal({ diff --git a/packages/databases-collections/src/modules/create-namespace.ts b/packages/databases-collections/src/modules/create-namespace.ts index 4ca74e8f4f0..957a0d09a13 100644 --- a/packages/databases-collections/src/modules/create-namespace.ts +++ b/packages/databases-collections/src/modules/create-namespace.ts @@ -357,6 +357,7 @@ export const createNamespace = ( { globalAppRegistry, connectionsManager, + connectionRepository, logger: { debug }, track, workspaces, @@ -391,7 +392,11 @@ export const createNamespace = ( expires: !!data.options.expireAfterSeconds, }; - track(`${kind} Created`, trackEvent); + track( + `${kind} Created`, + trackEvent, + connectionRepository.getConnectionInfoById(connectionId) + ); globalAppRegistry.emit('collection-created', namespace, { connectionId, diff --git a/packages/databases-collections/src/modules/databases.ts b/packages/databases-collections/src/modules/databases.ts index 138c723c3dc..511436a7d10 100644 --- a/packages/databases-collections/src/modules/databases.ts +++ b/packages/databases-collections/src/modules/databases.ts @@ -85,9 +85,11 @@ export const databasesChanged = (instance: MongoDBInstance) => ({ databases: instance.databases.toJSON(), }); -export const refreshDatabases = (): DatabasesThunkAction => { +export const refreshDatabases = ( + connectionId: string +): DatabasesThunkAction => { return (_dispatch, _getState, { globalAppRegistry }) => { - globalAppRegistry.emit('refresh-databases'); + globalAppRegistry.emit('refresh-databases', { connectionId }); }; }; diff --git a/packages/databases-collections/src/stores/create-namespace.ts b/packages/databases-collections/src/stores/create-namespace.ts index db0385e759c..1fbbece17b9 100644 --- a/packages/databases-collections/src/stores/create-namespace.ts +++ b/packages/databases-collections/src/stores/create-namespace.ts @@ -3,6 +3,7 @@ import { ConnectionsManagerEvents, type ConnectionsManager, type DataService, + type ConnectionRepositoryAccess, } from '@mongodb-js/compass-connections/provider'; import type { MongoDBInstance } from 'mongodb-instance-model'; import type { Logger } from '@mongodb-js/compass-logging'; @@ -29,6 +30,7 @@ type NS = ReturnType; export type CreateNamespaceServices = { connectionsManager: ConnectionsManager; + connectionRepository: ConnectionRepositoryAccess; instancesManager: MongoDBInstancesManager; globalAppRegistry: AppRegistry; logger: Logger; diff --git a/packages/explain-plan-helper/package.json b/packages/explain-plan-helper/package.json index a0d2092f2a7..7822bed821b 100644 --- a/packages/explain-plan-helper/package.json +++ b/packages/explain-plan-helper/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.1.13", + "version": "1.1.14", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -52,7 +52,7 @@ "mongodb-explain-compat": "^3.0.4" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/hadron-app-registry/package.json b/packages/hadron-app-registry/package.json index 18613339fab..ad5c07e29bf 100644 --- a/packages/hadron-app-registry/package.json +++ b/packages/hadron-app-registry/package.json @@ -7,7 +7,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "9.1.12", + "version": "9.2.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,7 +50,7 @@ "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/hadron-build/README.md b/packages/hadron-build/README.md index ba6642497e1..7394ed59470 100644 --- a/packages/hadron-build/README.md +++ b/packages/hadron-build/README.md @@ -16,10 +16,6 @@ npm install --save-dev hadron-build; ### `hadron-build info` -### `hadron-build develop` - -### `hadron-build clean` - ### `hadron-build release` ### `hadron-build upload` @@ -33,12 +29,9 @@ hadron-build [options] Commands: release :shipit: - clean Remove generated directories. config Configuration. - develop [options] Run the app in development mode. test [options] Run app tests. upload [options] Upload assets from `release`. - ui [options] Compile the app UI. verify [options] Verify the current environment meets the app\'s requirements. Options: @@ -74,12 +67,9 @@ Options: "scripts": { "check": "hadron-build check", "test-check-ci": "npm run test", - "clean": "hadron-build clean", "compile-ui": "hadron-build ui", "fmt": "hadron-build fmt", - "postuninstall": "hadron-build clean", "release": "hadron-build release", - "start": "hadron-build develop", } } ``` diff --git a/packages/hadron-build/cli.js b/packages/hadron-build/cli.js index 3bdeea21be6..f05b8f627b7 100755 --- a/packages/hadron-build/cli.js +++ b/packages/hadron-build/cli.js @@ -8,12 +8,9 @@ const yargs = require('yargs') .wrap(120) .usage('$0 [options]') .command(require('./commands/release')) - .command(require('./commands/clean')) .command(require('./commands/info')) - .command(require('./commands/develop')) .command(require('./commands/upload')) .command(require('./commands/download')) - .command(require('./commands/ui')) .command(require('./commands/verify')) .demand(1, 'Please specify a command.') .strict() diff --git a/packages/hadron-build/commands/clean.js b/packages/hadron-build/commands/clean.js deleted file mode 100644 index daefc037024..00000000000 --- a/packages/hadron-build/commands/clean.js +++ /dev/null @@ -1,27 +0,0 @@ -'use strict'; -/** - * @see [Atom's clean-task.coffee](https://git.io/vaZLw) - */ -const _ = require('lodash'); -const del = require('del'); -const cli = require('mongodb-js-cli')('hadron-build:clean'); -const ui = require('./ui'); - -exports.command = 'clean'; - -exports.describe = 'Remove generated directories.'; - -exports.builder = _.clone(ui.builder); - -exports.tasks = (argv) => { - return del([ - 'dist/', - 'node_modules/', - argv.less_cache - ]); -}; - -exports.handler = (argv) => { - exports.tasks(argv) - .catch((err) => cli.abortIfError(err)); -}; diff --git a/packages/hadron-build/commands/develop.js b/packages/hadron-build/commands/develop.js deleted file mode 100644 index a5329df3300..00000000000 --- a/packages/hadron-build/commands/develop.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; -/** - * TODO (imlucas) Use nodemon so main process has livereload. - */ -const Promise = require('bluebird'); -const _ = require('lodash'); -const spawn = require('child_process').spawn; -const ui = require('./ui'); -const verify = require('./verify'); -const cli = require('mongodb-js-cli')('hadron-build:develop'); -const ELECTRON_PREBUILT_EXECUTABLE = require('electron'); - -exports.command = 'develop [options]'; - -exports.describe = 'Run the app in development mode.'; - -exports.builder = { - devtools: { - describe: 'Automatically open devtools?', - type: 'boolean', - default: false - }, - interactive: { - describe: 'Launch a main process repl after app started?', - type: 'boolean', - default: false - } -}; - -_.assign(exports.builder, verify.builder, ui.builder); - -exports.tasks = function(argv) { - process.env.NODE_ENV = 'development'; - process.env.DEBUG = 'hadron*,mongo*,electron*'; - - if (argv.devtools) { - process.env.DEVTOOLS = '1'; - } - - if (argv.options) { - process.env.HADRON_DISTRIBUTION = argv.options; - } - - return Promise.all([ - verify.tasks(argv), - ui.tasks(argv) - ]) - .then( () => exports.startElectronPrebuilt(argv)); -}; - -exports.handler = (argv) => { - exports.tasks(argv) - .catch((err) => cli.abortIfError(err)); -}; - -exports.startElectronPrebuilt = (argv) => { - argv = argv || {}; - - const cwd = argv.cwd || process.cwd(); - const options = { - env: process.env, - cwd: cwd, - stdio: 'inherit' - }; - - let args = []; - if (argv.interactive) { - args.push('--interactive'); - } - args.push(cwd); - - const p = Promise.defer(); - spawn(ELECTRON_PREBUILT_EXECUTABLE, args, options) - .on('error', (err) => p.reject(err)) - .on('exit', () => p.resolve()); - return p.promise; -}; diff --git a/packages/hadron-build/commands/release.js b/packages/hadron-build/commands/release.js index 488e9c2aff7..4f02af27fd1 100644 --- a/packages/hadron-build/commands/release.js +++ b/packages/hadron-build/commands/release.js @@ -31,17 +31,12 @@ const run = require('./../lib/run'); const rebuild = require('@electron/rebuild').rebuild; const { signArchive } = require('./../lib/signtool'); -const ui = require('./ui'); const verify = require('./verify'); exports.command = 'release'; exports.describe = ':shipit:'; -const compileAssets = module.exports.compileAssets = (CONFIG, done) => { - run('npm', ['run', 'compile'], { cwd: CONFIG.dir }, done); -}; - /** * Run `electron-packager` * @@ -165,6 +160,26 @@ const copy3rdPartyNoticesFile = (CONFIG, done) => { } }; +/** + * Copies the SBOM file from the compass dir to the root of the archive, similar to + * copy3rdPartyNoticesFile(). + */ +const copySBOMFile = (CONFIG, done) => { + try { + const sbomPath = path.join(CONFIG.dir, '..', '..', '.sbom', 'sbom.json'); + const contents = fs.readFileSync(sbomPath); + CONFIG.write('.sbom.json', contents).then(() => { + cli.debug(format('.sbom.json written')); + }).then(() => done(null, true)); + } catch (err) { + if (err.code === 'ENOENT' && !process.env.COMPASS_WAS_COMPILED_AND_HAS_SBOM) { + cli.debug(format('Skipping sbom.json writing because the file is missing')); + return done(null, true); + } + done(err); + } +}; + // Remove a malicious link from chromium license // See: COMPASS-5333 const fixCompass5333 = (CONFIG, done) => { @@ -277,7 +292,7 @@ const transformPackageJson = async(CONFIG, done) => { const depEdge = packageNode.edgesOut.get(depName); if (!depEdge.to && !depEdge.optional) { throw new Error( - `Couldn\'t find node for package ${depName} in arborist tree` + `Couldn't find node for package ${depName} in arborist tree` ); } if (depEdge.to) { @@ -480,7 +495,7 @@ exports.builder = { } }; -_.assign(exports.builder, ui.builder, verify.builder); +_.assign(exports.builder, verify.builder); /** @@ -529,7 +544,6 @@ exports.run = (argv, done) => { done ); }), - task('compile application assets with webpack', compileAssets), task('create branded application', createBrandedApplication), task('create executable symlink', symlinkExecutable), task('cleanup branded application scaffold', cleanupBrandedApplicationScaffold), @@ -539,6 +553,7 @@ exports.run = (argv, done) => { task('fix COMPASS-5333', fixCompass5333), task('write license file', writeLicenseFile), task('write 3rd party notices file', copy3rdPartyNoticesFile), + task('write sbom file', copySBOMFile), task('remove development files', removeDevelopmentFiles), !noAsar && task('create application asar', createApplicationAsar), !skipInstaller && task('create branded installer', createBrandedInstaller), diff --git a/packages/hadron-build/commands/ui.js b/packages/hadron-build/commands/ui.js deleted file mode 100644 index a7aba8d62cc..00000000000 --- a/packages/hadron-build/commands/ui.js +++ /dev/null @@ -1,96 +0,0 @@ -'use strict'; - -const Promise = require('bluebird'); -const path = require('path'); -const LessCache = require('less-cache'); -const fs = require('fs-extra'); -const read = Promise.promisify(fs.readFile); - -const cli = require('mongodb-js-cli')('hadron-build:ui'); -const abortIfError = cli.abortIfError.bind(cli); - -exports.command = 'ui [options]'; - -exports.describe = 'Compile the app UI.'; - -const generateLessCache = (opts) => { - /** - * TODO (imlucas) Standardize to use CONFIG. - */ - const appDir = path.join(opts.dir, 'src', 'app'); - const src = path.join(appDir, 'index.less'); - if (!fs.existsSync(src)) { - return new Promise(function(resolve) { - resolve(); - }); - } - - if (!opts.less_cache) { - cli.warn('`less_cache` config option not set! skipping'); - return new Promise(function(resolve) { - resolve(); - }); - } - /** - * TODO (imlucas) Ensure `opts.less_cache` and `src` exist. - */ - const lessCache = new LessCache({ - cacheDir: opts.less_cache, - resourcePath: appDir - }); - - return read(src, 'utf-8').then((contents) => lessCache.cssForFile(src, contents)); -}; - -/** - * @note Durran - quick hack fix to get help cache building. Can be - * removed when we remove the help window. - */ -const generateLessHelpCache = (opts) => { - /** - * TODO (imlucas) Standardize to use CONFIG. - */ - const appDir = path.join(opts.dir, 'src', 'app'); - const src = path.join(appDir, 'help.less'); - if (!fs.existsSync(src)) { - return new Promise(function(resolve) { - resolve(); - }); - } - - if (!opts.less_cache) { - cli.warn('`less_cache` config option not set! skipping'); - return new Promise(function(resolve) { - resolve(); - }); - } - /** - * TODO (imlucas) Ensure `opts.less_cache` and `src` exist. - */ - const lessCache = new LessCache({ - cacheDir: opts.less_cache, - resourcePath: appDir - }); - - return read(src, 'utf-8').then((contents) => lessCache.cssForFile(src, contents)); -}; - -exports.builder = { - dir: { - description: 'Project root directory', - default: process.cwd() - }, - less_cache: { - description: 'Path for less cache', - default: path.join('src', 'app', '.compiled-less') - } -}; - -exports.handler = (argv) => { - cli.argv = argv; - exports.tasks(argv).catch(abortIfError); -}; - -exports.tasks = (argv) => { - return generateLessCache(argv).then(() => generateLessHelpCache(argv)); -}; diff --git a/packages/hadron-build/images/logo.png b/packages/hadron-build/images/logo.png deleted file mode 100644 index 97976939dce..00000000000 Binary files a/packages/hadron-build/images/logo.png and /dev/null differ diff --git a/packages/hadron-build/images/logo.svg b/packages/hadron-build/images/logo.svg deleted file mode 100644 index 1d8ecfa2aeb..00000000000 --- a/packages/hadron-build/images/logo.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hadron - - - Build - - diff --git a/packages/hadron-build/index.js b/packages/hadron-build/index.js index 8364ce7e2e9..d811147af8d 100644 --- a/packages/hadron-build/index.js +++ b/packages/hadron-build/index.js @@ -1,10 +1,7 @@ 'use strict'; exports = function() {}; -exports.clean = require('./commands/clean'); -exports.develop = require('./commands/develop'); exports.release = require('./commands/release'); -exports.ui = require('./commands/ui'); exports.upload = require('./commands/upload'); exports.download = require('./commands/download'); exports.verify = require('./commands/verify'); diff --git a/packages/hadron-build/lib/git.js b/packages/hadron-build/lib/git.js deleted file mode 100644 index 65b3e3919d8..00000000000 --- a/packages/hadron-build/lib/git.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; -/* eslint no-sync: 0 */ -const Promise = require('bluebird'); -const execFile = Promise.promisify(require('child_process').execFile); -const execFileSync = require('child_process').execFileSync; -const which = require('which'); - -const parse = (stdout) => { - const tag = stdout.toString('utf-8').split('\n')[0]; - return tag || null; -}; - -/** - * @param {String} sha - * @param {Function} done - * @example - * > git.isTag('2557def1585d4ac6752f9c21fc4e9af4e41979df'); - * > { '0': null, '1': false } - * > git.isTag('1a65be32d833f0eb5b3e3c68b15dbeff20ddcd35'); - * > { '0': null, '1': true } - * @return {Promise} - */ -exports.isTag = (sha) => { - return exports.getTag(sha) - .then((tag) => tag !== null); -}; - -exports.isTagSync = (sha) => { - return exports.getTagSync(sha) !== null; -}; - -const getExecArgs = (sha) => { - const GIT = which.sync('git'); - const opts = { - cwd: process.cwd(), - env: process.env - }; - - const args = [ - 'describe', - '--exact-match', - sha - ]; - - return [ - GIT, args, opts - ]; -}; - -/** - * @param {String} sha - * @param {Function} done - * @example - * > git.getTag('2557def1585d4ac6752f9c21fc4e9af4e41979df'); - * > { '0': null, '1': null } - * > git.getGitTag('1a65be32d833f0eb5b3e3c68b15dbeff20ddcd35'); - > { '0': null, '1': 'v1.2.0-pre.0' } - * @return {Promise} - */ -exports.getTag = (sha) => { - return execFile.apply(null, getExecArgs(sha)).then(parse); -}; - -exports.getTagSync = (sha) => { - return parse(execFileSync.apply(null, getExecArgs(sha))); -}; diff --git a/packages/hadron-build/package.json b/packages/hadron-build/package.json index 0634e904029..b76376804e3 100644 --- a/packages/hadron-build/package.json +++ b/packages/hadron-build/package.json @@ -1,7 +1,7 @@ { "name": "hadron-build", "description": "Tooling for Hadron apps like Compass", - "version": "25.5.3", + "version": "25.5.5", "scripts": { "check": "npm run lint && npm run depcheck", "test": "mocha -R spec", @@ -28,13 +28,12 @@ "@octokit/rest": "^18.6.2", "asar": "^3.0.3", "async": "^3.2.2", - "bluebird": "^3.7.2", "chalk": "^4.1.2", "cli-table": "^0.3.1", "debug": "^4.3.4", "del": "^2.0.2", "download": "^8.0.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "electron-packager": "^15.5.1", "electron-packager-plugin-non-proprietary-codecs-ffmpeg": "^1.0.2", "flatnest": "^1.0.0", @@ -45,7 +44,6 @@ "js-yaml": "^4.1.0", "json-diff": "^0.9.0", "jszip": "^3.5.0", - "less-cache": "^1.1.0", "lodash": "^4.17.21", "moment": "^2.29.4", "mongodb-js-cli": "^0.0.3", @@ -60,7 +58,7 @@ "zip-folder": "^1.0.0" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "chai": "^4.2.0", "depcheck": "^1.4.1", "eslint": "^7.25.0", diff --git a/packages/hadron-build/test/fixtures/hadron-app/package.json b/packages/hadron-build/test/fixtures/hadron-app/package.json index a16b1bb6485..2ebf3eda63c 100644 --- a/packages/hadron-build/test/fixtures/hadron-app/package.json +++ b/packages/hadron-build/test/fixtures/hadron-app/package.json @@ -56,12 +56,8 @@ } }, "scripts": { - "start": "hadron-build develop", "prepublish": "hadron-build release", - "postuninstall": "hadron-build clean", "test-check-ci": "npm run test", - "clean": "hadron-build clean", - "compile-ui": "hadron-build ui", "release": "hadron-build release", "upload": "hadron-build upload" }, diff --git a/packages/hadron-build/test/index.test.js b/packages/hadron-build/test/index.test.js index 6b560f25e4e..714d24f7928 100644 --- a/packages/hadron-build/test/index.test.js +++ b/packages/hadron-build/test/index.test.js @@ -14,39 +14,7 @@ describe('hadron-build', () => { expect(hadronBuild).to.be.a('function'); }); - describe('::clean', () => { - it('should include options from commands::ui', () => { - expect(commands.clean.builder).to.have.property('less_cache'); - }); - }); - - describe('::develop', () => { - it('should include options from commands::ui', () => { - expect(commands.develop.builder).to.have.property('less_cache'); - }); - - it('should include tasks from commands::ui'); - - it('should include options from commands::verify', () => { - expect(commands.develop.builder).to.have.property('nodejs_version'); - expect(commands.develop.builder).to.have.property('npm_version'); - }); - - it('should include tasks from commands::verify'); - - - describe('::handler', () => { - it('should set `NODE_ENV` to development'); - it('should set `DEVTOOLS` to `1` when --devtools is specified'); - it('should spawn electron-prebuilt'); - }); - }); - describe('::release', () => { - it('should include options from commands::ui', () => { - expect(commands.release.builder).to.have.property('less_cache'); - }); - it('should include options from commands::verify', () => { expect(commands.release.builder).to.have.property('nodejs_version'); expect(commands.release.builder).to.have.property('npm_version'); @@ -116,18 +84,6 @@ describe('hadron-build', () => { it('should spawn electron-mocha'); }); }); - describe('::upload', () => { - - }); - describe('::ui', () => { - it('should include a `less_cache` option', () => { - expect(commands.ui.builder).to.have.property('less_cache'); - }); - - it('should default `less_cache` to `src/app/less-cache`'); - - it('should generate the less cache'); - }); describe('::verify', () => { it('should have a `nodejs_version` option', () => { diff --git a/packages/hadron-document/package.json b/packages/hadron-document/package.json index b84281ae1a7..c11ee148dee 100644 --- a/packages/hadron-document/package.json +++ b/packages/hadron-document/package.json @@ -7,7 +7,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "8.5.4", + "version": "8.5.5", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -52,7 +52,7 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/hadron-document/src/element.ts b/packages/hadron-document/src/element.ts index bcb79bed419..b3bc37c4fd7 100644 --- a/packages/hadron-document/src/element.ts +++ b/packages/hadron-document/src/element.ts @@ -46,6 +46,12 @@ const UNEDITABLE_TYPES = [ 'DBRef', ]; +export function isValueExpandable( + value: BSONValue +): value is BSONObject | BSONArray { + return isPlainObject(value) || isArray(value); +} + /** * Represents an element in a document. */ @@ -58,6 +64,11 @@ export class Element extends EventEmitter { added: boolean; removed: boolean; elements?: ElementList; + // With Arrays and Objects we store the value in the + // `elements` instead of currentValue. We use `originalExpandableValue` + // to store the original value that was passed in. This is necessary + // to be able to revert to the original value when the user cancels + // any changes. originalExpandableValue?: BSONObject | BSONArray; parent: Element | Document | null; type: TypeCastTypes; @@ -116,7 +127,7 @@ export class Element extends EventEmitter { value = TypeChecker.cast(value, TypeChecker.type(value)); } - if (this._isExpandable(value)) { + if (isValueExpandable(value)) { // NB: Important to set `originalExpandableValue` first as element // generation will depend on it this.originalExpandableValue = value; @@ -168,10 +179,10 @@ export class Element extends EventEmitter { */ edit(value: BSONValue): void { this.currentType = TypeChecker.type(value); - if (this._isExpandable(value) && !this._isExpandable(this.currentValue)) { + if (isValueExpandable(value) && !isValueExpandable(this.currentValue)) { this.currentValue = null; this.elements = this._generateElements(value); - } else if (!this._isExpandable(value) && this.elements) { + } else if (!isValueExpandable(value) && this.elements) { this.currentValue = value; this.elements = undefined; } else { @@ -455,6 +466,10 @@ export class Element extends EventEmitter { } } + _isExpandable(): boolean { + return this.currentType === 'Array' || this.currentType === 'Object'; + } + /** * Is the element the last in the elements. * @@ -726,7 +741,7 @@ export class Element extends EventEmitter { * will most expand the element itself. */ expand(expandChildren = false): void { - if (!this._isExpandable(this.originalExpandableValue)) { + if (!this._isExpandable()) { return; } @@ -743,7 +758,7 @@ export class Element extends EventEmitter { * Collapses only the target element */ collapse(): void { - if (!this._isExpandable(this.originalExpandableValue)) { + if (!this._isExpandable()) { return; } @@ -801,17 +816,6 @@ export class Element extends EventEmitter { return !!element && element.isAdded() && element.isBlank(); } - /** - * Check if the value is expandable. - * - * @param value - The value to check. - * - * @returns If the value is expandable. - */ - _isExpandable(value: BSONValue): value is BSONObject | BSONArray { - return isPlainObject(value) || isArray(value); - } - /** * Generates a sequence of child elements. * diff --git a/packages/hadron-document/test/element.test.ts b/packages/hadron-document/test/element.test.ts index 5a08d1f65fe..39dfbc5d29c 100644 --- a/packages/hadron-document/test/element.test.ts +++ b/packages/hadron-document/test/element.test.ts @@ -12,7 +12,7 @@ import { } from 'bson'; import { expect } from 'chai'; import { Document, Element, ElementEvents } from '../src/'; -import { DATE_FORMAT } from '../src/element'; +import { DATE_FORMAT, isValueExpandable } from '../src/element'; import moment from 'moment'; import Sinon from 'sinon'; @@ -2773,10 +2773,37 @@ describe('Element', function () { expect(element.expanded).to.be.true; for (const el of element.elements ?? []) { - if (el._isExpandable(el.originalExpandableValue)) { + if (isValueExpandable(el.originalExpandableValue)) { expect(el.expanded).to.be.true; } } }); }); + + context( + 'when expanding an element that has been added with a changed type', + function () { + it('should expand the target element and its children', function () { + const element = new Element('names', { + firstName: 'A', + addresses: [1, 2], + }); + expect(element.expanded).to.be.false; + + element.insertEnd('pineapple', 'to be changed'); + element.get('pineapple')?.changeType('Object'); + + element.insertEnd('pie', new Int32(123)); + element.get('pie')?.changeType('Array'); + + expect(element.get('pineapple')?.expanded).to.be.false; + expect(element.get('pie')?.expanded).to.be.false; + + element.expand(true); + expect(element.expanded).to.be.true; + expect(element.get('pineapple')?.expanded).to.be.true; + expect(element.get('pie')?.expanded).to.be.true; + }); + } + ); }); diff --git a/packages/hadron-ipc/package.json b/packages/hadron-ipc/package.json index e3b05ee681c..115112c9f36 100644 --- a/packages/hadron-ipc/package.json +++ b/packages/hadron-ipc/package.json @@ -1,7 +1,7 @@ { "name": "hadron-ipc", "description": "Simplified IPC for electron apps.", - "version": "3.2.16", + "version": "3.2.18", "author": { "name": "MongoDB Inc", "email": "compass@mongodb.com" @@ -50,7 +50,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -69,7 +69,7 @@ }, "dependencies": { "debug": "^4.3.4", - "electron": "^29.4.3", + "electron": "^29.4.5", "is-electron-renderer": "^2.0.1" } } diff --git a/packages/instance-model/package.json b/packages/instance-model/package.json index ee455f47d21..087fc2546bc 100644 --- a/packages/instance-model/package.json +++ b/packages/instance-model/package.json @@ -2,7 +2,7 @@ "name": "mongodb-instance-model", "description": "MongoDB instance model", "author": "Lucas Hrabovsky ", - "version": "12.22.1", + "version": "12.23.1", "bugs": { "url": "https://jira.mongodb.org/projects/COMPASS/issues", "email": "compass@mongodb.com" @@ -29,12 +29,12 @@ }, "dependencies": { "ampersand-model": "^8.0.1", - "mongodb-collection-model": "^5.21.1", - "mongodb-data-service": "^22.21.1", - "mongodb-database-model": "^2.21.1" + "mongodb-collection-model": "^5.22.1", + "mongodb-data-service": "^22.22.1", + "mongodb-database-model": "^2.22.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "chai": "^4.3.4", "depcheck": "^1.4.1", diff --git a/packages/mongodb-query-util/package.json b/packages/mongodb-query-util/package.json index 180a070988f..3f6f6aba3b8 100644 --- a/packages/mongodb-query-util/package.json +++ b/packages/mongodb-query-util/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "2.2.3", + "version": "2.2.4", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -50,7 +50,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/my-queries-storage/package.json b/packages/my-queries-storage/package.json index ff3f0f686b8..a048e488b32 100644 --- a/packages/my-queries-storage/package.json +++ b/packages/my-queries-storage/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.10.0", + "version": "0.13.0", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -55,7 +55,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -73,10 +73,10 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-editor": "^0.25.0", - "@mongodb-js/compass-user-data": "^0.2.1", + "@mongodb-js/compass-editor": "^0.27.0", + "@mongodb-js/compass-user-data": "^0.3.1", "bson": "^6.7.0", - "hadron-app-registry": "^9.1.12", + "hadron-app-registry": "^9.2.1", "react": "^17.0.2" } } diff --git a/packages/reflux-state-mixin/package.json b/packages/reflux-state-mixin/package.json index 344fc2537a4..09ee7de2b95 100644 --- a/packages/reflux-state-mixin/package.json +++ b/packages/reflux-state-mixin/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "1.0.2", + "version": "1.0.3", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -53,7 +53,7 @@ "reflux": "^0.4.1" }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", diff --git a/packages/ssh-tunnel/package.json b/packages/ssh-tunnel/package.json index 8b0bdb587d5..0cea0eb5896 100644 --- a/packages/ssh-tunnel/package.json +++ b/packages/ssh-tunnel/package.json @@ -13,7 +13,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "2.2.1", + "version": "2.3.1", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -49,7 +49,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/mocha-config-compass": "^1.3.9", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/tsconfig-compass": "^1.0.4", @@ -73,7 +73,7 @@ "typescript": "^5.0.4" }, "dependencies": { - "@mongodb-js/compass-logging": "^1.3.1", + "@mongodb-js/compass-logging": "^1.4.1", "socksv5": "0.0.6", "ssh2": "^1.12.0" } diff --git a/scripts/package.json b/scripts/package.json index 3b54af1f698..99a6f42d658 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -14,7 +14,7 @@ "email": "compass@mongodb.com" }, "homepage": "https://github.com/mongodb-js/compass", - "version": "0.16.13", + "version": "0.16.15", "repository": { "type": "git", "url": "https://github.com/mongodb-js/compass.git" @@ -30,7 +30,7 @@ "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." }, "devDependencies": { - "@mongodb-js/eslint-config-compass": "^1.1.2", + "@mongodb-js/eslint-config-compass": "^1.1.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "depcheck": "^1.4.1", "eslint": "^7.25.0", @@ -40,7 +40,7 @@ "@babel/core": "^7.24.3", "@mongodb-js/monorepo-tools": "^1.1.1", "commander": "^11.0.0", - "electron": "^29.4.3", + "electron": "^29.4.5", "jsdom": "^21.1.0", "make-fetch-happen": "^8.0.14", "pacote": "^11.3.5",